如何利用torch7格式的已训练CNN模型完成单张图像推理并返回预测?
嘿,这事儿我熟!下面给你一步步拆解用Torch7预训练CNN模型做单张图像推理的流程,保证你能快速跑通:
1. 加载预训练模型
首先你得把保存的.t7模型加载进来,记得切换到评估模式——这很重要,因为训练时的dropout、BatchNorm层和推理时的行为不一样,不切换的话结果会不准:
-- 加载模型 local model = torch.load('path/to/your/trained_model.t7') -- 切换到评估模式 model:evaluate()
如果你的模型是在GPU上训练的,记得把模型移到GPU(如果要在GPU上推理):
model = model:cuda()
2. 预处理输入图像
Torch7的CNN模型对输入格式有严格要求,必须和训练时的预处理逻辑完全一致,不然预测结果会跑偏。一般流程是这样的:
- 加载图像:用Torch的
image库读取图像,默认会返回3xHxW的张量(通道在前) - 调整尺寸:缩放到模型要求的输入大小(比如ResNet是224x224,VGG是227x227,根据你的模型来)
- 归一化:用训练时用到的均值和标准差做归一化
- 增加batch维度:模型通常接受批量输入,所以要给单张图加一个batch维度(变成
1x3xHxW)
举个具体的代码例子:
-- 加载图像 local img = image.load('path/to/your/test_image.jpg') -- 调整到模型要求的输入尺寸(这里以224x224为例) img = image.scale(img, 224, 224) -- 归一化(假设训练时用的是ImageNet的均值和标准差) local mean = torch.Tensor({0.485, 0.456, 0.406}) local std = torch.Tensor({0.229, 0.224, 0.225}) img:add(-mean:view(3, 1, 1)) -- 均值中心化 img:div(std:view(3, 1, 1)) -- 标准差归一化 -- 增加batch维度 img = img:view(1, 3, 224, 224) -- 如果用GPU推理,把图像移到GPU img = img:cuda()
3. 执行推理
这一步很简单,直接调用模型的forward方法就行:
-- 前向传播得到输出 local output = model:forward(img)
这里的output要看模型最后一层的结构:如果最后是LogSoftMax,那输出是对数概率;如果是线性层,那输出是未归一化的logit,需要转成概率的话可以加个Softmax:
-- 把logit转成概率 local probabilities = torch.nn.Softmax():forward(output) -- 如果用GPU,记得把结果移回CPU方便后续处理 probabilities = probabilities:cpu()
4. 解析预测结果
现在你需要从输出里拿到最可能的预测类别:
-- 找到概率最大的类别索引和对应的概率值 local max_prob, pred_idx = torch.max(probabilities, 2) -- 打印结果 print('预测类别索引:', pred_idx[1][1]) print('对应概率:', max_prob[1][1])
如果你有类别标签的映射表(比如把索引对应到具体的类别名称,比如"猫"、"狗"),可以直接把索引转成名字:
-- 假设你有一个labels表,索引对应类别名 local labels = {'cat', 'dog', 'bird', ...} -- 根据你的数据集调整 print('预测类别名称:', labels[pred_idx[1][1]])
几个关键注意事项
- 预处理一致性:一定要保证图像的预处理(尺寸、归一化、通道顺序)和训练时完全相同,这是预测准确的核心
- 设备一致性:如果模型是GPU训练的,推理时要么在GPU上跑,要么把模型移回CPU(
model = model:cpu()),同时图像也要对应移到相同设备 - 模型输出结构:有些复杂模型可能输出多个结果(比如多任务模型),你需要根据模型的实际结构解析
output
内容的提问来源于stack exchange,提问作者Grigorios Kalliatakis
相关产品推荐
相关产品推荐

