簡體   English   中英

神經網絡在一個時代之后變得扁平化

[英]Neural Network flatlines after one epoch

我正在使用keras創建一個卷積神經網絡,試圖將圖像分為兩個不同的類,並且由於某種原因,在第一個時代之后,准確性永遠不會改變。

使用to_categorical()to_categorical()我的標簽看起來像:

[[0.  1.]
[1.  0.]
[1.  0.]
[0.  1.]]

我的模型的代碼是:

model = Sequential()
model.add(Conv2D(filters=32, kernel_size=[5, 5], strides=1, padding='same', activation='relu', input_shape=(imageSize, imageSize, 3)))
model.add(MaxPooling2D())
model.add(Conv2D(filters=64, kernel_size=[5, 5], strides=1, padding='same', activation='relu'))
model.add(MaxPooling2D())
model.add(Flatten())
model.add(Dense(2))
sgd = SGD()  # Use stochastic gradient descent for now
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

model.summary()

counter = 0
# Train one cycle at a time so we can shuffle data inbetween
for x in range(trainingEpochs):

    counter += 1
    print()  # New line
    print('Epoch ' + str(counter))

    trainingImages, trainingLabels = shuffle(trainingImages, trainingLabels, random_state=0)  # Shuffle both sets in unison

    model.fit(x=trainingImages, y=trainingLabels, batch_size=32, epochs=1, verbose=2)

此代碼導致輸出:

Epoch 1
36s - loss: 5.0770 - acc: 0.3554

Epoch 2
36s - loss: 4.9421 - acc: 0.3066

Epoch 3
36s - loss: 4.9421 - acc: 0.3066

Epoch 4
36s - loss: 4.9421 - acc: 0.3066

到目前為止,我嘗試使用binary_crossentropy更改批量大小,更改混洗方法,更改卷積參數,使用黑白照片而不是RGB,使用不同大小的圖片,使用ADAM代替SGD,以及使用較低的學習率對於新元,但沒有一個解決了這個問題。 我很茫然,有沒有人有任何想法?

編輯:trainingImages的形狀為(287,256,256,3),如果重要的話。

症狀是訓練損失相對較早地停止改善。 假設您的問題完全可以學習,這種行為有很多原因。 這些都是我的頭腦:

  1. 輸入的預處理不正確:

神經網絡優先選擇零均值輸入。 例如,如果輸入全部為正,則將限制權重在相同方向上更新,這可能是不可取的( https://youtu.be/gYpoJMlgyXA )。

因此,您可能希望從所有圖像中減去平均值(例如,從3個通道中的每個通道中減去127.5)。 縮放以在每個通道中進行單位標准偏差也可能有所幫助。

  1. 網絡的泛化能力:

網絡對於任務來說並不復雜或不夠深入。

這很容易檢查。 您可以在幾張圖片上訓練網絡(從3到10說)。 網絡應該能夠過度擬合數據並將損失驅動到接近0.如果不是這樣,您可能需要添加更多層,例如使用多於1個Dense層。

另一個好主意是使用預先訓練過的砝碼(在Keras文檔的應用中)。 您可以調整頂部的Dense圖層以適合您的問題。

  1. 重量初始化不正確。

不正確的權重初始化可以防止網絡收斂( https://youtu.be/gYpoJMlgyXA ,與之前相同的視頻)。

對於ReLU激活,您可能希望使用He初始化而不是默認的Glorot初始化。 我發現這有時可能是必要的,但並非總是如此。

最后,您可以使用Keras的調試工具,例如keras-vis,keplr-io,deep-viz-keras。 它們對於打開卷積網絡的黑盒非常有用。

您需要在網絡的最后一層添加一個sigmoid非線性,並將輸出數量更改為1.此非線性將輸入映射到[0,1]。

# ...
model.add(Flatten())
model.add(Dense(1))
# add nonlinearity
model.add(Activation('sigmoid'))

另外,將模型的損失更改為binary_crossentropy

model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])

最后,確保您的標簽是布爾(或0或1中的int)和形狀(n_observations,1)。 也就是說,將它們從[[0,1],[1,0],[1,0]]更改為[0 1 0 0 1]。

查看keras的博客,了解如何在遇到問題時如何構建二進制圖像分類器。

通過@rafaelvalle鏈接的博客文章后,我設法確定我的問題是由我的標簽編碼引起的。 最初我將它們作為一個熱門編碼,看起來像[[0, 1], [1, 0], [1, 0]] ,在博客文章中它們的格式為[0 1 0 0 1] 將我的標簽更改為此並使用二進制crossentropy使我的模型正常工作。 感謝Ngoc Anh Huynh和rafaelvalle!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM