【发布时间】:2021-09-07 23:12:19
【问题描述】:
我正在学习用于图像分类的 tensorflow/keras,我觉得我错过了理论的关键部分。
我目前正在处理的任务是使用预训练模型(在本例中为 Resnet50)在训练时间有限的小数据集上进行分类。
数据集是 1600 张 150 x 150 的水果彩色照片,分为 12 类。我正在使用图像生成器:
datagen = ImageDataGenerator(
validation_split=0.25,
rescale=1/255,
horizontal_flip=True,
vertical_flip=True,
width_shift_range=0.2,
height_shift_range=0.2,
rotation_range=90)
train_datagen_flow = datagen.flow_from_directory(
'/datasets/fruits_small/',
target_size=(150, 150),
batch_size=32,
class_mode='sparse',
subset='training',
seed=12345)
val_datagen_flow = datagen.flow_from_directory(
'/datasets/fruits_small/',
target_size=(150, 150),
batch_size=32,
class_mode='sparse',
subset='validation',
seed=12345)
features, target = next(train_datagen_flow)
这是我正在使用的层:
backbone = ResNet50(input_shape=(150, 150, 3),weights='imagenet', include_top=False) 主干.trainable = False
model = Sequential()
optimizer = Adam(lr=0.001)
model.add(backbone)
model.add(GlobalMaxPooling2D())
model.add(Dense(2048,activation='relu'))
model.add(BatchNormalization())
model.add(Dense(512,activation = 'relu'))
model.add(BatchNormalization())
model.add(Dense(12, activation='softmax'))
model.compile(optimizer = optimizer, loss='sparse_categorical_crossentropy',metrics=['acc'])
现在,这是我第一次尝试使用 globalmax 和 resnet50,我正在经历 MASSIVE 过拟合,因为我猜是小数据集。
我已经阅读了一些关于这个主题的文章,并且我尝试了一些标准化工作,但效果有限。
在与我的导师交谈时,他建议我在为密集层选择参数时更严格地考虑 resnet 模型的输出。
这个评论让我意识到我基本上是在任意选择密集层的过滤器,但听起来我应该在构建新层时理解与前一层的输出相关的东西,我不确定什么,但我觉得我错过了一些关键的东西。
这是我当前层摘要的样子:
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
resnet50 (Model) (None, 5, 5, 2048) 23587712
_________________________________________________________________
global_max_pooling2d_3 (Glob (None, 2048) 0
_________________________________________________________________
dense_7 (Dense) (None, 2048) 4196352
_________________________________________________________________
batch_normalization_2 (Batch (None, 2048) 8192
_________________________________________________________________
dense_8 (Dense) (None, 512) 1049088
_________________________________________________________________
batch_normalization_3 (Batch (None, 512) 2048
_________________________________________________________________
dense_9 (Dense) (None, 12) 6156
=================================================================
Total params: 28,849,548
Trainable params: 5,256,716
Non-trainable params: 23,592,832
这是我当前的输出:
Epoch 1/3
40/40 [==============================] - 363s 9s/step - loss: 0.5553 - acc: 0.8373 - val_loss: 3.8422 - val_acc: 0.1295
Epoch 2/3
40/40 [==============================] - 354s 9s/step - loss: 0.1621 - acc: 0.9423 - val_loss: 6.3961 - val_acc: 0.1295
Epoch 3/3
40/40 [==============================] - 357s 9s/step - loss: 0.1028 - acc: 0.9716 - val_loss: 4.8895 - val_acc: 0.1295
所以我读过关于冻结 resnet 层以进行训练以帮助过度拟合和正则化(这是我尝试批量标准化的方法?-尽管这似乎被很多人认为是有问题的..)我还尝试对第一和第二密集层使用 dropout,以及通过增强来增加数据集大小(我有旋转等)
任何意见将不胜感激!
【问题讨论】:
-
可能与传递给
datagen.flow_from_directory的class_mode='sparse',有关。模型的输出是一个softmax,对吧?在我看来,这更符合class_mode='"categorical"。 -
观察力不错,我可以试试! :)
-
事实证明 OHE 是绝对的,它很快就会失去对资源的控制并杀死内核(无论如何看起来)
-
是的,文档确实说“默认值:“分类”。确定返回的标签数组的类型:-“分类”将是 2D one-hot 编码标签“。如果我错了,请纠正我,但 softmax 是 OHE 近似值,对吗?不知道你所说的资源失控是什么意思,但你可能想缩小你的密集层。我认为 5M 可训练参数是相当多的开始。如果将两层都切成两半会怎样?
-
@GillesOttervanger 内核死了就是我所说的资源。我正在为此使用在线平台(这是我正在学习的课程)但是,您将层数减半的建议很棒-我误解并认为我需要为 resnet 的每个输出都有一个神经元,但是,用 256,然后 64 到最后一层 12 显着提高性能
标签: python tensorflow keras conv-neural-network image-classification