训练过程中做测试的精度同保存下来的模型重新load后测试精度不同


#1

各位大佬好,我在使用GluonCV的MobileNetV3_Large在自己的数据上做finetuning,代码是按照GluonCV的tutorials来写的,test代码和tutorial里面几乎都一样,我想训练过程每隔一段做一次test,根据test结果来保存模型,这部分代码参考了这个帖子
我在每一个backward和trainer.step后面加入了test来做测试,然后根据测试结果决定是否保存当前模型

    for i, batch in enumerate(train_data):
        data = gluon.utils.split_and_load(batch[0], ctx_list=ctx, batch_axis=0, even_split=False)
        label = gluon.utils.split_and_load(batch[1], ctx_list=ctx, batch_axis=0, even_split=False)
        with ag.record():
            outputs = [finetune_net(X) for X in data]
            loss = [L(yhat, y) for yhat, y in zip(outputs, label)]
        for l in loss:
            l.backward()
        trainer.step(batch_size)
        nd.waitall()
        best_acc = test(net, val_data, ctx)
        if check_highest(best_acc):
            net.export(save_name, epoch)
            net.save_parameters(save_name)

这样保存下来的模型,再重新load进来再所有训练开始之前用同一个test函数做测试,会出现精度不同的情况。不管gluon的params还是用SymbolBlock.import载入Symbol形式的模型都是如此。
一开始搜了一些论坛里面的帖子,怀疑是BN的问题,于是我重新load模型的时候,手动把所有BN的use_global_stats参数设置为True,但结果还是和之前直接load的结果一样,同训练过程中的测试结果不同。
test代码处加了ag.predict_mode()还是同上
请各位帮忙分析一下问题所在吧


#2

破案了
是DropOut的问题
测试时候手动把DropOut._rate设置为0测试出来就正常了
同时也确认了BN是会自动根据是否training进行调整
坑爹啊,不是说DropOut可以自动调整的吗:rofl::rofl::rofl: