keras concatenate_Keras: 冻结参数、双卡模型迁移CPU测试

90ec9cbbb7c562e2efc9e7629cab0109.png

keras 新手上路,进行一个分类任务,然后遇到了load pre-train model时候,参数是否冻结训练的问题。已经被知乎大佬讨论过的 BN 层训练和测试时候 frozen 开关的问题:

梦里风林:Keras的BN你真的冻结对了吗

github上大佬们都讨论出了解决补丁:

https://github.com/keras-team/keras/pull/9965

这里主要看的是base_model 中的 conv1bn_conv1 和自己在base_model后加的那层bn层的weights是否更新了。

pre-train 中的conv1 和bn_conv1 参数值:

# coding=utf-8

进行pre-train部分参数冻结,并在此基础上训一个epoch:

# 模型定义

解除 base_model 部分冻结,再训1个epoch看看:

# load pretrain model

最后再开启一下 x = BatchNormalization()(x,training=True) 看看变不变撒~

代码同上,我就直接贴结果啦~

# [1.0965952  1.0895271  0.8620075  1.3661622  1.1719416  1.1871375

==================== 2019.11.01 update =======================

做了组分类任务下冻结 base_model 内bn参数训练的对比实验,结论如下:

冻结base_model中的bn(即这些bn参数不训练,就一直套用imagenet的...) train上倒是表现还可以(acc 表现正常...),但是val上差的很严重(0.03+-的acc)

why?

因为train上的数据在训,迫使别的层适应因为这一层“差”而自我调整。但是val/test上的话,没有这个“训”的过程...巧的是,imagenet的分类都是猫狗人啊啥的,我train的任务都是***(反正跟猫狗人这些差别很大就是了...),这样的bn参数之前的“跨越”肯定是不能work的...

所以,还不如不把他们关掉,让model 好好适应适应新数据以备val/test使用

不冻结会导致:在val/ test时候,bn层导致的 diff 是: imagenet data 与train data 结合 与 val/test data 之间的 diff ,这总小过 val/test data 与 imagenet data 之间的直接 diff ...

====================== 2019.11.06 update =======================

没有空闲GPU测试?或许你需要这个:... 把双GPU下训好的model拿到CPU上测试:

from keras import backend as K
from keras.models import Model
from keras.utils import multi_gpu_model
from keras.layers import *
import tensorflow as tf
from keras.backend.tensorflow_backend import set_session
from keras.callbacks import TensorBoard, ModelCheckpoint
import numpy as np
from src.model.efficientNet import EfficientNetB3
from keras.utils import multi_gpu_model
import cv2
import os
import hashlib
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1" # 先需要多GPU把之前多GPU训好的model load进来...

# build model 
class_nums = 100 
input_tensor = Input((300,300,3))
base_model = EfficientNetB3(input_tensor=input_tensor)
x = base_model.layers[-3].output
x = Dense(1024,use_bias=False,activation = 'relu',name='fc')(x) 
x = BatchNormalization()(x,training=False)
x = Dropout(0.3)(x)
classify = Dense(class_nums, activation='softmax',use_bias=False, name='classify')(x)
model = Model(input_tensor, classify) 

multi_model = multi_gpu_model(model, gpus=2, cpu_merge=True)  # 把单model copy到双卡上 
# 因为我训好的model是在双卡上的 所以需要这样  也是因为在双卡上训的model我只保存了weights而没有保存model的结构 
# 所以就需要自己再一遍build model

multi_model.load_weights('model/multi_effi_best.h5')  # 载入双卡model weights

# 注意这里是model.save_.. model就代表我把参数存进单model了  然后save_weights是只存weights 没存model结构..
model.save_weights('single.h5')

# ok现在可以在cpu上载入model了
os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # 写一句这个 强制使用cpu
# single_model 和上面一样,再build下model取名为single_model
single_model.load_weights('single.h5')  

好了愉快的用cpu测试吧... 慢是慢了点 ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值