我的AI之路(43)--使用百度pyramidbox口罩识别模型

       疫情特殊时期百度大厂展现社会责任感,组织团队加班加点基于他们自己的人脸识别模型pyramidbox弄出了准确率比较高的口罩识别模型,安装paddlepaddle和paddlehub后就可把模型下载到本地免费使用,模型有server版还有mobile版,并且提供了python调用示例代码,这个很赞。

       据说腾讯优图也弄出了识别口罩佩戴准确率99%的模型,正在准备上线到云服务,期待两家的都试用一下PK一下看哪家更牛用哪个,有免费瓜吃我们吃瓜群众当然乐于等着试吃...

      百度的口罩识别模型上周公开,因项目急需,我本周一开始安装部署试用,第一版模型试用对正面识别比较准,侧脸就基本全错,百度的团队也在赶工提升模型和paddlehub,周四更新到第二版,测试发现侧脸识别基本可以了,进展也挺神速的,赞啊,不过试用过程中遇到了若干问题,提交给了百度的大牛,迅速做了解决和更新,现在支持GPU的版本基本上可用了,用于演示已经应该差不多了,只是性能还有待提升点,目前在我们的服务器上使用GPU版,识别一张1M多的图需要1.5-2秒,按理说虽然RTX2080TI GPU比不上Telsa v100那样的,但算力也算不错了,性能这点感觉百度模型或者paddlehub封装程序还有待提升的地方,大厂的团队后面能持续改进一下就很赞了。不过话说回来,免费的瓜还有啥好计较的,看跟我对接的老师/大牛也是在线工作到很晚还在回答我提交的问题,改正hub错误的地方发改好的版本给我试用,技术人尤其热爱技术的人都不容易啊,就算公司没要求加晚班自己也会手痒根本停不下来,哈哈...

     记录一下怎么安装百度的paddlepaddle和paddlehub以及口罩识别模型:

    百度的paddlepaddle官网https://www.paddlepaddle.org.cn/上面提供了类似pytorch那样的安装环境配置选择的界面,很方便,根据你需要安装的环境选择OS、Python版本、CUDA版本以及安装方式(pip、conda、docker、build from source),选好后下面会出现对应的一条或多条命令,拷贝这些命令依次执行就行了。

      安装方式我现在每次都毫不犹豫的选择docker,为么? 对于安装环境所在的机器上,如果只打算安装部署一种模型或框架,那么安装python后使用pip安装到默认路径下就行了,如果打算使用多个不同框架(tensorflow/pytorch/caffe/paddlepaddle...,到目前为止我只用过这四种,其他的微软和亚马逊的没用过,但看过一点示例代码感觉搞法都相似差不多)以及多种不同模型的训练环境,个人机器上用用,可以考虑使用conda建立隔离环境,分开安装也基本上能对付了,但是对于公司的企业级部署环境,conda显然不能满足要求,为么呢?conda不支持拷贝发布,换台机器都得安装一遍,你说烦不烦 时间和人力成本高不高,企业级部署当然最好使用docker了,现在的主流深度学习框架都有对应的docker文件不断的更新,拉取对应的版本的image后,创建个实例跑起来,里面框架和相关的必要支持包都给你安装好了,省了大把的安装和解决安装遇到问题的时间,在docker实例上把模型训练或者运行的环境安装好后commit出一个新的image后,就可以在很快在其他安装了docker服务的机器上跑起来,其他什么都不用安装了,这节省了大把时间。同时,同一台服务器上,不同的框架/模型跑在不同的docker实例里,互不干涉,没有支持包版本不兼容冲突之类头疼的问题(有过在同一环境下安装过多个模型环境经历的 一定会对numpy版本不兼容之类引起的错误深恶痛绝 ^_^ ),多好。

      

     根据我的环境选择Ubuntu、docker、Python3、CUDA10后拷贝下面的命令到服务器上执行:

         nvidia-docker pull hub.baidubce.com/paddlepaddle/paddle:1.6.3-gpu-cuda10.0-cudnn7

     等下载完毕后,执行docker images,可以看到大小有12.3G的image:

         hub.baidubce.com/paddlepaddle/paddle   1.6.3-gpu-cuda10.0-cudnn7       e3895a23df3d

     然后执行下面的命令创建和运行实例(映射的端口8866是为模型以server方式部署时准备的):

        nvidia-docker run --name paddle -it -v /home/arnold/AI/pphub:/paddle -p 8866:8866  hub.baidubce.com/paddlepaddle/paddle:1.6.3-gpu-cuda10.0-cudnn7 /bin/bash

      实例启动后进入python3.5,并验证paddlepaddle可运行:
         import paddle.fluid
         paddle.fluid.install_check.run_check()

      提示你安装成功或者提示只能用单机版:Your Paddle Fluid is installed successfully ONLY for SINGLE GPU or CPU! 中间报错一大堆说什么NCCL没安装之类的可以不理 ,就可以用了,如果你不需要使用多GPU做分布式训练的话。

     如果要安装NCCL的话,执行下面的命令安装2.4.8-1版nccl,不要安装最新的2.5.6-1版,因为paddlepaddle docker里安装的就是2.4.8-1,看来这个版本是没有兼容性问题的,盲目安装高了就出现NCCL没安装之类的这样那样的报错:

            sudo apt install libnccl2=2.4.8-1+cuda10.0 libnccl-dev=2.4.8-1+cuda10.0

     下面安装调用口罩识别模型所需的paddlehub,先更新一下pip和setuptools,否则安装过程中可能会报错:

            pip3 install --upgrade pip 
            pip3 install --upgrade setuptools

            pip3 install   paddlehub

       安装完了paddlehub,再安装一下 vim(必须品)和git(可选,下载源码才需要)之类的工具:

            apt-get install vim

       paddlepaddle和paddlehub都安装好了,那么怎么下载模型呢?下载模型隐藏在代码里!不能单独执行命令下载。

     

       模型可以部署到本地使用代码直接调用,也可以使用paddlehub部署成http server 模式供客户端远程访问,客户端代码使用http post调用,要识别的图片在post中上传。

