Keras CNN模型中的训练和损失没有变化

时间:2017-04-28 07:25:26

标签: tensorflow deep-learning keras conv-neural-network

我正在运行CNN进行左右skeprint分类。我有190,000张训练图像,我用10%的图像进行验证。我的模型设置如下所示。我得到了所有图像的路径,读取它们并调整它们的大小。我规范化图像,然后将其适合模型。我的问题是我的训练准确率达到了62.5%,并且损失了大约0.6615-0.6619。我有什么不对劲吗?我怎样才能阻止这种情况发生?

请注意一些有趣的观点:

1)我首先在10张图片上对此进行了测试我遇到了同样的问题,但将优化器更改为adam,将批量大小更改为4个。

2)然后我测试了越来越多的图像,但每次我都需要更改批量大小以获得准确性和损失的改进。有10,000个图像,我不得不使用批量大小500和优化程序rmsprop。然而,准确性和损失在第10纪元后才开始发生变化。

3)我现在正在训练190,000张图像,因为我的GPU处于最大值,所以无法增加批量大小。

imageWidth = 50
imageHeight = 150

def get_filepaths(directory):
file_paths = []
for filename in files:
filepath = os.path.join(root, filename)
file_paths.append(filepath) # Add it to the list.
return file_paths

def cleanUpPaths(fullFilePaths):
cleanPaths = []
for f in fullFilePaths:
if f.endswith(".png"):
cleanPaths.append(f)
return cleanPaths

def getTrainData(paths):
trainData = []
for i in xrange(1,190000,2):
im = image.imread(paths[i])
im = image.imresize(im, (150,50))
im = (im-255)/float(255)
trainData.append(im)
trainData = np.asarray(trainData)
right = np.zeros(47500)
left = np.ones(47500)
trainLabels = np.concatenate((left, right))
trainLabels = np_utils.to_categorical(trainLabels)
return (trainData, trainLabels)

#create the convnet
model = Sequential()

model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(imageWidth,imageHeight,1),strides=1))#32
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu',strides=1))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(1, 3)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (1, 2), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 1)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))

sgd = SGD(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer='rmsprop',metrics=['accuracy'])

#prepare the training data*/

trainPaths = get_filepaths("better1/train")
trainPaths = cleanUpPaths(trainPaths)
(trainData, trainLabels) = getTrainData(trainPaths)
trainData = np.reshape(trainData,(95000,imageWidth,imageHeight,1)).astype('float32')
trainData = (trainData-255)/float(255)

#train the convnet***
model.fit(trainData, trainLabels, batch_size=500, epochs=50, validation_split=0.2)

#/save the model and weights*/
model.save('myConvnet_model5.h5');
model.save_weights('myConvnet_weights5.h5');

5 个答案:

答案 0 :(得分:12)

我现在已经多次讨论过这个问题了,所以想想对它进行一些回顾以及可能的解决方案等,以便将来帮助人们。

问题:模型预测其看到的所有数据的2个(或更多)可能类别之一*

确认问题正在发生方法1:模型在训练时保持在0.5左右(或1 / n,其中n是类数)。 方法2:获取预测中每个班级的计数,并确认它预测所有一个班级。

修正/检查(按某种顺序):

  • 双重检查模型架构:使用model.summary(),检查模型。
  • 检查数据标签:确保您的列车数据的标签在预处理等的某个地方没有混淆(它会发生!)
  • 检查列车数据喂养是随机的:确保您不是一次将您的列车数据提供给模型一类。例如,如果使用ImageDataGenerator().flow_from_directory(PATH),请检查参数shuffle=Truebatch_size是否大于1.
  • 检查预训练的图层是否无法训练:**如果使用预先训练过的模型,请确保使用预先训练过的权重的任何图层都不最初可训练。对于第一个时期,只有新添加的(随机初始化的)层应该是可训练的; for layer in pretrained_model.layers: layer.trainable = False应该在您的代码中的某个位置。
  • 降低学习率:将学习率降低10倍并重试。请注意,每次尝试新的学习速率时,您都必须完全重新初始化您尝试训练的图层。 (例如,我遇到这个问题只有在我到达lr=1e-6后才能解决,所以继续前进!)

如果你们中的任何人知道更多可以进行模型培训的修复/检查,那么请做出贡献,我会尝试更新列表。

**请注意,一旦新的图层经过初步培训并且#34;足够"

,通常可以使更多的预训练模型可训练。

*帮助搜索的问题的其他名称到达此处... keras tensorflow theano CNN卷积神经网络坏训练卡住固定非静态破碎bug bugged堵塞训练优化优化只有0.5准确度不改变只预测一个单一类不会训练模型卡在类模型重置自己之间时代keras CNN相同输出

答案 1 :(得分:1)

我会尝试一些事情。较低的学习率应该有助于获得更多数据。通常,调整优化器应该有所帮助。此外,您的网络似乎非常小,您可能希望通过添加图层或增加图层中的过滤器数量来增加模型的容量。

这里给出了关于如何在实践中应用深度学习的更好描述:(http://www.deeplearningbook.org/contents/guidelines.html)。

答案 2 :(得分:1)

您可以尝试在BatchNornmalization()之后添加MaxPooling2D()图层。它对我有用。

答案 3 :(得分:1)

我还有2件事要添加到DBCerigo的重要列表中。

  • 检查激活函数:默认情况下,某些图层具有linear激活函数,如果您不将一些非线性插入模型中,将无法进行泛化,因此网络会尝试学习如何线性分离非线性特征空间。确保设置非线性是一个很好的检查点。
  • 检查模型复杂度:如果您有一个相对简单的模型,并且它只能学习到第一个或第二个时期,然后停滞不前,则可能是它试图学习太复杂的东西。尝试使模型更深。当使用仅冻结1或2层的冻结模型时,通常会发生这种情况。

尽管第二个可能很明显,但我一次遇到了他的问题,在弄清楚所有内容(数据,批处理,LR ...)之前,我浪费了很多时间。

希望这会有所帮助

答案 4 :(得分:-1)

在我的情况下,激活功能很重要。我从“ sgd”更改为“ a”