# 分类器

本示例通过ResNet50模型说明如何使用MIGraphX Python API进行分类模型的推理，包括预处理、推理并获取推理结果。



## 模型简介

本示例使用了经典的ResNet50模型，onnx文件在/Resource/Models/Classifier文件夹下，模型结构可以通过netron (https://netron.app/) 查看，该模型的输入shape为[1,3,224,224] ，数据排布为NCHW，输出是1000个类别的概率（未归一化）。

​																														

## 预处理

在将数据输入到模型之前，需要对图像做如下预处理操作：

- 转换数据排布为NCHW
- 将像素值归一化到[0.0, 1.0]
- 调整输入数据的尺寸为（1, 3, 224, 224）

本示例代码采用了OpenCV实现了预处理操作：

```
def Preprocessing(pathOfImage):
    image = cv2.imread(pathOfImage,cv2.IMREAD_COLOR)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    # 调整图像的尺寸
    image = cv2.resize(image, (224,224))
    # 维度转换HWC->CHW
    image = image.transpose(2, 0, 1)
    # 维度拓展，增加batch维度
    image = np.expand_dims(image, 0)
    image = np.ascontiguousarray(image)
    image = image.astype(np.float32)
    # 归一化
    input = image / 255
    return input
```



## 推理

完成预处理后，就可以执行推理了：

```
if __name__ == '__main__':
    ...
    
    # 预处理
    pathOfImage ="../Resource/Images/mnist_9.jpg"
    image = Preprocessing(pathOfImage)

    # 推理
    results = model.run({inputName: migraphx.argument(image)}) # 推理结果，list类型

    # 获取输出节点属性
    result=results[0]                      # 获取第一个输出节点的数据,migraphx.argument类型
    outputShape=result.get_shape()         # 输出节点的shape,migraphx.shape类型
    outputSize=outputShape.lens()          # 每一维大小，维度顺序为(N,C,H,W),list类型
    numberOfOutput=outputShape.elements()  # 输出节点元素的个数

    # 获取分类结果
    result=results[0].tolist()             # 将migraphx.argument转换为list
    result=np.array(result)

    # 打印1000个类别的输出值
    print(result)
```

- Preprocessing()函数返回输入数据（numpy类型），然后通过{inputName: migraphx.argument(image)}构造一个字典输入模型执行推理，如果模型有多个输入，则在字典中需要添加多个输入数据。
- model.run()返回模型的推理结果，返回结果是一个list类型，results[0]表示第一个输出节点的输出，是一个migraphx.argument类型，由于示例模型只有一个输出节点，所以results[0]对应resnetv24_dense0_fwd节点，如果想将migraphx.argument类型转换为list类型，可以通过tolist()方法实现。最后，打印出1000个类别的输出值。
