Python 用于签名识别的卷积网络正在训练中,但没有';t收敛

Python 用于签名识别的卷积网络正在训练中,但没有';t收敛,python,neural-network,deep-learning,keras,conv-neural-network,Python,Neural Network,Deep Learning,Keras,Conv Neural Network,我的模型是训练的,并不是每次都预测相同的输出,但它不是收敛的,我的意思是,在第30个纪元中,验证准确率=65%,在第31个纪元中,验证准确率=38%。此外,损失约为27至29,并且根本没有减少(在拟合模型时) 仅供介绍: 问题:识别签名是真是假 数据集:GPDS数据库脱机签名,由4000个用户组成=>24个真实用户/30个伪造用户 网络输入:同一用户的两张签名图片的总和。真+假=假(0级)或真+真=真(1级) 现在,Im培训有大约130k张图片(仅是大约400万张可能总数的图片中的一小部分),其

我的模型是训练的,并不是每次都预测相同的输出,但它不是收敛的,我的意思是,在第30个纪元中,验证准确率=65%,在第31个纪元中,验证准确率=38%。此外,损失约为27至29,并且根本没有减少(在拟合模型时)

仅供介绍:

问题:识别签名是真是假

数据集:GPDS数据库脱机签名,由4000个用户组成=>24个真实用户/30个伪造用户

网络输入:同一用户的两张签名图片的总和。真+假=假(0级)或真+真=真(1级)

现在,Im培训有大约130k张图片(仅是大约400万张可能总数的图片中的一小部分),其中100k张是正版+伪造,30k张是正版+正版,总共有大约150名用户。无论如何,我在训练中使用了班级权重(model.fit_生成器)

有一个问题值得关注:

图像的大小各不相同,但通常约为1200x400像素。这对于内存来说是巨大的,而且训练会持续很长时间,所以我使用了函数flow_的属性target_size,它将图像的大小调整为100x100像素。此外,Im最多可进行100个时代的培训

我在亚马逊使用一个实例,有1个GPU,8个CPU,15Gb RAM

代码如下:



我想知道图像大小调整是否是一个严重的问题,可能是培训不够,可能是解决方案的方法不好,可能是数据集样本不够,可能是优化器不够

谢谢你的关注


Lucas

比较“训练准确度”和“验证准确度”。如果差距太大,说明您的模型太好(称为“过度拟合”)。在这种情况下,增加辍学率或减少过滤器/层的数量等可能会有所帮助。如果两者都不好,那么很可能是您的模型功能不够强大或不适合此任务。PS:我认为“分类交叉熵”比“稀疏分类交叉熵”更适合“softmax”。嘿,丹尼尔。谢谢你的回复。验证精度差且波动,而训练精度相当好(约95%)且不断提高。这可能是一个过度装配的问题。你知道我应该如何解决它吗?我如何知道我的问题的过滤器/层的数量?至于辍学者,我如何知道他们的好比率,以及我应该把他们放在我的网络中的什么地方?没有简单或现成的答案。大多数情况下,你必须尝试和调整。我认为卷积层中的滤波器数量和密集层中的单位在你的模型中是最明显的例如,辍学可以是层(模型中有一层,辍学率为20%),您可以在每次卷积后放置一层。此外,确保训练图像和测试图像在某种程度上是相似的,如果它们有明显的差异,您的模型可能会捕捉到这种差异。
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras import backend as K
from keras.preprocessing.image import ImageDataGenerator
K.set_image_dim_ordering('th')

train_datagen = ImageDataGenerator(rescale=1./255, shear_range=0.2, 
zoom_range=0.2, horizontal_flip=True)
train_generator = train_datagen.flow_from_directory('C:\Users\lucas\Desktop\DL\TrainGenuineForgery', target_size=(100, 100), color_mode="grayscale", batch_size=10, class_mode='binary')

validation_datagen = ImageDataGenerator(rescale=1./255)
validation_generator = validation_datagen.flow_from_directory('C:\Users\lucas\Desktop\DL\Validation', target_size=(100, 100), color_mode="grayscale", batch_size=10, class_mode='binary')

model = Sequential()
model.add(Conv2D(96, (11, 11), input_shape=(1, 100, 100), activation='relu', data_format='channels_first'))
model.add(MaxPooling2D(pool_size=(3, 3)))
model.add(Conv2D(256, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(3, 3)))
model.add(Conv2D(384, (3, 3), activation='relu'))
model.add(Conv2D(256, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(3, 3)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(4096, activation='relu'))
model.add(Dense(2, activation='softmax'))

optAdadelta = keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-08, decay=0.0)
model.compile(loss='sparse_categorical_crossentropy', optimizer=optAdadelta, metrics=['accuracy'])

history = model.fit_generator(train_generator, steps_per_epoch=13000, epochs=100, validation_data=validation_generator, validation_steps=100, class_weight = {0:29,1:71})