TinyMind 多标签图像分类竞赛 之路
竞赛传送门:https://www.tinymind.cn/competitions/42
我们就是傻狗天仙配啦~
决赛排行榜:
这次比赛感谢第一名的 baseline:https://blog.csdn.net/guleileo/article/details/81946511
我们的代码基于这个baseline,省去了自己编写数据读取、评分准则的麻烦。
首先,我们将baseline的模型换成ResNet50、DenseNet201空模型效果不好;然后,我们选择了迁移学习,参考博客:https://blog.csdn.net/tsyccnh/article/details/78889838,后来将其InceptionV3换成InceptionResNetV2:
from keras.applications.inception_resnet_v2 import InceptionResNetV2,preprocess_input base_model = InceptionResNetV2(weights='imagenet',include_top=False) x = base_model.output x = GlobalAveragePooling2D()(x) x = Dense(1024,activation='relu')(x) predictions = Dense(6941,activation='sigmoid')(x) model = Model(inputs=base_model.input, outputs=predictions) model.summary()
加入了imgaug库的数据增强:
from imgaug import augmenters as iaa seq = iaa.Sequential([ iaa.CropAndPad(percent=(-0.1, 0.1)), iaa.Sometimes(0.5, iaa.GaussianBlur(sigma=(0, 0.5)) ), iaa.ContrastNormalization((0.75, 1.5)), iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.05*255)), ], random_order=True) imglist=[] imglist.append(X_train) images_aug = seq.augment_images(X_train)
之后基于这个模型开始了调节batchsize、steps及两个epoch的工作,我们调节的最佳结果:
batch_size = 128 setup_to_transfer_learning(model, base_model) history_t1 = model.fit_generator(train_generator, steps_per_epoch=274, validation_data = val_generator, epochs=10, callbacks=[reduce], verbose=1) setup_to_fine_tune(model,base_model) history_ft = model.fit_generator(train_generator, steps_per_epoch=274, epochs=8, validation_data=val_generator, validation_steps=10, callbacks=[reduce], verbose=1)
这时,就得到了预赛排名榜的分数44.3。
下面是得到45.89分的两个关键的工作啦!
第一,将arr2tag函数中的0.5改成0.3。原因:数据集小,很多标签对应的训练图片数量少,预测得到的概率值低,所以需要调低阈值让更多正确标签预测到。
第二,模型融合。我们是将InceptionV3和InceptionResNetV2两个模型的结果融合,先将两个模型保存训练出来,然后求两个模型预测出的标签的并集。
部分代码如下:
def arr2tag(arr1, arr2): tags = [] for i in range(arr1.shape[0]): tag = [] index1 = np.where(arr1[i] > 0.3 ) index2 = np.where(arr2[i] > 0.3 ) index1 = index1[0].tolist() index2 = index2[0].tolist() index = list(set(index1).union(set(index2))) tag = [hash_tag[j] for j in index] tags.append(tag) return tags
model = load_model('model1.h5') y_pred1 = model.predict(X_test) del model model = load_model('model2.h5') y_pred2 = model.predict(X_test) y_tags = arr2tag(y_pred1, y_pred2)
针对以上两个关键工作,可以提升的点:
两个0.3还可以调的精确些;模型融合还可以加入其它的模型一起融合。
小心情:没拿到第一还是有点遗憾的,报名后好长时间没有做,也没想到更好的方法,所以重心都放在调参上,学习率、epoch都试了很多,epoch甚至需要一个一个的减小。关键工作都在是比赛结束前一天晚上和最后的上午完成的。我们队由傻狗和天仙两人组成,天仙之前在一个公众号里看到模型融合的方法,最后一天晚上决定再试一试这种方法,傻狗很聪明,训练需要保存的模型时将arr2tag函数里的0.5改成0.4,早晨提交发现结果提升了1分多,欢喜得不得了。这次比赛还是收获颇丰哒~
傻狗刚刚说给大家公开一下代码吧,那好吧:https://github.com/feifanrensheng/TinyMind-