Tutorial_Python.md 3.23 KB
Newer Older
yangql's avatar
yangql committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# 分类器

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



## 模型简介

本示例使用了经典的ResNet50模型,onnx文件在Resource/Models/文件夹下,模型结构可以通过netron (https://netron.app/) 查看,该模型的输入shape为[1,3,224,224] ,数据排布为NCHW。



## 预处理

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

- 图像格式转换,将BGR转换为RGB
- 调整图像大小,使短边为 256,长边等比例缩放
- 裁剪图像,在中心窗口位置裁剪出224x224大小的图像
- normalize操作,对图像减均值再除方差
- 调整输入数据的尺寸为(1, 3, 224, 224)

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

```
def Preprocessing(pathOfImage):
    
    image = cv2.imread(pathOfImage, cv2.IMREAD_COLOR)    
    
    # 转换为RGB格式
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    
    # 调整大小,保持长宽比
    ratio = float(256) / min(image.shape[0], image.shape[1])
    if image.shape[0] > image.shape[1]:
        new_size = [int(round(ratio * image.shape[0])), 256]
    else:
        new_size = [256, int(round(ratio * image.shape[1]))]
    image = np.array(cv2.resize(image, (new_size[1],new_size[0])))    # w h 格式
    
    # 裁剪中心窗口
    h, w, c = image.shape
    start_x = w//2 - 224//2
    start_y = h//2 - 224//2
    image = image[start_y:start_y+224, start_x:start_x+224, :]
    
    # transpose
    image = image.transpose(2, 0, 1)
    
    # 将输入数据转换为float32
    img_data = image.astype('float32')
    
    # normalize
    mean_vec = np.array([123.675, 116.28, 103.53])
    stddev_vec = np.array([58.395, 57.12, 57.375])
    norm_img_data = np.zeros(img_data.shape).astype('float32')
    for i in range(img_data.shape[0]):
        norm_img_data[i,:,:] = (img_data[i,:,:] - mean_vec[i]) / stddev_vec[i]
    
    # 调整输入数据的尺寸
    norm_img_data = norm_img_data.reshape(1, 3, 224, 224).astype('float32')
    return norm_img_data
```



## 推理

完成预处理后,就可以执行推理了:

```
def ort_seg_dcu(model_path,image):
    
    #创建sess_options
    sess_options = ort.SessionOptions()

    #设置图优化
    sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_BASIC

    #是否开启profiling
    sess_options.enable_profiling = False
    dcu_session = ort.InferenceSession(model_path,sess_options,providers=['ROCMExecutionProvider'],)
    input_name=dcu_session.get_inputs()[0].name

    results = dcu_session.run(None, input_feed={input_name:image })
    scores=np.array(results[0])
    # print("ort result.shape:",scores.shape)

    return scores
```

- Preprocessing()函数返回输入数据(numpy类型),然后通过构造一个字典输入模型执行推理,如果模型有多个输入,则在字典中需要添加多个输入数据。
- model.run()返回模型的推理结果,返回结果是一个list类型,results[0]表示第一个输出节点的输出。由于示例模型只有一个输出节点,所以results[0]对应resnetv24_dense0_fwd节点。最后,通过np.array(result)获取分类结果。