[英]Neural Network Issue with Back Propagation Calculation
我目前正在嘗試構建一個簡單的神經網絡,以使用 MNIST 數字數據庫識別書面數字。 當我運行第一個測試時,我在我的輸出數組中得到了隨機的概率分類,這是預期的。 但是,當我多次運行它時,我的輸出數組幾乎在所有索引位置都降為零。 似乎我對反向傳播的權重調整的計算導致了問題,但我似乎無法找出原因。
def sigmoid(x):
a = 1 / (1 + np.exp(-x))
return a
def sigmoid_derivative(x):
return x * (1 - x)
def train(n, inputs):
input_layer = inputs
weights1 = 2 * np.random.random ((784 , 16)) - 1
weights2 = 2 * np.random.random ((16 , 10)) - 1
for i in range(n):
trained_hidden = sigmoid(np.dot(input_layer, weights1))
trained_outputs = sigmoid(np.dot(trained_hidden, weights2))
o_error = (outputs - trained_outputs)
o_adjustments = o_error * sigmoid_derivative(trained_outputs)
h_error = np.dot(o_adjustments, weights2.T)
h_adjustments = h_error * sigmoid_derivative(trained_hidden)
w1 = np.dot(input_layer.T, h_adjustments)
w2 = np.dot(trained_hidden.T, o_adjustments)
weights1 += w1
weights2 += w2
return trained_outputs
我正在使用 Numpy 數組,輸入是一個 (10000 x 784) 數組,灰度值為 0 - 1,輸出一個 (10000 x 10) 數組,實際數字的索引位置為 1。
x_train, t_train, x_test, t_test = mnist.load()
inputs = x_test/256
outputs = np.zeros((10000,10), dtype=int)
for i in range(10000):
x = t_test[int(i)]
outputs[i][x] = 1
set = train(10, inputs)
我使用了許多資源來構建它,包括來自 3 blue 1 brown 神經網絡系列的理論以及此處提供的示例所遵循的代碼( https://enlight.nyc/projects/neural-network/ )
編輯:根據@9000 的建議,這是一個示例中每個步驟的打印輸出。 查看結果,看起來 w1(權重調整計算)是問題所在,但一遍又一遍地查看它,我無法弄清楚為什么它不正確,任何幫助表示贊賞。
編輯 2:我在第二次訓練中包含了同一個例子的第二個打印輸出。
第一次運行
trained_hidden [0.87880514 0.4789476 0.38500953 0.00142838 0.01373613 0.37572408 0.53673194 0.11774215 0.99989426 0.0547656 0.20645864 0.85484692 0.99903171 0.88929566 0.00673453 0.03816501]
trained_output [0.33244312 0.26289407 0.79917376 0.95143406 0.90780616 0.2100068 0.66253735 0.57961972 0.28231436 0.15963378]
o_error [ 0.66755688 -0.26289407 -0.79917376 -0.95143406 -0.90780616 -0.2100068 -0.66253735 -0.57961972 -0.28231436 -0.15963378]
o-adjustment [ 0.14814735 -0.05094382 -0.12826344 -0.04396319 -0.07597805 -0.03484096 -0.14813117 -0.14123055 -0.05720055 -0.02141501]
h_error [-0.00359599 0.18884347 0.15954247 -0.14839811 0.2081496 -0.01152563 0.03262859 -0.46315722 -0.06974061 -0.46774417 -0.00690463 -0.44303219 -0.16267084 -0.02505235 -0.12866526 0.22212537]
h_adjustment [-3.82997246e-04 4.71271721e-02 3.77760172e-02 -2.11665993e04 2.81989626e-03 -2.70339996e-03 8.11312465e-03 -4.81122794e02 -7.37327102e-06 -2.42134002e-02 -1.13120886e-03 -5.49730579e-02 -1.57359939e-04 -2.46637616e-03 -8.60664795e-04 8.15387570e-03]
w1 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
w2 [-111.70644608 -164.50671691 -254.60942018 -205.06537232 -330.43317768 -94.6976 -346.78221607 -272.22044431 -249.54889015 -75.99543441]
weights1 [-0.09535479 -0.09824519 -0.11582134 -0.65075843 -0.65593035 0.77593957 -0.0406199 0.12669151 0.79979191 -0.52502487 -0.2433578 0.16617536 -0.25711996 0.92995152 -0.40922601 -0.63029133]
weights2 [-112.24597022 -164.86741004 -254.21715269 -205.27326963 -331.18579697 -95.07615178 -347.04311247 -271.82206581 -250.04075852 -76.69273265]
第二次運行
trained_hidden [0.00000000e+000 1.00000000e+000 1.00000000e+000 3.77659154e-181 1.00000000e+000 0.00000000e+000 0.00000000e+000 0.00000000e+000 1.00000000e+000 0.00000000e+000 1.00000000e+000 0.00000000e+000 2.71000625e-055 0.00000000e+000 0.00000000e+000 1.00000000e+000]
trained_output [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
o_error [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
o-adjustment [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
h_error [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
h_adjustment [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
w1 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
w2 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
weights1 [-0.09535479 -0.09824519 -0.11582134 -0.65075843 -0.65593035 0.77593957 -0.0406199 0.12669151 0.79979191 -0.52502487 -0.2433578 0.16617536 -0.25711996 0.92995152 -0.40922601 -0.63029133]
weights2 [-112.24597022 -164.86741004 -254.21715269 -205.27326963 -331.18579697 -95.07615178 -347.04311247 -271.82206581 -250.04075852 -76.69273265]
首先,您確定您打印的 weights1 和 weights2 是正確的嗎? 它們在具有非常不同輸出的兩次運行之間是相同的,這對我來說似乎非常可疑。
我稍微檢查了你的衍生品,從我研究的一點點來看,它們看起來是正確的。 但是,我看到兩個錯誤。 更新權重時,您實際上想從權重中減去導數。 因為梯度總是指向上坡,你想最小化損失,所以你想往下坡方向走。 第二個可能的錯誤是你使用全導數作為更新,基本上總是,在神經網絡中,使用學習率(例如 0.001)作為更新導數的乘數,如果你不縮小你的更新前的梯度,它可能會真的很難過沖,例如將所有權重設置為非常大的值,這會導致非常不穩定的優化。
所以我的建議是更換:
weights1 += w1
weights2 += w2
和:
learning_rate = 0.001
weights1 -= w1 * learning_rate
weights2 -= w2 * learning_rate
此外,調試神經網絡的一般經驗法則是使用您的網絡應該適合的最小示例,因此從您的數據集中選擇一個樣本並查看每次迭代中的更新,這會告訴您很多信息(例如使用調試器) . 如果你不能適應一個例子,你就不能適應 10000。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.