1. 程式人生 > >西瓜書 課後習題5.5 標準bp演算法,累計bp演算法

西瓜書 課後習題5.5 標準bp演算法,累計bp演算法

import numpy as np


def dataSet():
    '''
    西瓜3.0資料集離散化
    '''
    X = np.mat('2,3,3,2,1,2,3,3,3,2,1,1,2,1,3,1,2;\
            1,1,1,1,1,2,2,2,2,3,3,1,2,2,2,1,1;\
            2,3,2,3,2,2,2,2,3,1,1,2,2,3,2,2,3;\
            3,3,3,3,3,3,2,3,2,3,1,1,2,2,3,1,2;\
            1,1,1,1,1,2,2,2,2,3,3,3,1,1,2,3,2;\
            1,1,1,1,1,2,2,1,1,2,1,2,1,1,2,1,1;\
            0.697,0.774,0.634,0.668,0.556,0.403,0.481,0.437,0.666,0.243,0.245,0.343,0.639,0.657,0.360,0.593,0.719;\
            0.460,0.376,0.264,0.318,0.215,0.237,0.149,0.211,0.091,0.267,0.057,0.099,0.161,0.198,0.370,0.042,0.103\
            ').T
    X = np.array(X)
    Y = np.mat('1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0')
    Y = np.array(Y).T
    return X, Y


def sigmoid(x):
    '''
    sigmoid函式
    '''
    return 1.0 / (1.0 + np.exp(-x))


def bpa(hiddenLayer):
    '''
    累計誤差逆傳播
    :param hiddenLayer: 隱層數目
    '''
    # 初始化引數
    X, Y = dataSet()  # 資料集和標籤,分別為shpae[n,d],shape[n.L],這裡的L=1
    V = np.random.rand(X.shape[1], hiddenLayer)  # shape[d,q]
    W = np.random.rand(hiddenLayer, Y.shape[1])  # shape[q,L]
    t0 = np.random.rand(1, hiddenLayer)  # shape[1,q]
    t1 = np.random.rand(1, Y.shape[1])  # shape[1,L]
    # 設定初始化變數
    r = 0.1  # 學習率
    error = 0.001  # 最大允許誤差
    maxTrainNum = 1000000  # 最大學習次數
    trainNum = 0  # 訓練次數
    loss = 0
    flag = 1
    while flag:
        b = sigmoid(X.dot(V) - t0)  # shape[n,q]
        Y0 = sigmoid(b.dot(W) - t1)  # shape[L,1]
        loss = sum((Y0 - Y) ** 2) / X.shape[0]
        if loss < error or trainNum > maxTrainNum:
            break
        trainNum += 1
        # 更新引數
        g = Y0 * (1 - Y0) * (Y - Y0)  # shape[n,L]
        e = b * (1 - b) * g.dot(W.T)  # shape[n,q]        
        W += r * b.T.dot(g)
        t1 -= r * g.sum(axis=0)
        V += r * X.T.dot(e)
        t0 -= r * e.sum(axis=0)
    # 輸出訓練結果引數
    print('累計誤差逆傳播法 訓練次數: ' + str(trainNum))
    print('V:')
    print(V)
    print('W:')
    print(W)
    print('t0:')
    print(t0)
    print('t1:')
    print(t1)
    print('loss: ' + str(loss[0]))


def bps(hiddenLayer):
    '''
    標準誤差逆傳播
    :param hiddenLayer: 隱層數目
    '''
    # 初始化引數
    X, Y = dataSet()  # 資料集和標籤,分別為shpae[n,d],shape[n.L],這裡的L=1
    V = np.random.rand(X.shape[1], hiddenLayer)  # shape[d,q]
    W = np.random.rand(hiddenLayer, Y.shape[1])  # shape[q,L]
    t0 = np.random.rand(1, hiddenLayer)  # shape[1,q]
    t1 = np.random.rand(1, Y.shape[1])  # shape[1,L]
    # 設定初始化變數
    r = 0.1  # 學習率
    error = 0.001  # 最大允許誤差
    maxTrainNum = 1000000  # 最大學習次數
    trainNum = 0  # 訓練次數
    loss = 0
    flag = 1
    while flag:
        for k in range(X.shape[0]):
            b = sigmoid(X.dot(V) - t0)  # shape[n,q]
            Y0 = sigmoid(b.dot(W) - t1)  # shape[L,1]
            loss = sum((Y0 - Y) ** 2) / X.shape[0]
            if loss < error or trainNum > maxTrainNum:
                flag = 0
                break
            trainNum += 1
            # 更新引數
            g = Y0[k] * (1 - Y0[k]) * (Y[k] - Y0[k])  # shape[1,L]
            g = g.reshape(1, g.size)  # shape[1,L]
            b = b[k]
            b = b.reshape(1, b.size)  # shape[1,q]
            e = b * (1 - b) * g.dot(W.T)  # shape[1,q]
            W += r * b.T.dot(g)  # shape[q,L]
            t1 -= r * g
            V += r * X[k].reshape(1, X[k].size).T.dot(e)  # shape[d,q]
            t0 -= r * e

    # 輸出訓練結果引數
    print('標準誤差逆傳播法 訓練次數: ' + str(trainNum))
    print('V:')
    print(V)
    print('W:')
    print(W)
    print('t0:')
    print(t0)
    print('t1:')
    print(t1)
    print('loss: ' + str(loss[0]))


if __name__ == '__main__':
    bpa(5)  # 隱層數目為5
    bps(5)

結果:累計誤差逆傳播法 訓練次數: 7758           loss: 0.0009998732359117453

           標準誤差逆傳播法 訓練次數: 205086       loss: 0.0009999861270941792     

參考:https://blog.csdn.net/u013527937/article/details/58637367