競賽傳送門: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-