Keras模型未训练层,验证精度始终为0.5

时间:2020-02-17 11:05:32

标签: python tensorflow keras conv-neural-network

我的Keras CNN模型(基于an implementation of AlexNet)的训练精度始终接近0.5(在+-0.02之内),而无论哪个时期,验证精度始终始终为0.5。它是一种二元分类模型,其中火车/停车位的比例大致为85/15,在这两个组内,每个类别的图像均按50/50的比例进行分割。

我使用哪种模型架构似乎无关紧要,或者无论是使用随机权重还是ImageNet权重初始化,验证精度始终为0.5。实际上,当我没有将图像按50/50分成其二进制分类时,验证精度将反映出这一点(因此,当我拥有更多属于一类的图像时,验证精度将始终为0.85)。

由于最后一点,我怀疑问题不在于模型或权重优化,而在于我对ImageDataGenerator类的实例化-尽管这只是现阶段的预感。

我在下面包含了我的代码,任何人都可以找到任何显而易见的错误吗?

sz=224 # image width = height = 224
batch_size=64
train_data_dir = r"./crack_dataset/train"
validation_data_dir = r"./crack_dataset/validate"
nb_train_samples = 3416
nb_val_samples = 612

train_datagen = ImageDataGenerator(rescale=1./255)

validation_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(train_data_dir,
                                                    target_size = (sz, sz),
                                                    batch_size=batch_size,
                                                    class_mode='binary')

validation_generator = validation_datagen.flow_from_directory(validation_data_dir,
                                                              target_size = (sz, sz),
                                                              batch_size=batch_size,
                                                              class_mode='binary')

# Create Model 
model = Sequential()

model.add(Conv2D(filters=96, input_shape=input_shape, kernel_size=(11,11), strides=(4,4), padding='valid', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))

model.add(Conv2D(filters=256, kernel_size=(11,11), strides=(1,1), padding='valid', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))

model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='valid', activation='relu'))

model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='valid', activation='relu'))

model.add(Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='valid', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))

model.add(Flatten())
model.add(Dense(4096, input_shape=(256,), activation='relu'))
model.add(Dropout(0.4))

model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.4))

model.add(Dense(1, activation='sigmoid'))

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

model.fit_generator(train_generator,
                    steps_per_epoch = nb_train_samples // batch_size, 
                    epochs=30,
                    validation_data=validation_generator,
                    validation_steps=nb_val_samples // batch_size)

2 个答案:

答案 0 :(得分:1)

问题在于优化器的学习率,该值太大。 如评论中所建议,应将其设置为一个较低的值,接近0。

您可以在下图中看到学习率如何影响分类精度:

example of how the learning rate influences the performance of a model

答案 1 :(得分:-2)

这是一条评论,但是太长了,所以我切换到了正确的答案。

我还没有尝试过您的CNN,但我会修改您的图层。我不是设计CNN架构的专家,但是在具有相同参数的第2层(第5层和第6层)中连续放置2层并没有太多意义,对于我到目前为止所学的知识来说,这毫无用处。尝试一些简单的体系结构,然后从那里“按比例放大”(就体系结构的复杂性而言)。

此外,在“单位数”方面(第1、3、5、6、7层,Conv2D)上下浮动可能不是最佳策略,每次您向上移动时,就获得的功能进行概括因为您从较少的功能开始,所以您要求网络从较小的功能集中创建功能。在某些情况下可能有用,但我认为这不是其中一种。

对于重新缩放,您无需调用“ ImageDataGenerator”,您可以通过以下方式获得相同的结果:

train_datagen = train_datagen/255.0

简化您的位置。