问题描述
我已经建立了一个模型,可以对图像是否为特定的视频游戏进行分类进行训练.我将我的图像pre-scaled
转换为250x250
像素,并将其分成两个分别标记为0
和1
的文件夹(两个二进制类).这两类的数量彼此都在~100
以内,我总共拥有大约3500
张图片.
I have set up a model to train on classifying whether an image is a certain video game or not. I pre-scaled
my images into 250x250
pixels and have them separated into two folders (the two binary classes) labelled 0
and 1
. The amount of both classes are within ~100
of each other and I have around 3500
images in total.
以下是培训过程,模型设置和一些预测的照片: https://imgur.com /a/CN1b6LV
Here are photos of the training process, the model set up and some predictions: https://imgur.com/a/CN1b6LV
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0,
zoom_range=0,
horizontal_flip=True,
width_shift_range=0.1,
height_shift_range=0.1,
validation_split=0.2)
train_generator = train_datagen.flow_from_directory(
'data\\',
batch_size=batchsize,
shuffle=True,
target_size=(250, 250),
subset="training",
class_mode="binary")
val_generator = train_datagen.flow_from_directory(
'data\\',
batch_size=batchsize,
shuffle=True,
target_size=(250, 250),
subset="validation",
class_mode="binary")
pred_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0,
zoom_range=0,
horizontal_flip=False,
width_shift_range=0.1,
height_shift_range=0.1)
pred_generator = pred_datagen.flow_from_directory(
'batch_pred\\',
batch_size=30,
shuffle=False,
target_size=(250, 250))
model = Sequential()
model.add(Conv2D(input_shape=(250, 250, 3), filters=25, kernel_size=3, activation="relu", padding="same"))
model.add(Conv2D(filters=32, kernel_size=3, activation="relu", padding="same"))
model.add(Conv2D(filters=32, kernel_size=3, activation="relu", padding="same"))
model.add(MaxPooling2D(pool_size=2, padding="same", strides=(2, 2)))
model.add(BatchNormalization())
model.add(Conv2D(filters=64, kernel_size=3, activation="relu", padding="same"))
model.add(Conv2D(filters=64, kernel_size=3, activation="relu", padding="same"))
model.add(Conv2D(filters=64, kernel_size=3, activation="relu", padding="same"))
model.add(MaxPooling2D(pool_size=2, padding="same", strides=(2, 2)))
model.add(BatchNormalization())
model.add(Conv2D(filters=128, kernel_size=3, activation="relu", padding="same"))
model.add(Conv2D(filters=128, kernel_size=3, activation="relu", padding="same"))
model.add(Conv2D(filters=128, kernel_size=3, activation="relu", padding="same"))
model.add(MaxPooling2D(pool_size=2, padding="same", strides=(2, 2)))
model.add(Conv2D(filters=256, kernel_size=3, activation="relu", padding="same"))
model.add(Conv2D(filters=256, kernel_size=3, activation="relu", padding="same"))
model.add(Conv2D(filters=256, kernel_size=3, activation="relu", padding="same"))
model.add(MaxPooling2D(pool_size=2, padding="same", strides=(2, 2)))
model.add(BatchNormalization())
dense = False
if dense:
model.add(Flatten())
model.add(Dense(250, activation="relu"))
model.add(BatchNormalization())
model.add(Dense(50, activation="relu"))
else:
model.add(GlobalAveragePooling2D())
model.add(Dense(1, activation="softmax"))
model.compile(loss='binary_crossentropy',
optimizer=Adam(0.0005), metrics=["acc"])
callbacks = [EarlyStopping(monitor='val_acc', patience=200, verbose=1),
ModelCheckpoint(filepath="model_checkpoint.h5py",
monitor='val_acc', save_best_only=True, verbose=1)]
model.fit_generator(
train_generator,
steps_per_epoch=train_generator.samples // batchsize,
validation_data=val_generator,
validation_steps=val_generator.samples // batchsize,
epochs=500,
callbacks=callbacks)
根据model
按时期迭代数据,查找正确数量的图像等方法,一切似乎都可以正确运行.但是,尽管验证准确度高,损失小,准确性高,但我的预测始终是50%
等
Everything appears to run correctly in terms of the model
iterating the data by epoch, it finding the correct number of images etc. However, my predictions are always 50%
despite a good validation accuracy, low loss, high accuracy etc.
我不确定自己做错了什么,我们将不胜感激.
I'm not sure what I'm doing wrong and any help would be appreciated.
推荐答案
问题是您正在具有一个单元的密集层上使用softmax
. Softmax函数将其输入归一化,以使其元素之和等于1.因此,如果它具有一个单位,则输出将始终为1.相反,对于二进制分类,您需要使用sigmoid
函数作为最后一层的激活函数.
The problem is that you are using softmax
on a Dense layer with one unit. Softmax function normalizes its input such that the sum of its elements becomes equal to one. So if it has one unit, then the output would be always 1. Instead, for binary classification you need to use sigmoid
function as the activation function of last layer.
这篇关于用于二进制分类预测的Keras的fit_generator()始终为50%的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!