我正在努力從頭開始開發一個神經網路。問題似乎可能出在我的反向傳播(relu back-propagation)上。當我訓練模型時,它有時輸出0,有時輸出好的預測(相對而言)。誰能告訴我是否我的反向傳播做得不對,或者是否有什么原因導致我的 relu 預測為-0?
-- [編輯]
修復了預測-0的問題,但現在它只是預測XOR的所有輸入為0。誰能看看我的反向傳播?
import numpy as np
# 我們的神經網路中的每一層都是如此
class NeuralLayer。
def __init__(self, input_neurons, output_neurons)。
self.weights = np.random.randn(input_neurons, output_neurons)* np.sqrt(2. / input_neurons)
self.bias = np.ones((1, output_neurons) * 0.5 0.5
# 兩種不同的激活方式,默認為sigmoid。
def sigmoid(self, neurons)。
self.act = 1.0/(1.0 np.exp(-neurons))
return self.act
def sigmoidBackward(self, grad)。
return grad * self.act * (1 - self.act)
def relu(self, neurons)。
self.act = (neurons > 0)
return neurons * self.act
def reluBackward(self, grad)。
return grad * self.act
# 本層的前向傳遞。
def forward(self, input, activation) 。
self.input = np.atleast_2d(input)
if activation == sigmoid':
return self.sigmoid(input @ self.weights self.bias)
else:
return self.relu(input @ self.weights self.bias)
# backward pass for this layer[/span]。
def backward(self, grad, activation)。
if activation == 'sigmoid'/span>:
grad = self.sigmoidBackward(np.atleast_2d(grad))
else:
grad = self.reluBackward(np.atleast_2d(grad))
self.grad_weights = np.matmul(self.input.T, grad)
self.grad_bias = grad.sum()
return grad @ self.weights.T
def step(self, step_size)。
self.weights -= step_size*self.grad_weights
self.bias -= step_size*self.grad_bias
# Our neural net(我們的神經網路)。
class NeuralNetwork。
# 動態創建所有圖層。
def __init__(self, input_neurons, hidden_neurons, layer_count, activation, output_neurons = 1) 。
self.activation = activation
# Used to ensure input neurons match inputted dataassert layer_count >= 2 andoutput_neurons >= 1
#輸入層
self.layer = [NeuralLayer(input_neurons, hidden_neurons)]。
# Hidden Layers 隱藏層
for i in range(layer_count - 2)。
self.layer.append(NeuralLayer(hidden_neurons, hidden_neurons))
# 輸出層# 每個層的正向傳遞 # 每個層的正向傳遞
def forward(self, inp)。
assert inp.shape[0] == self.neuron_safety
for layer in self.layer:
inp = layer.forward(inp, self.activation)
return inp
def backward(self, grad)。
for layer in reversed(self.l layers):
grad = layer.backward(grad, self.activation)
def step(self, step_size = 0.01) 。
for layer in self.l layers:
layer.step(step_size)
# loss function - only 1 output neuron[/span]。
def meanSquaredError(self, preds, labels)。
self.labs = labels
self.preds = preds
return (self.preds - self.labs)**2。
def meanSquaredErrorGrad(self)。
return 2 * (self.preds - self.label)
# 創建一個有2個輸入、每層有2個隱藏神經元的神經網路
net = NeuralNetwork(2,16,4, 'relu')
epochs = 5000 5000
# 輸入資料(A,B)進行XOR。
X = np. array([[0,0], [1,1], [1,0], [0,1]])
# 預期輸出資料
Y = np.array([[0],[0],[1],[1]] )
for i in range(epochs)。
preds = []
for idx, x in enumerate(X):
預測 = net.forward(x)
preds.append(predictions)
loss = net.meanSquaredError(predictions, Y[idx])
loss_grad = net.meanSquaredErrorGrad()
net.backward(loss_grad)
net.step()
print("模型預測的。{}
實際值。{} ".format(preds, Y.T)
輸出:
Model predicted: [array([[-0.]], array([[-0.]]), array([[1.]], array([-0.]) ]
實際值。[[0 0 1 1]]。
有時預測是完美的,但大多數情況下,至少有一個預測是-0
uj5u.com熱心網友回復:偏差梯度是不正確的。 你正在使用self.grad_bias = grad.sum()。 這將計算出整個矩陣的總和。 它需要self.grad_bias = grad.sum(axis=0, keepdims=True)來計算一個1 x output_neurons陣列,這將正確更新偏置向量。 否則,grad.sum()會提供一個單一的數字,你用它來更新所有的偏置,這是不正確的。
另外,確保你將ReLU的前向傳遞更新為np.maximum(neurons, 0),如評論中所述。
def relu(self, neurons)。
self.act = (neurons > 0)
return np.maximum(neurons, 0)
激活的梯度將是0或1,這取決于輸入的哪些部分是正的。
最后,對于 XOR 問題,你通常不使用 ReLU 作為輸出層的激活,因為它不像 XOR 問題那樣在 [0-1] 之間有界限。 你用sigmoid激活函式得到好結果的原因是,該激活函式的動態范圍很適合XOR問題。 作為一個實驗,你可以把輸出層修改為sigmoid,把隱藏層修改為ReLU。 如果你這樣做,你應該得到和一直使用sigmoid一樣好的性能。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/326871.html
標籤:
下一篇:為什么這個地圖的回圈代碼不作業?
