如何关闭Turi Create生成的Core ML图像分类器的Softmax层?
如何用Turi Create生成不带Softmax层的Core ML图像分类器
没问题,这事儿完全能搞定,不用费劲深度修改Turi Create源码,给你两种实用方法,按需选择:
方法1:导出后修改Core ML模型(最简单快捷)
Turi Create默认导出的图像分类模型带Softmax层,但我们可以用Core ML Tools轻松移除它,步骤如下:
- 先按常规流程训练并导出模型:
import turicreate as tc # 加载你的图像数据集 data = tc.image_analysis.load_images("你的数据集文件夹路径", with_path=True) # 从路径提取标签(根据你的文件夹结构调整逻辑) data["label"] = data["path"].apply(lambda path: path.split("/")[-2]) # 训练图像分类器 model = tc.image_classifier.create(data, target="label") # 导出默认带Softmax的Core ML模型 model.export_coreml("OriginalWithSoftmax.mlmodel") - 用Core ML Tools加载模型并移除Softmax层:
这样得到的模型输出就是预Softmax的logits值,你可以在App里自行计算Softmax。import coremltools as ct # 加载刚导出的模型 mlmodel = ct.models.MLModel("OriginalWithSoftmax.mlmodel") # 获取模型的神经网络结构规范 nn_spec = mlmodel.get_spec() # 遍历所有层,找到Softmax层并标记删除 softmax_layer_indices = [] for idx, layer in enumerate(nn_spec.neuralNetwork.layers): if layer.WhichOneof("layer") == "softmax": softmax_layer_indices.append(idx) # 倒序删除,避免索引错乱 for idx in reversed(softmax_layer_indices): del nn_spec.neuralNetwork.layers[idx] # 保存修改后的无Softmax模型 modified_model = ct.models.MLModel(nn_spec) modified_model.save("ClassifierWithoutSoftmax.mlmodel")
方法2:训练阶段自定义模型结构(更灵活)
如果你想从源头就避免添加Softmax层,可以用Turi Create的NeuralNetClassifier搭建自定义网络,手动控制最后一层:
- 准备数据集并构建自定义网络:
import turicreate as tc # 加载数据集并处理标签 data = tc.image_analysis.load_images("你的数据集文件夹路径", with_path=True) data["label"] = data["path"].apply(lambda path: path.split("/")[-2]) # 将标签映射为数值ID(分类任务需要) data = data.add_row_number() label_id_map = data.groupby("label", {"class_id": tc.aggregate.MIN("row_number")}) data["class_id"] = data["label"].apply(lambda x: label_id_map[label_id_map["label"] == x]["class_id"][0]) # 构建自定义神经网络 net = tc.neural_networks.Sequential() # 添加预训练特征提取器(比如ResNet50,也可以用其他或自定义卷积层) net.add(tc.image_analysis.resnet_v2_50_feature_extractor()) # 添加全局平均池化层,压缩特征维度 net.add(tc.layers.GlobalAveragePooling2D()) # 添加线性输出层,维度等于类别数,**不要设置激活函数** num_classes = len(data["label"].unique()) net.add(tc.layers.Dense(num_classes, activation=None)) # 训练模型,注意损失用softmax_cross_entropy(内部会自动处理logits) model = tc.neural_net_classifier.create( data, target="class_id", network=net, loss="softmax_cross_entropy", metric="accuracy" ) - 导出模型即可:
这个模型的输出直接就是logits,完全符合你的需求。model.export_coreml("CustomNoSoftmaxClassifier.mlmodel")
小提示
- 训练时用
softmax_cross_entropy损失完全没问题,哪怕最后一层没有Softmax,Turi Create会在计算损失时自动处理logits,不影响模型训练效果。 - 修改完模型后,记得在Xcode里查看模型的输出类型,确认是对应每个类别的向量(logits),而不是概率值。
内容的提问来源于stack exchange,提问作者Timothy Moose
相关产品推荐
相关产品推荐

