MxNet内置预训练VGG16模型推理结果异常求助
解决MxNet预训练VGG16识别猫为鸟类的问题
我一眼就揪出问题的核心了——你用OpenCV读取图片的通道顺序是BGR,但MxNet的预训练VGG16模型是基于RGB格式训练的,这直接导致输入数据的颜色分布完全不符合模型预期,才会出现把猫识别成鸟类的离谱结果,同时也引发了color_normalize输出数值异常的问题。
问题根源拆解
OpenCV的cv2.imread()默认读取的图片通道顺序是BGR,而ImageNet数据集的图片标准格式是RGB,MxNet所有基于ImageNet训练的预训练模型,都是以RGB数据为输入训练的。通道顺序颠倒后,颜色归一化的结果完全偏离模型学习到的特征分布,自然无法正确分类。
修正后的完整代码
from mxnet.gluon.model_zoo.vision import vgg16 from mxnet.image import color_normalize import mxnet as mx import numpy as np import cv2 data_dir = 'F:/Temps/Models_tmp/' img_dir = 'F:/Temps/DataSets/ImageNet/' # 读取图片并转换通道顺序为RGB(关键修正) img = cv2.imread(img_dir + 'cat.jpg') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = mx.nd.array(img) # 后续预处理步骤保持不变 img,_ = mx.image.center_crop(img,(224,224)) img = img/255 img = color_normalize(img,mean=mx.nd.array([0.485, 0.456, 0.406]),std=mx.nd.array([0.229, 0.224, 0.225])) img = mx.nd.transpose(img, axes=(2, 0, 1)) img = img.expand_dims(axis=0) # 加载标签 with open(data_dir + 'synset.txt', 'r') as f: labels = [l.rstrip() for l in f] # 加载模型并推理 aVGG = vgg16(pretrained=True,root='F:/Temps/Models_tmp/') features = aVGG.forward(img) features = mx.ndarray.softmax(features) features = features.asnumpy() features = np.squeeze(features) a = np.argsort(features)[::-1] # 输出Top5结果 for i in a[0:5]: print('probability=%f, class=%s' %(features[i], labels[i]))
额外优化建议
你也可以直接用MxNet自带的mx.image.imread()来读取图片,它默认就是RGB格式,能彻底避免通道顺序的坑:
# 替换OpenCV读取方式为MxNet自带函数 img = mx.image.imread(img_dir + 'cat.jpg')
修正后你可以检查color_normalize的输出,数值绝对值应该不会再大面积超过1,这也能验证预处理是否正确。调整后模型就能正确识别猫的类别啦!
内容的提问来源于stack exchange,提问作者Blue Bird
相关产品推荐
相关产品推荐

