• 【深度学习】树莓派Zero w深度学习模型Python推理


    机器学习开发过程中,当模型训练好后,接下来就要进行模型推理了,根据部署环境可分为三类场景:

    边缘计算:一般指手机,嵌入式设备,直接在数据生成的设备上进行推理,因为能避免将采集到的数据上传到云端,所以实时性非常好。

    端计算:介于云和边缘设备之间的计算平台,个人PC可以归为这一类。

    云计算:指云计算平台,具有强大的计算和存储能力,通过服务释放AI能力。

    在之前跟大家分享的AI工具中,都是在PC上进行推理,也就是属于端设备推理。

    基于深度学习的抠图工具
    https://github.com/AIDajiangtang
    基于深度学习的图像拼接工具
    https://github.com/AIDajiangtang/Superpoint-LightGlue-Image-Stiching
    基于大模型的分割工具
    https://github.com/AIDajiangtang/Segment-Anything-CPP
    https://github.com/AIDajiangtang/Segment-Anything-CSharp
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    今天,我将为大家演示如何在边缘设备上进行推理。

    要准备毕业设计的小伙伴可以作为参考。

    我选择的边缘设备是树莓派的Zero w开发板,硬件配置参数如下:

    1GHz single-core CPU ARM11 ARMv6
    
    512MB RAM
    
    Mini HDMI® port
    
    Micro USB OTG port
    
    Micro USB power
    
    HAT-compatible 40-pin header
    
    Composite video and reset headers
    
    CSI camera connector (v1.3 only)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这里多说一点,对于ARM芯片,要区分芯片系列与CPU架构。不同的CPU架构对应不同的指令集,如果涉及从源码编译需要考虑CPU架构。

    ARM7:
    时间点:ARM7系列处理器于1994年发布。
    特点:ARM7系列处理器是ARM架构的早期版本,采用32位RISC架构,主要用于嵌入式系统和低功耗设备。它具有较低的功耗和成本,适用于资源受限的应用。
    CPU架构:ARMv4T架构。
    
    ARM9:
    时间点:ARM9系列处理器于1997年发布。
    特点:ARM9系列处理器也是基于32位RISC架构,用于多种应用,包括嵌入式系统、移动设备和数字音频。它具有较高的性能和灵活性,适用于中等功耗和性能需求的应用。
    CPU架构:ARMv5TE架构。
    
    
    ARM11:
    时间点:ARM11系列处理器于2002年发布。
    特点:ARM11系列处理器同样采用32位RISC架构,主要应用于移动设备和数字媒体领域。它具有更高的性能和计算能力,支持多媒体处理和浮点运算。
    CPU架构:ARMv6架构。
    
    ARM Cortex-A:
    时间点:ARM Cortex-A系列处理器于2005年发布。
    特点:Cortex-A系列面向高性能应用,用于智能手机、平板电脑、服务器和其他需要较高处理性能的设备。它具有更强大的处理能力、更高的频率和更复杂的功能。
    CPU架构:基于ARMv7-A或ARMv8-A架构。
    
    ARM Cortex-R:
    时间点:ARM Cortex-R系列处理器于2004年发布。
    特点:Cortex-R系列面向实时应用,用于嵌入式系统、汽车电子、工业控制等需要快速响应和可靠性的应用。它具有较低的延迟和更可靠的实时性能。
    CPU架构:基于ARMv7-R或ARMv8-R架构。
    
    ARM Cortex-M:
    时间点:ARM Cortex-M系列处理器于2004年发布。
    特点:Cortex-M系列面向低功耗嵌入式系统,用于微控制器、传感器、物联网设备等资源受限的应用。它具有较低的功耗、小尺寸和高效的实时性能。
    CPU架构:基于ARMv6-M或ARMv7-M架构。
    
    • 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

    常见ARM芯片系列和架构

    我们选择的Raspberry Zero w属于ARM11系列,ARMv6 CPU架构,支持wifi。

    Raspberry Pi 1 Model A/B/A+/B+:
    CPU系列:ARM11系列
    CPU架构:ARMv6架构
    
    Raspberry Pi 2 Model B:
    CPU系列:ARM Cortex-A系列
    CPU架构:ARMv7-A架构
    
    Raspberry Pi 3 Model B/B+:
    CPU系列:ARM Cortex-A系列
    CPU架构:ARMv8-A架构
    
    Raspberry Pi 4 Model B:
    CPU系列:ARM Cortex-A系列
    CPU架构:ARMv8-A架构
    
    Raspberry Pi Zero/Zero W:
    CPU系列:ARM11系列
    CPU架构:ARMv6架构
    
    Raspberry Pi Compute Module 3/3+:
    CPU系列:ARM Cortex-A系列
    CPU架构:ARMv8-A架构
    
    Raspberry Pi Compute Module 4:
    CPU系列:ARM Cortex-A系列
    CPU架构:ARMv8-A架构
    
    • 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

    常见树莓派开发板CPU型号

    由于本项目涉及到的软件比较多,我帮大家整理到一起了。

    关注微信公众号:人工智能大讲堂,后台回复【rsb】获取模型和所有安装包。

    开始吧。

    准备硬件

    除了开发板外,还需要USB电源,摄像头,miscro SD卡,以及读卡器。某宝上可以买到,然后按下图连接

    在这里插入图片描述

    准备推理框架

    按理讲,硬件就绪后,接下来应该安装操作系统了,为什么要先说推理框架呢?也是出于无奈啊!

    我选择的推理框架是tensorflow lite,但它对于ARMv6没有现成的pip安装包,也就是没办法通过下面的命令安装推理运行时。

    python3 -m pip install tflite-runtime
    
    • 1

    有两种解决方法。

    第一种是安装好树莓派操作系统后自己准备编译环境,然后从源码编译tensorflow lite whl安装包。

    https://www.tensorflow.org/lite/guide/build_cmake_pip
    
    • 1

    第二种则是去网上找现成的针对ARM v6架构的安装包。

    我选择了第二种。

    开源的力量是强大的,我在Github上真就找到了一个针对ARM v6架构的whl安装包,虽然是完整的tensorflow安装包,但可以通过导出tensorflow lite来使用推理功能。

    import tensorflow as tf
    interpreter = tf.lite.Interpreter(model_path=args.model_file)
    
    • 1
    • 2

    安装包下载连接

    https://github.com/lhelontra/tensorflow-on-arm/releases/download/v2.4.0/tensorflow-2.4.0-cp37-none-linux_armv6l.whl
    
    • 1

    这里需要注意,该pip安装包是在python3.7环境下编译的,所以树莓派开发板也要安装自带python3.7的操作系统,这也是为什么先确定推理框架的原因。

    准备操作系统

    接下来就要找自带python3.7的树莓派操作系统。

    除了python3.7外,另一个需要考虑的因素是内存,我们本次选择的Raspberry Zero w内存只有500M,为了运行效率,选择操作系统时建议选择不带桌面的Lite版本。

    对于内存比较大的开发板,则可以选择带桌面的操作系统,甚至可以选择带预装各种软件环境的操作系统。

    图片

    幸好,我在Archive找到python3.7的操作系统。

    操作系统下载链接

    https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-05-28/
    
    • 1

    下载后保存到另一台电脑硬盘中等待使用。

    接下来要通过树莓派自带的工具Raspberry pi Imager将操作系统烧录到miscro sd卡中。

    将sd卡放入读卡器,插到另一台电脑USB接口上。

    https://www.raspberrypi.com/software/
    
    • 1

    图片

    启动刻录软件

    图片

    1.选择操作系统->使用自定义镜像

    图片

    2.选择SD卡

    3.设置

    3.1勾选设置主机名,输入主机名

    3.2勾选开启SSH服务,选择使用密码登录

    图片

    3.3勾选设置操作系统用户名和密码,输入用户名和密码

    3.4勾选配置WIFI,设置热点名和登录密码(可以用手机热点)

    图片

    4.烧录

    烧录成功后,将miscro sd卡插到树莓派sd卡插槽上,连接电源就可以开机了。

    远程连接树莓派

    由于没有桌面环境,所以需要另一台电脑远程连接到树莓派上,此时Raspberry Zero w支持wifi就起到作用了,安装操作系统时我们会配置网络,树莓派启动后主动连接热点,另一台电脑也连接到同一个热点,就可以远程了。

    通过手机热点查看树莓派IP地址。

    另一台电脑连接同一个手机热点。

    启动另一台电脑的Windows PowerShell。

    输入ssh 树莓派用户名@树莓派IP

    例如 ssh rsb@192.168.133.223,根据提示需要输入密码。
    
    • 1

    光有远程还不够,还需要能够在两个系统之间传输文件,推荐在另一台电脑中安装WinSCP。

    启动WinSCP,输入树莓派主机名,用户名和密码。

    图片

    安装软件

    安装tensorflow

    wget https://github.com/lhelontra/tensorflow-on-arm/releases/download/v2.2.0/tensorflow-2.2.0-cp37-none-linux_armv6l.whl
    
    • 1
    sudo pip3 install tensorflow-2.2.0-cp37-none-linux_armv6l.whl
    
    • 1

    安装完成后通过下面命令查看是否安装成功

    python -c "import tensorflow as tf;print(tf.reduce_sum(tf.random.normal([100, 100])))"
    
    • 1

    如果报类似下面这样的错误

    TypeError: Descriptors cannot not be created directly.
    可以尝试通过下面命令解决

    Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
    
    • 1

    安装OpenCV

    sudo apt-get -y install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
    sudo apt-get -y install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
    sudo apt-get -y install libxvidcore-dev libx264-dev
    sudo apt-get -y install qt4-dev-tools libatlas-base-dev
    sudo apt-get install libgstreamer1.0-dev
    sudo apt-get install libopenexr-dev
    sudo apt-get install libilmbase-dev
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    根据环境的不同,可能有些已安装,可能还缺少其他安装包,根据情况安装。

    pip3 install opencv-python==3.4.6.27
    
    • 1

    也可以把上面的版本去掉,安装最新版本。

    开始推理

    软硬件都准备好后,就可以开始进行推理了。

    准备tflite模型

    由于tensorflow lite仅支持tflite格式的模型,如果你使用其他框架训练的,需要转换成tflite格式。

    由于我的目的是为了演示如何在嵌入式设备上运行推理,所以选择什么模型不重要。

    我给大家准备了一个水果分类和检测的模型,关注微信公众号:人工智能大讲堂,后台回复【rsb】获取模型和前面所有安装包。

    模型在model文件夹下,cls_model.tflite为分类模型,det_model.tflite为目标检测模型。

    图片

    分类模型类别标签

    图片

    目标检测模型类别标签

    打开摄像头

    树莓派开发板通过外接摄像头来拍摄图像。

    sudo raspi-config
    
    • 1

    选择Interface Options—camera,选择yes,将摄像头权限开启,我们便可以使用树莓派进行摄像头拍照了。

    在命令行执行如下命令测试,如果看到文件夹中新增了image.jpg文件,则代表配置成功。

    raspistill -t 2000 -o image.jpg
    
    • 1

    开始推理

    import tensorflow as tf
    import numpy as np
    import cv2
    
    
    
    det = true//是分类还是目标检测
    
    model_path="cls_model.tflite"
    if det:
      model_path="det_model.tflite"
    
    # 加载分类tflite文件
    interpreter = tf.lite.Interpreter(model_path)
    interpreter.allocate_tensors()
    label_id_offset = 1
    
    
    # Again, uncomment this decorator if you want to run inference eagerly
    def detect(interpreter, input_tensor):
      """Run detection on an input image.
    
      Args:
        interpreter: tf.lite.Interpreter
        input_tensor: A [1, height, width, 3] Tensor of type tf.float32.
          Note that height and width can be anything since the image will be
          immediately resized according to the needs of the model within this
          function.
    
      Returns:
        A dict containing 3 Tensors (`detection_boxes`, `detection_classes`,
          and `detection_scores`).
      """
      input_details = interpreter.get_input_details()
      output_details = interpreter.get_output_details()
    
      # We use the original model for pre-processing, since the TFLite model doesn't
      # include pre-processing.
      preprocessed_image, shapes = detection_model.preprocess(input_tensor)
      interpreter.set_tensor(input_details[0]['index'], preprocessed_image.numpy())
    
      interpreter.invoke()
    
      boxes = interpreter.get_tensor(output_details[0]['index'])
      classes = interpreter.get_tensor(output_details[1]['index'])
      scores = interpreter.get_tensor(output_details[2]['index'])
      return boxes, classes, scores
    
    # 定义摄像头
    capture = cv2.VideoCapture(0)
    
    while True:
        # 拍照并预处理照片
        ret, frame = capture.read()
        frame = cv2.flip(frame, 1)
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        
        if det:
          resized_image = cv2.resize(frame_rgb, (300, 300))
        else:
          resized_image = cv2.resize(frame_rgb, (224, 224))
          
        resized_image = resized_image .astype(np.float32)
        # 将像素值缩放到0-1范围
        resized_image /= 255.0
        # 将像素值缩放到-1到1范围
        resized_image = (resized_image - 0.5) * 2.0
            
        test = np.expand_dims(resized_image, axis=0)
        input_tensor = tf.convert_to_tensor(test, dtype=tf.float32)
        # 目标检测模型进行检测
        boxes, classes, scores = detect(interpreter, input_tensor)
        viz_utils.visualize_boxes_and_labels_on_image_array(
            test[0],
            boxes[0],
            classes[0].astype(np.uint32) + label_id_offset,
            scores[0],
            category_index,
            use_normalized_coordinates=True,
            min_score_thresh=0.8)
        # 呈现检测结果
        frame = cv2.cvtColor(test[0], cv2.COLOR_BGR2RGB)
        cv2.imshow("Object detector", frame)
        c = cv2.waitKey(20)
        # 如果按q键,则终止
        if c == 113:
            break
    cv2.destroyAllWindows()
    
    • 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

    最终结果

    图片

    图片

  • 相关阅读:
    什么是ASCII码,ASCII码值的大小顺序是怎么样
    【c语言】100行代码搞定电子琴
    NLog自定义Target之MQTT
    datax 同步本地csv到mysql
    中后台管理系统如何更优雅的支持移动端
    35岁左右的项目经理,这5种能力一定要有​
    Argumentative structure for English essay
    java计算机毕业设计养生药膳推荐系统源程序+mysql+系统+lw文档+远程调试
    高仿拼多多源码/拼单商城系统源码/拼团商城源码
    【Mysql系列】LAG与LEAD开窗函数
  • 原文地址:https://blog.csdn.net/weixin_41755306/article/details/132863718