卷起来の极市平台使用经验&高通AI大赛部分踩坑

去年疫情居家没啥事干,碰巧发现极市的比赛,统一算力并且数据不可见,倒是很适合我这种没有机器的,于是参加了一下。平台的使用困难给限制了一部分萌新,部分有算力的大佬也转身去了更大的平台,最后给本咸鱼混了个小奖品。为了让这次比赛更加卷(滑稽),在此分享一下在极市平台的使用经验以及本次比赛中的部分踩坑。

链接:https://challenge.cvmart.net/race

  • 平台环境
  • 训练
  • 标准测试
  • SDK测试
  • 手绘图像识别

1.平台环境


  • 系统环境

平台提供了TensorFlow、Torch、Caffe和ONNX的环境,这里其实就需要注意一下版本信息了,本人主要使用的是PyTorch,这里PyTorch是1.5版本,并且PyThon是3.6版本,后面安装其他库需要注意对应上。

卷起来の极市平台使用经验&高通AI大赛部分踩坑_第1张图片

  • 编码环境

卷起来の极市平台使用经验&高通AI大赛部分踩坑_第2张图片

进入在线编码就能看见编码调试IDE,主要就是VScodeJupyterLab,这里不推荐VScode,因为很多时候都连不上,并且功能没有JupyterLab丰富,所以就开启后者。

卷起来の极市平台使用经验&高通AI大赛部分踩坑_第3张图片

进入之后两个文件夹ev_sdktrain,分别存放的是用于测试和训练的代码,他们分别对应了系统上的两个Git仓库,路径如下

/usr/local/ev_sdk
/project/train/src_repo

右边启动页就有很多可以用的功能,但是主要还是Teminal终端最好用,特别是熟悉Linux环境的可以直接进行调试,另一个就是Notebook,跟Python的Jupyter-Notebook是一样的,做数据分析之类的很方便。左上角的加号可以增加启动页。

然后通过Terminal,跳转系统路径和查看系统环境(显卡不错,挖矿一定很快吧bushi)

卷起来の极市平台使用经验&高通AI大赛部分踩坑_第4张图片

需要注意的是,系统的Python版本和pip版本似乎是不匹配的,因此通常的pip install可能并没有安装库到需要的环境中,建议用python3.6 -m pip install xxx

2.训练


训练这里没有多少问题,初始环境已经包含了DockerFilerequirements.txt,前者不需要修改,后者里面添加需要的库名字,如果在训练时遇到缺少库,就在这里添加。需要注意的是环境中torch是1.5.1版本,因此torchvision需要指定版本号为0.6.1。

