BPニューラルネットワークPython
3249 ワード
空き期间、暇で无事、最も基础的なBPニューラルネットワークを书きます.
順方向ネットワーク伝達は比較的簡単で,直接行列が乗算され,ここでは無視される.主に逆方向のネットワーク伝達について:1:出力ネットワーク誤差=出力層損失関数導関数*損失関数2:隠し層ネットワーク誤差=出力層損失関数導関数*(次層誤差*中間重み)3:重み更新=元の重み+学習率*(前分岐転置*後誤差)4:バイアス更新=元のバイアス+学習率*(前分岐転置*後誤差)
実際の動作では,バイアスは重み行列に直接配置して計算することができ,出力層は不要である.
順方向ネットワーク伝達は比較的簡単で,直接行列が乗算され,ここでは無視される.主に逆方向のネットワーク伝達について:1:出力ネットワーク誤差=出力層損失関数導関数*損失関数2:隠し層ネットワーク誤差=出力層損失関数導関数*(次層誤差*中間重み)3:重み更新=元の重み+学習率*(前分岐転置*後誤差)4:バイアス更新=元のバイアス+学習率*(前分岐転置*後誤差)
実際の動作では,バイアスは重み行列に直接配置して計算することができ,出力層は不要である.
import numpy as np
def tanh(x):
return np.tanh(x)
def tanh_deriv(x): #
return 1.0 - np.tanh(x) * np.tanh(x)
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmod_derivate(x): #
return x * (1 - x)
# layers: ,
# activation:
class NeuralNetwork: #
def __init__(self, layers, activation='sigmoid'):
if activation == 'sigmoid':
self.activation = sigmoid
self.activation_deriv = sigmod_derivate
elif activation == 'tanh':
self.activation = tanh
self.activation_deriv = tanh_deriv
#
self.weights = [] # +
self.panel = [] #
self.error = [] #
self.panel.append(np.zeros(layers[0]+1))
for i in range(1, len(layers)-1):
self.weights.append((2*np.random.random((layers[i-1]+1, layers[i]+1))-1)*0.25)
self.panel.append(np.zeros(layers[i]+1))
self.error.append(np.zeros(layers[i]+1))
self.weights.append((2 * np.random.random((layers[-2] + 1, layers[-1])) - 1) * 0.25)
self.panel.append(np.zeros(layers[-1]))
self.error.append(np.zeros(layers[-1]))
# inputs:
def predict(self, inputs): #
inputs = [inputs]
temp = np.ones([np.array(inputs).shape[1]+1])
temp[:-1] = np.array(inputs)
inputs = temp
self.panel[0] = np.array(inputs)
for i in range(len(self.weights)):
self.panel[i+1] = self.activation(np.dot(self.panel[i], self.weights[i])) #
return self.panel[-1]
# case:
# label:
# learn:
def back_propagate(self, case, label, learn): #
self.predict(case)
self.error[-1] = (label - self.panel[-1])*self.activation_deriv(self.panel[-1]) #
for i in range(len(self.panel)-2, 0, -1):
self.error[i-1] = (self.error[i].dot(self.weights[i].T))*self.activation_deriv(self.panel[i]) #
for i in range(len(self.weights)):
self.weights[i] += learn * np.atleast_2d(self.panel[i]).T.dot(np.atleast_2d(self.error[i])) #
# X:
# y:
# epochs:
# learn:
def train(self, X, y, epochs=10000, learn=0.05):
for k in range(epochs):
i = np.random.randint(np.array(X).shape[0])
case = X[i]
label = np.array(y[i])
self.back_propagate(case, label, learn)
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0, 0], [1, 1], [1, 1], [0,0]])
nn = NeuralNetwork([2, 5, 2, 2], activation='tanh') #
nn.train(X, y, 10000, 0.2) #
for case in X: #
print(nn.predict(case))