我在Matlab 2019b中训练了一个CNN,它可以进行二进制分类。当CNN在测试数据集中进行测试时,其准确率约为95%。我使用了exportONNXNetwork函数,这样我就可以在Keras的Tensorflow中实现我的CNN。这是我在keras中使用ONNX文件时使用的代码:
import onnx
from onnx_tf.backend import prepare
import numpy as np
from numpy import array
from IPython.display import display
from PIL import Image
onnx_model = onnx.load("model.onnx")
tf_rep = prepare(onnx_model)
img = Image.open("image.jpg").resize((224,224))
img = array(img).reshape(1,3,224,224)
img = img.astype(np.uint8)
classification = tf_rep.run(img)
print(classification)
当这个python代码在相同的测试数据集上测试时,它将几乎所有的东西都分类为类0
,还有一些情况是类1
。我不知道为什么会发生这种事。
乍一看,我认为您需要排列图像轴,而不是重塑:
img = Image.open("image.jpg").resize((224,224))
img = array(img).transpose(2, 0, 1)
img = np.expand_dims(img, 0)
从PIL获得的图像采用通道最后一种格式,即形状为(height, width, channels)
的张量,在本例中为(224, 224, 3)
。您的模型期望通道优先格式的输入,即形状为(channels, height, width)
的张量,在本例中为(3, 224, 224)
。
您需要将最后一个轴移到前面。如果您使用整形,NumPy将以C顺序遍历数组(最后一个轴索引变化最快(,这意味着您的图像最终将被打乱。这在一个例子中更容易理解:
>>> img = np.arange(48).reshape(4, 4, 3)
>>> img[0, 0, :]
array([0, 1, 2])
(0,0(像素的RGB值为(0,1,2(。如果使用np.transpose()
,则保留以下内容:
>>> img.transpose(2, 0, 1)[:, 0, 0]
array([0, 1, 2])
如果你使用整形,你的图像会被打乱:
>>> img.reshape(3, 224, 224)[:, 0, 0]
array([0, 16, 32])