【问题标题】:Keras convolutional network scoring low on CIFAR-10 DatasetKeras 卷积网络在 CIFAR-10 数据集上得分低
【发布时间】:2018-07-20 12:09:30
【问题描述】:

我正在尝试在 Keras 的 CIFAR-10 数据集上训练 CNN,但我只能获得大约 10% 的准确率,基本上是随机的。我正在训练超过 50 个 epoch,批量大小为 32,学习率为 0.01。有什么特别是我做错了吗?

import os
import numpy as np
import pandas as pd
from PIL import Image

from keras.models import Model
from keras.layers import Input, Dense, Conv2D, MaxPool2D, Dropout, Flatten
from keras.optimizers import SGD
from keras.utils import np_utils


# trainingData = np.array([np.array(Image.open("train/" + f)) for f in os.listdir("train")]) #shape: 50k, 32, 32, 3
# testingData = np.array([np.array(Image.open("test/" + f)) for f in os.listdir("test")]) #shape: same as training
#
# trainingLabels = np.array(pd.read_csv("trainLabels.csv"))[:,1] #categorical labels ["dog", "cat", "etc"....]
# listOfLabels = sorted(list(set(trainingLabels)))
# trainingOutput = np.array([np.array([1.0 if label == ind else 0.0 for ind in listOfLabels]) for label in trainingLabels]) #converted to output
#                                                                                                                            #for example: training output for dog =
#                                                                                                                                  #[1.0, 0.0, 0.0, ...]
# np.save("trainingInput.np", trainingData)
# np.save("testingInput.np", testingData)
# np.save("trainingOutput.np", trainingOutput)


trainingInput = np.load("trainingInput.npy") #shape = 50k, 32, 32, 3
testingInput = np.load("testingInput.npy") #shape = 10k, 32, 32, 3

listOfLabels = sorted(list(set(np.array(pd.read_csv("trainLabels.csv"))[:,1]))) #categorical list of labels as strings
trainingOutput = np.load("trainingOutput.npy") #shape = 50k, 10
                                                    #looks like [0.0, 1.0, 0.0 ... 0.0, 0.0]

print(listOfLabels)

print("Data loaded\n______________\n")


inp = Input(shape=(32, 32, 3))
conva1 = Conv2D(64, (3, 3), padding='same', activation='relu')(inp)
conva2 = Conv2D(64, (3, 3), padding='same', activation='relu')(conva1)
poola = MaxPool2D(pool_size=(3, 3))(conva2)
dropa = Dropout(0.1)(poola)

convb1 = Conv2D(128, (5, 5), padding='same', activation='relu')(dropa)
convb2 = Conv2D(128, (5, 5), padding='same', activation='relu')(convb1)
poolb = MaxPool2D(pool_size=(3, 3))(convb2)
dropb = Dropout(0.1)(poolb)

flat = Flatten()(dropb)
dropc = Dropout(0.5)(flat)
out = Dense(len(listOfLabels), activation='softmax')(dropc)
print(out.shape)
model = Model(inputs=inp, outputs=out)
lrSet = SGD(lr=0.01, clipvalue=0.5)
model.compile(loss='categorical_crossentropy', optimizer=lrSet, metrics=['accuracy'])
model.fit(trainingInput, trainingOutput, batch_size=32, epochs=50, verbose=1, validation_split=0.1)
print(model.predict(testingInput))

【问题讨论】:

  • model.predict(trainingInput) 的准确度如何?

标签: machine-learning dataset keras


【解决方案1】:

我有什么特别做错的地方吗?

不一定是“错误”,但我可以提出的一些建议是:

  1. 重新调整数据很重要,以防您不这样做。与其处理范围为[0,255] 的值,不如将所有值除以255 并处理范围为[0,1] 的数据。这有助于您的模型的权重更快地收敛,因为与未缩放的版本相比,每个梯度更新都将更加重要。

  2. 我认为您的辍学可能会影响您的表现。更多地看到您在将数据传递到输出时正在使用 CNN 和强 (0.5) Dropout。引用this 很好的答案:

    在 Hinton (2012) 提出的 提出 dropout 层的原始论文中,在输出之前的每个完全连接的 (密集)层上都使用了 dropout(p=0.5) ;它没有用于卷积层。这成为最常用的配置。

    最近的研究表明,dropout 也适用于卷积层,尽管水平要低得多:p=0.1 或 0.2。

    所以也许减少你的辍学或稍微玩一下会产生更好的结果。请注意,您的数据连续丢失,在我看来这似乎没有多大帮助,也可能导致问题,因此请考虑重新设计该部分:

    dropb = Dropout(0.1)(poolb) #drop
    flat = Flatten()(dropb) #flatten 
    dropc = Dropout(0.5)(flat) #then drop again?
    
  3. 您的学习率可能高于正常使用率。尽管这是 SGD 的默认学习率,但对于更高的学习值,您可能会“匆忙”训练并且无法找到可以产生更好性能的更好的最小值。考虑使用较低的学习率0.001 或更低,根据需要调整时期),或者在您的SGD 实例上添加权重衰减。这将防止您的模型卡在给出次优结果的局部最小值上。

【讨论】:

  • 谢谢,所有这些建议都有帮助!取出第二个 dropout 并更改学习率最能修复它。
  • @RushilJoshi 很高兴听到这个消息!很高兴能为您提供帮助,祝您编码顺利。
猜你喜欢
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
  • 2018-06-22
  • 2020-03-10
  • 2019-02-26
  • 1970-01-01
相关资源
最近更新 更多