我试图在Keras的CIFAR-10数据集上训练CNN,但我的准确度只有10%左右,基本上是随机的。我培训了50多个时代,批量为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))
答案 0 :(得分:0)
我有什么特别的错误吗?
不一定&#34;错误&#34;,但我可以建议的一些指示是:</ p>
如果您不这样做,重新调整数据非常重要。除了处理[0,255]
范围内的值之外,最好将所有值除以255并处理范围为[0,1]
的数据。这有助于您的模型权重更快收敛,因为与其未缩放版本相比,每个渐变更新将更加重要。
我认为您的辍学可能会影响您的表现。在将数据传递到输出时,更多地看到您正在使用CNN和强(0.5)Dropout。引用this很好的答案:
在提出辍学层的原始论文中,Hinton(2012)在输出前的每个完全连接的(密集)层上使用了辍学(p = 0.5) 强>; 未在卷积层上使用。这成为最常用的配置。
最近的研究表明,将辍学也应用于卷积层有一些价值,尽管水平低得多:p = 0.1或0.2。
因此,或许减少辍学或稍微使用它会产生更好的效果。请注意,您正在对您的数据进行连续退出,这在我看来似乎没有什么帮助,也可能导致问题,因此请考虑重新设计该部分:
dropb = Dropout(0.1)(poolb) #drop
flat = Flatten()(dropb) #flatten
dropc = Dropout(0.5)(flat) #then drop again?
您的学习率可能高于通常使用的。虽然这是SGD的默认学习率,但是学习价值较高,你可能会“匆匆而过”。你的训练并没有找到可以产生更好表现的更好的最小值。考虑使用较低的学习率(0.001
或更低,根据需要调整时期),或者在SGD实例上添加权重衰减。这样可以防止您的模型卡在局部最小值上,从而产生次优结果。