其他还有几个需要注意的地方:

  • 数据路径:/home/data/*,不同题目最后那个路径是不一样的,需要通过终端去查看

  • 存储路径:/project/train/models/*,模型存储需要在这个路径下创建子目录进行存储

  • Log:/project/train/log/log.txt (暂时没有用到) 存log,训练完之后看很方便,自己写到txt里面,想怎么存就怎么存qwq

  • Print:通常会print一些log出来查看,但是这次不知道为啥没有显示,而且很乱,换成logging能全打出来,但是还是很乱就是了。

    import logging
    # 切换到Debug模式,不然也不会打印info
    logging.basicConfig(level=logging.DEBUG)
    # print的部分换成info
    logging.info("")
    

然后把自己的祖传代码COPY过来就可以了。

训练的时候要用命令,最好把要做的操作写到shell里面,然后直接run,我的run.sh仅供参考

cd /project/train/src_repo/
python3.6 datasplit.py
python3.6 train.py

最后git三连送到服务器训练,输入命令

bash /project/train/src_repo/run.sh

卷起来の极市平台使用经验&高通AI大赛部分踩坑_第5张图片

训练完的模型就在模型列表可以查看。

3.标准测试


标准测试,就是本次的accuracy分数所需要的测试,这次没有以这个来算性能分倒是减少了C++的要求。直接用Python测试,需要修改2个部分

  • ji.py:估计大多数新用这个平台的都不知道咋整,直接在ev_sdk文件夹中的src文件夹下创建ji.py,然后写根据逻辑写就行了,相关的模型和代码也可以写到文件里,或者相同目录下。大致上,测试时平台会自动import这个文件,调用init获取模型,再调用process_image获取结果。以下代码仅供参考。
import cv2
import json
import numpy as np
import torch
from torchvision import transforms, models
# 自己的模型
from model import BaseModel

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def init():
    # 测试时选择的文件名
    pth = '/usr/local/ev_sdk/model/best.pth'
    model = BaseModel()
    model.load_state_dict(torch.load(pth))
    model.to(device)
    model.eval()
    
    return model

# 根据训练的标签设置
class_dict = {}

def process_image(net, input_image, args=None):
    # 输入图像是opencv读取的bgr格式
    # bgr to rgb
    img = input_image[..., ::-1]
    """
    其他预处理
    """
    # h, w, c to c, h, w
    img = np.transpose(2, 1, 0)
    img = torch.from_numpy(img)
    img = img.unsqueeze(0)
    img = img.to(device)
    
    out = net(img)
    _, pred = torch.max(out, 1)
    
    return json.dumps(
        {'class': class_dict[pred[0].item()]}
    )


if __name__ == '__main__':
    net = init()
    x = torch.randn((224, 224, 3)).numpy()
    print(process_image(net, x))
  • DockerFile:需要增加ENV AUTO_TEST_USE_JI_PYTHON_API=1

完成这两步再git三连基本就可以测试了,其他文件不需要动。但是本次比赛还得先搞个量化才能进行这一步,所以还要继续。

4.SDK测试


这一步是最磨人的,本人也仅仅完成了一部分,最终能够测试成功。以PyTorch为例

  • 转换onnx:PyTorch虽然好用,但是部署的时候是需要静态图的,所以要转换,通常是转成onnx,这块资料还挺多的,就不用贴代码了。需要注意的就是PyTorch模型,在forward里面常常会用x.view()来拉直gap后的特征,转换前需要在模型里把这一步换成torch.flatten()或者nn.Flatten()

  • 转换dlc:文档里面提供了代码,首先要激活snpe环境,然后转换。有时候会遇到缺少库的情况,需要在激活环境后install。

source /opt/snpe/snpe_venv/bin/activate
###
pip install xxx
###
snpe-onnx-to-dlc --input_network /usr/local/ev_sdk/model/model.onnx --output_path /usr/local/ev_sdk/model/model.dlc

完成转换生成dlc之后基本就可以使用标准测试,得到accuracy值了,但是仍然会显示测试失败,因为还没有量化,骁龙888调用失败(安卓机皇警告)。

  • 量化:大多数的坑都是在量化这一步了,参考量化命令
snpe-dlc-quantize --input_dlc /usr/local/ev_sdk/model/model.dlc --output_dlc /usr/local/ev_sdk/model/model_quantized.dlc --input_list /usr/local/ev_sdk/file_list.txt
  • file_list.txt官方文档都不说清楚这文件哪来的,查了snpe文档好久才发现系统自带了一个转换文件(*@!!&#……&@),在/opt/snpe/models路径下,有snpe官方的一些样例,比如inception_v3/scripts下,包含了创建raw文件的代码,创建file_list的代码等,从这边copy一个然后修改一下图像尺寸和维度就可以了。通常只需要十几个raw文件就可以了,因此就对某一个子文件夹转换,然后把转换后的文件路径打包到file_list里面即可。
python /usr/local/ev_sdk/create_onnx_raw.py -i /home/data/7/car -d /home/data/raw
  • enable_htp:官方文档是有这一个参数的,但是我一直报错,最后去掉了这个参数就测试成功了,很无语,不过从测试详情看还是用的GPU,估计是没量化成功,有空再研究研究。(有大佬搞出来记得带带我)
  • 其他:
    • 转换dlc指定维度时可能会报google什么错,需要升级protobuf,pip install protobuf --upgrade
    • 以上所有命令的文件都建议用绝对路径
    • 文档建议查看SNPE的官方文档,虽然是英文的,但是多数问题都能解决

以上的操作都需要写入model文件夹中的convert_model.sh,我自己的sh仅供参考。如果能够在本地调用这个shell文件生成dlc,基本就没有问题了。
卷起来の极市平台使用经验&高通AI大赛部分踩坑_第6张图片

5.手绘图像识别


环境通了开始搞题目,目前主要就搞了手绘图像识别,一点点结果分享。

主干模型用的torchvision自带的Resnet18预训练模型,数据增强用了随机水平、垂直翻转,随机角度变换,随机裁剪等等,测试用的中心裁剪,图像尺寸是224x224,算是分类任务最常规的设置。

训练30轮,测试准确率0.34(当场自闭)

然后考虑了一下数据情况,减小了图像尺寸,换成了112x112,涨到了0.65(笑)

去掉了随机旋转,又涨了0.03
去掉垂直翻转和角度变换,涨了0.1(可怕)

… …

以上结果仅供参考,手绘图像也是第一次接触,做好EDA还是很有必要的,不知道怎么做数据增强,再去翻翻论文_(:з」∠)_。想要更好的结果,换换大模型?继续调参吧0-0

最后,数据分布看看吧,还挺平衡的。
卷起来の极市平台使用经验&高通AI大赛部分踩坑_第7张图片


暂时就想到这么多,有问题可以留言,我也不一定知道_(:з」∠)_
代码与部分方案:https://github.com/Kurumi233/GaoTong2021-Baseline

参考:

[1] 极市开发者平台-文档中心. https://challenge.cvmart.net/document
[2] SPNE模型转换. https://blog.csdn.net/weixin_38498942/article/details/105819685
[3] SNPE SDK工具介绍. https://blog.csdn.net/weixin_38498942/article/details/105959493
[4] SNPE SDK. https://developer.qualcomm.com/docs/snpe/tools.html#tools_snpe-dlc-quantize
[5] SNPE inception-v3. https://developer.qualcomm.com/docs/snpe/tutorial_inceptionv3.html
[6] SNPE VGG-onnx. https://developer.qualcomm.com/docs/snpe/tutorial_onnx.html
[7] SNPE 量化. https://developer.qualcomm.com/docs/snpe/model_conversion.html

你可能感兴趣的:(比赛,CV,caffe,深度学习,pytorch)