本节课主要对于大白AI课程:https://mp.weixin.qq.com/s/STbdSoI7xLeHrNyLlw9GOg
《Pytorch模型推理及多任务通用范式》课程中的第四节课进行学习。
包含以下必做题和思考题
1.1 对 “./images/car.jpg” 做语义分割,提取出里面的车辆,模仿上课时,对“可视化推理结果” 和“BGRA 四通道图” 进行保存。
1.2 自己找 2 张其他图,对图中某个类别进行分割,并保存“BGRA 四通道图” 。
2.1 用 time 模块和 for 循环,对”./images/car.jpg” 连续推理 100 次,统计时间开销。有 CUDA 的同学,改下代码: self.device=torch.device(‘cuda’),统计时间开销。
2.2 以 0.5 为阈值,计算”./images/car.jpg” 图中车辆的面积(单位:像素)。
修改文件名为"./images/car.jpg" ,并修改person_id=7,对应的为car的类别,推理结果如下:
我使用上节课的猫和狗的图片做为推理输入,图片如下:
分别修改文件名为"./images/cat.jpg" 、"./images/dog.jpg" ,并修改person_id=8、12,对应的为cat和dog的类别,推理结果如下:
2)BGRA 四通道图:
和上节课的思考题内容一致,不再做细致的讨论,修改__main__代码如下:
if __name__ == '__main__':
import time
print("Starting")
# 实例化
print("Loading Weight...")
t_all_LW = 0
t_start = time.time()
model_segment = ModelPipline(person_id=7)
t_end = time.time()
t_all_LW += t_end - t_start
print("Loading Weight Time:{}".format(t_all_LW))
# 第一次推理时间
image = cv2.imread('./images/car.jpg')
print("First Predicting...")
t_all_FP = 0
t_start = time.time()
result = model_segment.predict(image)
t_end = time.time()
t_all_FP += t_end - t_start
print("First Predicting Time:{}".format(t_all_FP))
# 一百次推理时间
print("100 Predicting...")
t_all = 0
for i in range(100):
t_start = time.time()
result = model_segment.predict(image)
t_end = time.time()
t_all += t_end - t_start
print("100 Predicting Time:{}".format(t_all))
首先测试cpu推理速度,单次推理时间3.2s,100次推理时间接近6分钟,好的让我们先泡杯茶,刷会b站。
cpu推理结果:
Starting
Loading Weight…
Loading Weight Time:0.4857034683227539
First Predicting…
First Predicting Time:3.2739310264587402
100 Predicting…
100 Predicting Time:351.99774956703186
Ending
接着我们来测试gpu的推理速度,修改self.device = torch.device(‘cuda’),开始测试。
gpu推理结果:
Starting
Loading Weight…
Loading Weight Time:2.228027105331421
First Predicting…
First Predicting Time:0.9911150932312012
100 Predicting…
100 Predicting Time:26.768312215805054
Ending
结论:
我们可以很清楚的看到gpu的推理速度,虽然在模型加载过程中,gpu的速度较慢,但在第一次推理中,gpu快了三倍左右,在100次推理过程中,gpu快了10倍不止。gpu的并行计算效率要远远高于cpu,在模型较大或是输入数据量大的情况下,gpu的性能要远大于cpu的性能。
PS:
推理过程中,可以打开任务管理器,可以看到的gpu是否正在运行:
在可视化输出的代码段中加入计算面积的代码:
# 可视化结果
cv2.imwrite('./demos/car_1_mask.jpg', (result * 255).astype(np.uint8))
mask = result.copy()
mask[mask >= 0.5] = 255
mask[mask < 0.5] = 0
# 计算面积
# add in here
image_mask = np.concatenate([image, mask[:, :, np.newaxis]], axis=2)
cv2.imwrite('./demos/car_1_mask.png', image_mask)
这里我写了两种方法来计算面积。
1)第一种方法,暴力循环计算像素点的个数:
# 方法1:暴力计算
area= 0
high, width = mask.shape
for i in range(high):
for j in range(width):
if mask[i][j] == 255:
area += 1
print("图中分割的目标面积为: {}(pix)".format(area))
输出结果:
图中分割的目标面积为: 102781(pix)
2)第二种方法,利用numpy数组的特性来直接计算面积,代码比较简洁:
# 方法2:利用numpy数组的性质
area = len(mask[mask == 255])
print("图中分割的目标面积为: {}(pix)".format(area))
输出结果相同:
图中分割的目标面积为: 102781(pix)
在理解了上节课的内容后,在看本节课的内容,除了关于分割算法的部分属于新知识外,其它是对上节课的学习的巩固,另外思考题中的计算面积,也是复习了自己对numpy数组特性的知识。这样一个循环递进的过程,进一步加深自己对Pytorch模型推理的认识与理解,我相信在之后的工作中,一定会用到课程中学习到的东西,学以致用。