下面写调用测试代码(这些代码参考百度官网,根据自己情况改写一下就行了),下面是本地直接调用模型识别图片的代码:

         import paddlehub as hub
         import paddle.fluid

         import cv2
         import os

        os.environ["CUDA_VISIBLE_DEVICES"]="0"   # 推理时想要用到GPU的话一定要有这句话,不然只是要CPU,我觉得这里有点怪,自己去找0号GPU不就行了,猜测可能是CUDA没有提供判断GPU是否被占用的接口?所以paddle只能要求这么干了

       #下载(已下载则略过)模型并创建实例,模型文件被下载存放到/root/.paddlehub/modules/下,pyramidbox_lite_mobile_mask用于嵌入式环境,pyramidbox_lite_server_mask用于PC环境,但实际上两个模型都可以在PC上跑:

     #hub install pyramidbox_lite_server_mask==1.2.0

     hub install pyramidbox_lite_mobile_mask==1.2.0

       module = hub.Module(name="pyramidbox_lite_mobile_mask",version='1.2.0')  
       #module = hub.Module(name="pyramidbox_lite_server_mask", version='1.2.0')

       img_path="/paddle/drdkz/dr-2.jpg"

       img=[img_path]
       input_dict = {"image": img}
       results = module.face_detection(data=input_dict,use_multi_scale=True, shrink=0.6,use_gpu=True,use_cuda=True)  #使用GPU时需要加这些红色参数

       for result in results:
           print(result)  

      或者:

      img_path=["/paddle/drdkz/dr-2.jpg"]

      img_data = [cv2.imread(img) for img in img_path]

      results=module.face_detection(data={"data":img_data},use_gpu=True,use_cuda=True) #使用GPU时需要加这些红色参数

      for result in results:
           print(result) 

     本地直接调用模型需要自己根据结果数据把在图中把标注框画出来:

      img = cv2.imread(img_path)
      for result in results:
          print(result)
          data =result['data']
          x_min=int(data['left'])
          y_min=int(data['top'])
          x_max=int(data['right'])
          y_max=int(data['bottom'])
          #print(x_min,y_min,x_max,y_max)
          text=data['label']+" "+ str(round(float(data['confidence']),2))
          cv2.rectangle(img,(x_min,y_min),(x_max,y_max),(0,255,0),3)
          cv2.putText(img, text,(x_min,y_min),cv2.FONT_HERSHEY_COMPLEX,0.6,(0,0,255),1)
          path,file = os.path.split(img_path)
          img_out =  path + os.path.sep + "/checked/"+file
          cv2.imwrite(img_out,img)

   对于使用paddlehub把模型部署到sever端供远程使用http post调用,非常简单,服务端执行(使用GPU需要加上红色部分):

         export CUDA_VISIBLE_DEVICES=0

         hub serving start -m pyramidbox_lite_server_mask -p 8866 --use_gpu --use_singleprocess 

   服务启动后在8866监听(前面在启动docker时对此端口对外做了映射以边docker容器外部访问),然后客户端调用测试代码使用:

       import requests
       import json
       import base64
       import os


      file_list = ["drdkz/dr-1.jpg"]
      files = [("image", (open(item, "rb"))) for item in file_list]
      url = "http://127.0.0.1:8866/predict/image/pyramidbox_lite_server_mask"
      r = requests.post(url=url, files=files)  #如果不需要response中包含识别结果图片的base64数据和文件的path,则

                                                                 #加上参数 data={"visual_result": "False"},默认包含
      results = eval(r.json()["results"]
      print(results)
      if not os.path.exists("output"):
         os.mkdir("output")
     for item in results:
         with open(os.path.join("output", item["path"]), "wb") as fp:
             fp.write(base64.b64decode(item["base64"].split(',')[-1]))
             item.pop("base64")
     print(json.dumps(results, indent=4, ensure_ascii=False))
   

注意这里要识别的文件是以二进制方式上传的,使用其他语言编写时以form的upload方式上传文件即可:

发布了61 篇原创文章 · 获赞 90 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/XCCCCZ/article/details/104446803