在网上下载的MXNet预训练模型常常是完整的,但是在实际应用中,我们一般只需要网络中某一层作为特征提取,这个时候就需要重建模型,使得网络最后的输出是特征。
加载预训练模型
加载模型使用model.FeedForward.load
就可以了,后面的参数分别是模型的名字、迭代次数和batch大小,需要根据实际模型进行修改:
import mxnet as mx
import numpy as np
model=mx.model.FeedForward.load('model_name',1,num_batch_size=1)
找到特征层
别人训练好的模型我们常常不知道有哪些层,这时候需要列出所有的层,以便于我们找到特征层:
internals=model.symbol.get_internals() #list all symbol
internals.list_outputs()
列出网络中所有的层,像这样:
['data',
'conv1_weight',
'conv1_bias',
'conv1_output',
'slice1_output0',
'slice1_output1',
'_maximum0_output',
……
……
'slice_fc1_output0',
'slice_fc1_output1',
'_maximum9_output',
'drop1_output',
'fc2_weight',
'fc2_bias',
'fc2_output',
'softmax_label',
'softmax_output']
重建符号与模型
比如我们要把drop1_output
作为输出特征:
fea_symbol=internals['drop1_output'] #choose feature layer
feature_extractor=mx.model.FeedForward(symbol=fea_symbol,numpy_batch_size=1,arg_params=model.arg_params,aux_params=model.aux_params,allow_extra_params=True)
这里的feature_extractor
就是我们的新模型。
重新保存
得到的新模型当然要保存下来:
feature_extractor.save('new_model_name',1) #save new symbol and model
模型名字要根据自己的情况做一些修改。
测试一下:
new_model=mx.model.FeedForward.load('new_model_name',1,num_batch_size=1)
完整代码
完整代码在我的GitHub上:
相关issue: