是否有可能训练一个拥有庞大类别数量的图像分类网络?(例如30万个类别),每个类别至少包含10张图片,分为训练/测试/验证集(即超过300万张250x250x3的图片)。
我尝试使用ResNet50模型并将批次大小降低到1来训练数据集,但仍然遇到了内存溢出问题(使用2080 Ti)。我发现内存溢出是由参数过多引起的,因此我尝试使用一个非常基础的10层模型,并将批次大小设置为1来训练网络。虽然它能运行,但速度和准确度不出所料地非常差。
有没有什么方法可以将训练集分成更小的类别部分,比如说:
第一个.h5文件 = 类别1 ~ 20,000
第二个.h5文件 = 类别20,001 ~ 40,000
第三个.h5文件 = 类别40,001 ~ 60,000,等等。
然后再将它们合并成一个单一的h5文件,可以加载并识别所有30万个不同类别?
根据@人名的建议进行的编辑:
我认为我已经成功地将两个模型合并成一个,但合并后的模型层数几乎翻倍了…
源代码:
model1 = load_model('001.h5')model2 = load_model('002.h5')for layer in model1.layers: layer._name = layer._name + "_1" # 避免重复的层名称,否则会抛出错误 layer.trainable = Falsefor layer in model2.layers: layer._name = layer._name + "_2" layer.trainable = Falsex1 = model1.layers[-1].outputclasses = x1.shape[1]x1 = Dense(classes, activation='relu', name='out1')(x1)x2 = model2.layers[-1].outputx2 = Dense(x2.shape[1], activation='relu', name='out2')(x2)classes += x2.shape[1]x = concatenate([x1, x2])output_layer = Dense(classes, activation='softmax', name='combined_layer')(x)new_model = Model(inputs=[model1.inputs, model2.inputs], outputs=output_layer)new_model.summary()new_model.save('new_model.h5', overwrite=True)
合并后的模型看起来是这样的:
Model: "model"_________________________________________________________________________Layer (type) Output Shape Param # Connected to =========================================================================input_1_1 (InputLayer) [(None, 224, 224, 3) 0 _________________________________________________________________________input_1_2 (InputLayer) [(None, 224, 224, 3) 0 _________________________________________________________________________conv1_pad_1 (ZeroPadding2D) (None, 230, 230, 3) 0 input_1_1[0][0] _________________________________________________________________________conv1_pad_2 (ZeroPadding2D) (None, 230, 230, 3) 0 input_1_2[0][0] _________________________________________________________________________conv1_conv_1 (Conv2D) (None, 112, 112, 64) 9472 conv1_pad_1[0][0] _________________________________________________________________________conv1_conv_2 (Conv2D) (None, 112, 112, 64) 9472 conv1_pad_2[0][0] ......conv5_block3_out_1 (Activation) (None, 7, 7, 2048) 0 conv5_block3_add_1[0][0] _________________________________________________________________________conv5_block3_out_2 (Activation) (None, 7, 7, 2048) 0 conv5_block3_add_2[0][0] _________________________________________________________________________avg_pool_1 (GlobalAveragePoolin (None, 2048) 0 conv5_block3_out_1[0][0] _________________________________________________________________________avg_pool_2 (GlobalAveragePoolin (None, 2048) 0 conv5_block3_out_2[0][0] _________________________________________________________________________probs_1 (Dense) (None, 953) 1952697 avg_pool_1[0][0] _________________________________________________________________________probs_2 (Dense) (None, 3891) 7972659 avg_pool_2[0][0] _________________________________________________________________________out1 (Dense) (None, 953) 909162 probs_1[0][0] _________________________________________________________________________out2 (Dense) (None, 3891) 15143772 probs_2[0][0] _________________________________________________________________________concatenate (Concatenate) (None, 4844) 0 out1[0][0] out2[0][0] _________________________________________________________________________combined_layer (Dense) (None, 4844) 23469180 concatenate[0][0] =========================================================================Total params: 96,622,894Trainable params: 39,522,114Non-trainable params: 57,100,780
如您所见,由于Model(inputs=[input1, input2]),所有层都被翻倍了。这将在我稍后使用这个模型进行图像预测时造成问题。有没有办法可以在不翻倍所有前层的情况下,只添加尾部的密集层?按照这个速度,我将比以前更快地被参数数量所压垮…
回答:
从技术上讲这是可能的,所以你可以做的是,因为你有3个分类器(1.h5,2.h5,3.h5),你可以加载这些模型及其权重,然后使用tensorflow中的功能API https://www.tensorflow.org/guide/keras/functional,其中concatenate() API将3个分类器的输出合并成一个向量,然后使用几个带有激活函数的密集网络进行最终预测。