如何访问Core ML模型中CNN内部层(如conv5)的输出?
如何在Core ML中访问CNN内部层的输出
当然支持啦!Core ML完全可以像Caffe那样获取CNN内部层(比如你说的conv5)的输出,我给你两种实用的实现方式,你可以根据自己的场景选择:
方法一:转换模型时直接指定输出层
如果你还没完成模型转换,或者愿意重新转换一次,这是最直接的方式。在使用coremltools的convert函数时,通过output_feature_names参数同时保留原有的分类输出和你想要的内部层输出就行。
举个例子,假设你的Caffe AlexNet模型定义在alexnet.prototxt,权重文件是alexnet.caffemodel,代码可以这么写:
import coremltools as ct # 加载Caffe模型结构和权重 caffe_model = ct.utils.load_caffe('alexnet.prototxt', 'alexnet.caffemodel') # 转换时同时指定分类输出和conv5的输出 coreml_model = ct.convert( caffe_model, input_names=["image"], # 输入特征的名字,对应模型的输入 output_feature_names=["classLabel", "conv5"] # 保留原分类输出,添加conv5的输出 ) # 保存修改后的模型 coreml_model.save("AlexNetWithConv5.mlmodel")
这里要注意:conv5的名字必须和你Caffe prototxt里定义的层名完全一致,如果不确定,可以用Netron工具打开Caffe模型或者转换后的Core ML模型查看层结构和名字。
方法二:修改已转换好的Core ML模型
如果你已经有了转换好的.mlmodel文件,不想重新转换,可以直接修改模型的spec来添加内部层输出:
import coremltools as ct from coremltools.proto import FeatureTypes_pb2 # 加载已有的Core ML模型 model = ct.models.MLModel("AlexNet.mlmodel") spec = model.get_spec() # 先确认conv5层的输出名字(用Netron查看模型结构就能找到) # 添加这个输出到模型中,这里假设conv5的输出是(256, 13, 13)的张量 output_type = FeatureTypes_pb2.ArrayFeatureType() output_type.shape.extend([256, 13, 13]) # 对应conv5输出的维度 ct.utils.feature_utils.add_output(spec, "conv5", output_type) # 保存修改后的模型 new_model = ct.models.MLModel(spec) new_model.save("AlexNetWithConv5.mlmodel")
在iOS/macOS代码中获取内部层输出
修改好模型后,在Swift代码里调用模型时,就能直接拿到conv5的输出了:
import CoreML // 假设你已经把模型添加到项目中,自动生成了对应的模型类 let model = AlexNetWithConv5() // 准备输入图像(这里假设你已经把UIImage转换成了模型需要的CVPixelBuffer) guard let testImage = UIImage(named: "test.jpg"), let pixelBuffer = testImage.convertToCVPixelBuffer() else { print("图像转换失败") return } do { let output = try model.prediction(image: pixelBuffer) // 获取分类结果 let resultLabel = output.classLabel // 获取conv5的输出张量 let conv5Features = output.conv5 // 这里就可以对conv5的输出做进一步处理了 } catch { print("模型预测失败:\(error.localizedDescription)") }
小提示:Netron工具真的很实用,不管是查看Caffe还是Core ML的模型结构、层名、输出维度,都能一目了然,强烈推荐用它来确认你要访问的层的准确信息。
内容的提问来源于stack exchange,提问作者AJ Z.
相关产品推荐
相关产品推荐

