在 CIFAR-100 上训练 Keras MobileNetV2(从头开始)
Training Keras MobileNetV2 on CIFAR-100 (from scratch)
我想在 CIFAR-100 上从头开始训练 MobileNetV2,我得到以下结果,它在一段时间后停止学习。
这是我的代码。我希望看到至少 60-70% 的验证准确率,我想知道我是否必须在 imagenet 上 pre-train 还是因为 CIFAR100 只是 32x32x3?
由于一些限制,我使用的是 Keras 2.2.4 和 tensorflow 1.12.0。
from keras.applications.mobilenet_v2 import MobileNetV2
[..]
(x_train, y_train), (x_test, y_test) = cifar100.load_data()
x_train = x_train / 255
x_test = x_test / 255
y_train = np_utils.to_categorical(y_train, 100)
y_test = np_utils.to_categorical(y_test, 100)
input_tensor = Input(shape=(32,32,3))
x = MobileNetV2(include_top=False,
weights=None,
classes=100)(input_tensor)
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
x = Dense(512, activation='relu')(x)
preds = Dense(100, activation='softmax')(x)
model = Model(inputs=[input_tensor], outputs=[preds])
optimizer = Adam(lr=1e-3)
model.compile(loss="categorical_crossentropy",
optimizer=optimizer,
metrics=['accuracy'])
epochs = 300
batch_size = 64
callbacks = [ReduceLROnPlateau(monitor='val_loss', factor=np.sqrt(0.1), cooldown=0, patience=10, min_lr=1e-6)]
generator = ImageDataGenerator(rotation_range=15,
width_shift_range=5. / 32,
height_shift_range=5. / 32,
horizontal_flip=True)
generator.fit(x_train)
model.fit_generator(generator.flow(x_train, y_train),
validation_data=(x_test, y_test),
steps_per_epoch=(len(x_train) // batch_size),
epochs=epochs, verbose=1,
callbacks=callbacks)
嗯,MobileNets
和所有其他基于 imagenet 的模型对图像进行 5 次下采样(224 -> 7),然后执行 GlobalAveragePooling2D
,然后是输出层。
我认为直接在这些模型上使用 32*32 图像不会给你一个好的结果,因为即使在 GlobalAveragePooling2D
.
之前张量形状也会是 1*1
也许你应该尝试调整图像大小以像 96*96 or remove the first stride=2
. Take the NASNet paper 作为参考,他们在 Cifar 和 ImageNet 版本中都使用 4 个池化,而只有 ImageNet 版本在第一个卷积层中有 stride=2
。
我想在 CIFAR-100 上从头开始训练 MobileNetV2,我得到以下结果,它在一段时间后停止学习。
这是我的代码。我希望看到至少 60-70% 的验证准确率,我想知道我是否必须在 imagenet 上 pre-train 还是因为 CIFAR100 只是 32x32x3? 由于一些限制,我使用的是 Keras 2.2.4 和 tensorflow 1.12.0。
from keras.applications.mobilenet_v2 import MobileNetV2
[..]
(x_train, y_train), (x_test, y_test) = cifar100.load_data()
x_train = x_train / 255
x_test = x_test / 255
y_train = np_utils.to_categorical(y_train, 100)
y_test = np_utils.to_categorical(y_test, 100)
input_tensor = Input(shape=(32,32,3))
x = MobileNetV2(include_top=False,
weights=None,
classes=100)(input_tensor)
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
x = Dense(512, activation='relu')(x)
preds = Dense(100, activation='softmax')(x)
model = Model(inputs=[input_tensor], outputs=[preds])
optimizer = Adam(lr=1e-3)
model.compile(loss="categorical_crossentropy",
optimizer=optimizer,
metrics=['accuracy'])
epochs = 300
batch_size = 64
callbacks = [ReduceLROnPlateau(monitor='val_loss', factor=np.sqrt(0.1), cooldown=0, patience=10, min_lr=1e-6)]
generator = ImageDataGenerator(rotation_range=15,
width_shift_range=5. / 32,
height_shift_range=5. / 32,
horizontal_flip=True)
generator.fit(x_train)
model.fit_generator(generator.flow(x_train, y_train),
validation_data=(x_test, y_test),
steps_per_epoch=(len(x_train) // batch_size),
epochs=epochs, verbose=1,
callbacks=callbacks)
嗯,MobileNets
和所有其他基于 imagenet 的模型对图像进行 5 次下采样(224 -> 7),然后执行 GlobalAveragePooling2D
,然后是输出层。
我认为直接在这些模型上使用 32*32 图像不会给你一个好的结果,因为即使在 GlobalAveragePooling2D
.
也许你应该尝试调整图像大小以像 96*96 or remove the first stride=2
. Take the NASNet paper 作为参考,他们在 Cifar 和 ImageNet 版本中都使用 4 个池化,而只有 ImageNet 版本在第一个卷积层中有 stride=2
。