将Caffe训练的Caffenet转为移动端模型后,如何提取图像特征?
解决移动端转换后CNN特征提取的问题
我之前也碰到过一模一样的情况——在Caffe里随手就能用net.blobs['conv5'].data[0, : , : , :]拿到特征,转成移动端模型后突然就找不到这种便捷的方式了。下面是我亲测有效的几个解决思路:
1. 转换阶段就指定保留目标层为输出
绝大多数模型转换工具(像caffe2onnx、MMdnn、TensorFlow转换脚本这类)都支持指定额外输出节点的功能。你只需要在转换命令里把conv5设为模型的输出之一,这样转出来的移动端模型就会把该层的特征作为一个输出结果。
举个例子,用ONNX转换工具时,可以加类似这样的参数:
python -m caffe2onnx.convert --input model.prototxt --weight model.caffemodel --output model.onnx --output-names conv5
转换完成后,在移动端推理时,直接获取这个新增的输出就能拿到conv5的特征了。
2. 用移动端框架的API提取中间层输出
不同的移动端推理框架有各自的中间层获取方式,举几个常见的例子:
- TensorFlow Lite:如果转换时保留了层名称,可以用
interpreter.get_tensor(interpreter.get_output_details()[1]['index'])来获取(假设conv5是第二个输出);如果名称没保留,先通过interpreter.get_tensor_details()遍历所有张量,找到对应conv5的张量索引。 - ncnn:加载模型后,创建
Extractor对象,直接调用extract("conv5", feature_mat)就能把特征提取到feature_mat里(前提是你确认模型里的层名还是conv5)。 - Core ML:转换时在模型配置里添加
conv5作为输出,推理后直接从结果字典里取对应的键值即可。
3. 先确认目标层的名称是否被修改
很多转换工具会自动重命名层(比如加前缀、简化名称),所以转换完成后,一定要用Netron这种模型可视化工具打开转换后的模型,确认conv5层的实际名称是什么——比如可能变成了conv5_1或者C5之类的。找对正确的层名是提取特征的前提。
另外还要注意:移动端模型的输入输出维度可能和Caffe原生有差异,比如有些框架会默认去掉batch维度,所以拿到特征后可能需要手动调整维度,比如从(C, H, W)转成(1, C, H, W)来匹配你之前的处理逻辑。
内容的提问来源于stack exchange,提问作者AJ Z.
相关产品推荐
相关产品推荐

