簡單BP神經網路的python實現__python

來源:互聯網
上載者:User

儘管神經網路已經有了很完備並且好用的架構,而且BP神經網路又是其中比較簡單低效的一種,但是出於學習的目的來實現一下這個神經網路還是有意義的吧我想。

下面程式用到了iris資料集,為了方便畫圖先用PCA對資料進行了降維。同時對分類結果進行了標籤化,針對神經網路的特點,用三個神經元作為輸出來表示三個不同的分類,代碼如下:

import mathimport randomfrom sklearn.decomposition import PCAfrom sklearn.cross_validation import train_test_splitimport matplotlib.pyplot as pltimport matplotlib as mplimport numpy as npfrom sklearn.metrics import accuracy_score def trtype(s):#定義類別轉換函式    types = {'Iris-setosa': 0, 'Iris-versicolor': 1, 'Iris-virginica': 2}    return types[s]data = np.loadtxt('iris.data',delimiter=',',converters={4:trtype})#讀入資料,第五列轉換為類別012x,y = np.split(data,(4,),axis=1)#切分data和labelpca=PCA(n_components=2)x=pca.fit_transform(x)#為方便繪圖,對x進行PCA降維至二維 #劃分測試集和訓練集def label_tr(y):#標籤轉換,將一維標籤轉換為三維    l = {0:[1,0,0],1:[0,1,0],2:[0,0,1]}    ys = []    for i in range(len(y)):        ys.append(l[int(y[i])])    return np.array(ys)def inv_label_tr(y_1d):#標籤轉換逆過程       y_pres = []    for i in range(y_1d.shape[0]):        for j in range(3):            if (y_1d[i][j]==1):                y_lable = j        y_pres.append(y_lable)            return np.array(y_pres)y = label_tr(y)#劃分資料x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1, train_size=0.6)random.seed(0)def rand(a, b):#隨機數函數    return (b - a) * random.random() + adef make_matrix(m, n, fill=0.0):#矩陣產生函數    mat = []    for i in range(m):        mat.append([fill] * n)    return matdef sigmoid(x):#啟用函數    return 1.0 / (1.0 + math.exp(-x))def sigmoid_derivative(x):#啟用函數求導    return x * (1 - x)class BPNeuralNetwork:#BP神經網路類    def __init__(self):#初始化        self.input_n = 0        self.hidden_n = 0        self.output_n = 0        self.input_cells = []        self.hidden_cells = []        self.output_cells = []        self.input_weights = []        self.output_weights = []        self.input_correction = []        self.output_correction = []    def setup(self, ni, nh, no):        #初始化輸入、隱層、輸出元數        self.input_n = ni + 1        self.hidden_n = nh        self.output_n = no        # 初始化神經元        self.input_cells = [1.0] * self.input_n        self.hidden_cells = [1.0] * self.hidden_n        self.output_cells = [1.0] * self.output_n        # 初始化權重矩陣        self.input_weights = make_matrix(self.input_n, self.hidden_n)        self.output_weights = make_matrix(self.hidden_n, self.output_n)        # 初始化權重        for i in range(self.input_n):            for h in range(self.hidden_n):                self.input_weights[i][h] = rand(-0.2, 0.2)        for h in range(self.hidden_n):            for o in range(self.output_n):                self.output_weights[h][o] = rand(-2.0, 2.0)        # 初始化偏置        self.input_correction = make_matrix(self.input_n, self.hidden_n)        self.output_correction = make_matrix(self.hidden_n, self.output_n)    def predict(self, inputs):        # 啟用輸入層        for i in range(self.input_n - 1):            self.input_cells[i] = inputs[i]        # 啟用隱層        for j in range(self.hidden_n):            total = 0.0            for i in range(self.input_n):                total += self.input_cells[i] * self.input_weights[i][j]            self.hidden_cells[j] = sigmoid(total)        # 啟用輸出層        for k in range(self.output_n):            total = 0.0            for j in range(self.hidden_n):                total += self.hidden_cells[j] * self.output_weights[j][k]            self.output_cells[k] = sigmoid(total)        return self.output_cells[:]    def back_propagate(self, case, label, learn, correct):        # 反向傳播        self.predict(case)        # 求輸出誤差        output_deltas = [0.0] * self.output_n        for o in range(self.output_n):            error = label[o] - self.output_cells[o]            output_deltas[o] = sigmoid_derivative(self.output_cells[o]) * error        # 求隱層誤差        hidden_deltas = [0.0] * self.hidden_n        for h in range(self.hidden_n):            error = 0.0            for o in range(self.output_n):                error += output_deltas[o] * self.output_weights[h][o]            hidden_deltas[h] = sigmoid_derivative(self.hidden_cells[h]) * error        # 更新輸出權重        for h in range(self.hidden_n):            for o in range(self.output_n):                change = output_deltas[o] * self.hidden_cells[h]                self.output_weights[h][o] += learn * change + correct * self.output_correction[h][o]                self.output_correction[h][o] = change        # 更新輸入權重        for i in range(self.input_n):            for h in range(self.hidden_n):                change = hidden_deltas[h] * self.input_cells[i]                self.input_weights[i][h] += learn * change + correct * self.input_correction[i][h]                self.input_correction[i][h] = change        # 求全域誤差        error = 0.0        for o in range(len(label)):            error += 0.5 * (label[o] - self.output_cells[o]) ** 2        return error    def train(self, cases, labels, limit=10000, learn=0.05, correct=0.1):        #訓練神經網路        for j in range(limit):            error = 0.0            for i in range(len(cases)):                label = labels[i]                case = cases[i]                error += self.back_propagate(case, label, learn, correct)        def fit(self,x_test):#離散預測函數用於輸出資料        y_pre_1d = []        for case in x_test:            y_pred = self.predict(case)            for i in range(len(y_pred)):                if (y_pred[i] == max(y_pred)):                    y_pred[i] = 1                else: y_pred[i] = 0            y_pre_1d.append(y_pred)        return inv_label_tr(np.array(y_pre_1d))    def fit2(self,x_test):#連續預測函數用於畫圖        y_pre_1d = []        for case in x_test:            w = np.array([0,1,2])            y_pred = self.predict(case)            y_pre_1d.append(np.array(y_pred).dot(w.T))        return np.array(y_pre_1d)if __name__ == '__main__':#主函數    nn = BPNeuralNetwork()    nn.setup(2, 5, 3)#初始化    nn.train(x_train, y_train, 100000, 0.05, 0.1)#訓練    y_pre_1d = nn.fit(x_test)#測試    y_test_1d = inv_label_tr(y_test)    print accuracy_score(y_pre_1d,y_test_1d)#列印測試精度    #畫圖mpl.rcParams['font.sans-serif'] = [u'SimHei']mpl.rcParams['axes.unicode_minus'] = Falsecm_light = mpl.colors.ListedColormap(['#FFA0A0', '#A0FFA0', '#A0A0FF'])cm_dark = mpl.colors.ListedColormap(['#AAAAFF', '#FFAAAA','#AAFFAA'])x1_min, x1_max = x[:, 0].min(), x[:, 0].max()  # 第0列的範圍x2_min, x2_max = x[:, 1].min(), x[:, 1].max()  # 第1列的範圍x1, x2 = np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j] # 產生網格採樣點grid_test = np.stack((x1.flat, x2.flat), axis=1)  # 測試點grid_hat = nn.fit2(grid_test)#預測結果grid_hat = grid_hat.reshape(x1.shape)  # 使之與輸入的形狀相同plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light)plt.scatter(x[:, 0], x[:, 1], c=y, edgecolors='k', s=50, cmap=cm_dark)plt.title(u'BPNN二特徵分類', fontsize=15)plt.show()print grid_hat.shape
最終分類結果的准去率評分達到了0.983,但是可以在下面的圖中看到,綠色和藍色點的邊界部分存在著過擬合的問題,這個問題日後慢慢解決嘍..



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.