此次实验主要是利用已经写好的关于垃圾分类的卷积神经网络代码,来进行模型训练、转换、部署的实验的。对于模型的训练利用的是华为云平台来进行训练,而转换则是利用docker容器或者Atlas200DK的开发环境来进行转换,部署则是将转换完成的模型文件部署至Atlas开发板中。最后通过读取本地图像数据,来对图像的垃圾进行识别分类,并保存到本地中。
本次实验为了连接开发板,需要安装linux系统以方便操作。对于linux的安装有很多种方法,可以直接安装虚拟机然后拉入linux镜像配置虚拟环境,也可以直接利用windows的子系统linux,还可以直接将windows系统替换为linux系统(基本不会这样做)。在这里我选择了安装windows的子系统linux来进行实验。以下为linux安装与配置的步骤:
1. 开启windows****子系统功能
打开windows设置-点击应用与功能-点击程序与功能-选择启用或关闭windows功能-勾选启用linux的windows子系统
安装ubantu子系统有两种方式,一种是直接windows的应用商店安装另外一种是手动下载安装包进行安装。这里我为了能把子系统安装到D
盘,我选择了手动下载。
首先在下面的网址上选择unbantu18.04
进行下载
https://docs.microsoft.com/en-us/windows/wsl/install-manual
将安装包改成.zip
后缀然后解压缩点击ubantu.exe
进行安装
先对源文件进行备份
sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup
修改源文件
sudo gedit /etc/apt/sources.list
编辑完后进行以下操作进行更新与升级
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential
至此linux的基础环境就配置好了
这一步主要是恢复Atlas200DK
的系统,其方式是通过存储卡内的系统文件进行安装。其步骤如下:
下载并安装Etcher工具
balenaEtcher - Flash OS images to SD cards & USB drives
下载并解压镜像文件
打开网站中下载回来的文件后进行解压缩,最后能得到一个32GB的镜像文件
Wiki - Gitee.com
插入SD卡配置Etcher并进行烧录
选择好镜像文件,以及磁盘后点击flash后会自动进行烧录,其烧录的图如下所示。
完成后如图所示
插入SD卡至开发板进行系统恢复
如图直接将SD卡插入开发板即可
然后连接电源就会自动升级,
升级成功后四个led灯均会亮起
根据官方的介绍若左边两个led灯亮起则表示开机成功,若右边两个亮起则表示正在升级,若四个均亮起则表示可以正常运行。
对于连接开发板有很多种的方式,不仅仅只能通过linux连接,比如windows的一些ssh软件(如xshell)、windows的linux子系统等均可连接。但是这些连接的前提都是先要把虚拟网卡在本机的网段调整为和开发板的网段一致,linux系统和windows系统的调整方式存在一定的不同。由于一开始我以为子系统拥有linux的所有功能,所以就直接按照指南的操作进行了配置,但是最后发现这是不同的。于是最后还是通过windows进行调整。
识别网卡
首先需要用type-C USB
线连接开发板与电脑。打开windows的设备管理,
打开后会发现有个其他设备(由于我此步已经完成所以看不到其他设备)
对于其他设备会看到
USB RNDIS6
的名称,对于此项右键点击更新驱动程序
,
然后点击浏览我的电脑查找驱动程序
,再点击从我的计算机中选取
,选择网络适配器并选择microsoft
的rndis6
即可安装虚拟网卡驱动。若不完成此操作计算机将不能以网卡的方式发现开发板,也将不能通过ssh连接。
配置同一网段
发现网卡后,在ubuntu中输入ifconfig
指令查看是否有网卡多出(通过拔插的方式发现),如图所示,
在这里虚拟网卡以eth0
的名称被我电脑识别,其ip号为169.254.92.40
,然而开发板的地址是192.168.1.2
如果要让两者连通那么就需要配置同一网段,由于开发板尚未连接上,所以只能配置服务器的。对于子系统配置网段则需要直接配置windows的。
打开控制面板-网络和 Internet-网络连接
控制板的网络连接面板,找到虚拟网卡(其名称为RNDIS6
),如图所示
右键选择属性,如图选择ipv4
协议点击编辑,按照下图配置相关ip与掩码。需要注意的是,这里的Ip地址千万千万不能配置成192.168.1.2,否则ssh连接到的只会是本机,由于一开始对原理不是很了解所以我配置成了192.168.1.2,以至于花费很多时间找出问题。
在完成上面的配置后,再输入ifconfig
查看是否修改成功,如下图所示已经成功修改。
ssh连接开发板
在配置完上面后输入下面的指令即可连接,
ssh [email protected]
密码未Mind@123,若连接失败则可能未开启ssh服务,可以通过下面的指令开启,
service ssh start
连接成功后会如下图所示,
由于我这里使用的是windows的子系统,所以开发板的联网方式,与《大作业指南》的不同。这里我是先利用了USB连接进行开发板网络配置,然后再通过网络连接来共享wifi的网络。下面为具体流程:
网线连接
用网线连接电脑与开发板
在ubuntu中,输入 su root
输入密码Mind@123
进入root用户模式。然后输入下面指令进入开发板网络配置路径
cd /etc/netplan
打开01-netcfg.yaml
进行编辑,
vi 01-netcfg.yaml
network:
version: 2
# renderer: NetworkManager
renderer: networkd
ethernets:
eth0:
dhcp4: yes
addresses: [192.168.0.2/24]
gateway4: 192.168.0.100
nameservers:
addresses: [8.8.8.8]
addresses: [114.114.114.114]
usb0:
dhcp4: no
addresses: [192.168.1.2/24]
gateway4: 192.168.0.1
nameservers:
addresses: [114.114.114.11]
用以上的内容进行代替。完成上面操作后输入下面的指令,令其生效
netplan apply
换至win10系统进行网络配置,同样打开网络适配中心,选出网卡,手动设置其Ipv4协议,如下所示。
完成上面操作后即可用网线连接开发板,不过其ip号会改变,其连接方法如下
ssh [email protected]
以共享方式配置wifi网卡
由于电脑的网卡接口已经与开发板连接,所以只能利用wifi来进行联网。
同样先打开网络适配中心,找出wifi网卡的适配器,然后打开属性,切换至共享,在家庭网络连接
中选择网线的适配器即可,
在配置完上面后,网线网卡的ipv4会改变,只需要重新调整回来即可。至此联网配置就完成了。下面为ping www.baidu.com 的效果图,可以看到可以成功连网。
对于模型的训练,为了拥有更好的计算资源,我们选择了用华为云来进行云上训练。
创建OBS
登录到华为云中,寻找出OBS存储桶并创建,如下图所示,
搭建Model Arts环境
进入华为云的Model Arts区块,并创建notebook。在创建Notebook时,选择Ascend-Powered-Engine 1.0 (Python3)镜像,然后选择新创建的OBS存储,如下图所示
创建完成后,需要将训练代码以及数据集传入到云端中,在存储桶截面上传mobienetv2_garbage.zip到/name/123路径中,上传完成后打开jupyternotebook终端对压缩包进行解压缩,如下图所示,
训练MobileNetV2模型
在准备好数据集后,创建一个notebook文件并复制mobienetv2_garbage中的训练代码到notebook中,然后运行,并保存最有模型,
对于模型的转换,《大作业指南》中给出了两种转换方法,分别为利用自身电脑的Ubuntu系统拉入docker镜像进行转换与利用开发板自身的开发环境进行转换。这里的两种方式我都尝试了,相对来说开发板直接转换的方式会更为简单,由于限制篇幅,所以这里只重点说明开发板中的转换,
由于转换工具的环境集成在了docker中,所以需要安装docker。由于我是使用windows子系统作为ubuntu系统的,所以安装方法有所不同。
切换为wsl2
由于wsl1并不拥有完整的linux内核,所以先需要升级。
在终端中输入下面的指令查看版本号,与子系统个数与名称。
wsl -l -v
由于我之前先升级了,所以这里已经为wsl2了,若为1的则输入下面指令升级。
wsl --set-version Ubuntu-18.04 2
安装docker
打开ubuntu终端逐一输入下面的指令利用脚本安装docker。参考:https://blog.csdn.net/qq_38856939/article/details/116528514
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo service docker start
输入下面的指令查看docker是否能正常运行,
sudo service docker status
若显示Docker is running
则说明可以正常使用了。
拉入镜像
在ubuntu的终端中输入下面的指令拉取镜像并运行,
docker run -it --privileged -v /dev:/dev -v /tmp:/tmp --net=host -e DISPLAY=$DISPLAY taotaoba/develop-env:cann3.3.a1
# it 表示打开可交互终端
# --privileged 表示容器内的root用户可以使用宿主机的root权限
# -v 表示绑定宿主机和容器间的卷
# --net 表示容器的网络连接类型
# -e 用于设置环境变量
运行程序进行转换
在完成上一步后,输入下面指令进入此镜像的终端,若拉取完镜像后自动进入了就无需操作此步,
# 运行容器
docker run -it --privileged -v /dev:/dev -v /tmp:/tmp --net=host -e DISPLAY=$DISPLAY taotaoba/develop-env:cann3.3.a1
#重启后通过下面指令进入镜像终端
docker exec -it 容器名/容器ID /bin/bash
19f259bcd84f
docker exec -it 19f259bcd84f /bin/bash
在容器中切换Ascend
用户,
# 在容器中执行
su Ascend
bash
下载cfg文件,拉入一个目录,下载链接为:https://c7xcode.obs.cn-north-4.myhuaweicloud.com/models/garbage_picture/insert_op_yuv.cfg,也可以用wget
方式下载,也可以直接下载。
下载完成后,保持docker终端不动,打开另外一个终端进行文件传输操作,
查看ID号,
docker ps -a # 查看当前容器的ID
#由下图可知ID为 ac5384396884
b1c6b811c63f
docker cp mobilenetv2文件的父目录/mobilenetv2.air
容器ID号:/home/Ascend
docker cp cfg文件所在的父目录/insert_op_yuv.cfg
容器ID号:/home/Ascend
# /mnt/d/学习资料/大二下/资料/人工智能概述/大作业/转换临时文件夹
docker cp insert_op_yuv.cfg 19f259bcd84f:/home/Ascend
传输完成后,再切换至docker终端中,输入下面的指令进行转换,
cd /home/Ascend #确保进入了此目录
atc --model=./mobilenetv2.air --framework=1 --output=garbage_yuv --soc_version=Ascend310 --insert_op_conf=./insert_op_yuv.cfg --input_shape="data:1,3,224,224" --input_format=NCHW
然而再转换过程中出现了下面的错误,
提示权限不足,所以我把Ascend
的权限改为了root权限,
先切换回root,
sudo -i
然后输入下面的指令修改文件,
vi /etc/passwd
将下图的红圈圈住的内容改为0,
然后再指向转换命令即可转换成功,
转换完成后,会在同一目录下产生转换文件,对于此文件则需要将其拉出到一个自己记得的文件夹中,在ubuntu中输入此命令进行拉出,
#在宿主机中执行以下命令,将om文件copy出来
docker cp 容器ID号:/home/Ascend/garbage_yuv.om 想要存储的文件夹
#文件夹目录 /mnt/d/学习资料/大二下/资料/人工智能概述/大作业/转换临时文件夹
docker cp 19f259bcd84f:/home/Ascend/garbage_yuv.om /mnt/d/学习资料/大二下/资料/人工智能概述/大作业/转换临时文件夹
这个的前提是已经配置好了合设环境。对于直接利用开发板转换,可以减少很多的环境配置。
传入文件
按照之前的操作输入指令连接开发板,并创建文件夹
ssh [email protected]
#密码 Mind@123
mkdir -p ~/projects/atc-test
切换至ubuntu,输入下面的指令传入文件,
cd 模型所在的目录
# /mnt/d/学习资料/大二下/资料/人工智能概述/大作业/转换临时文件夹
#传入air模型
scp -r mobilenetv2.air [email protected]:/home/HwHiAiUser/projects/atc-test/
#传入cfg文件
scp -r insert_op_yuv.cfg [email protected]:/home/HwHiAiUser/projects/atc-test/
进行转换
在传入必要文件后,切换到开发板终端,输入下面的指令进行转换,
cd $HOME/projects/atc-test
# 完成模型转换
atc --model=./mobilenetv2.air --framework=1 --output=garbage_yuv --soc_version=Ascend310 --insert_op_conf=./insert_op_yuv.cfg --input_shape="data:1,3,224,224" --input_format=NCHW
转换成功后如下图所示,
查看文件可以看到有om文件的存在,
在完成模型转换后,下一步需要对Python的模板文件需要镜像补充与修改。
创建数据集
打开子系统ubuntu,进入需要暂时存储的文件夹中,
#ssh [email protected]
cd /mnt/d/学习资料/大二下/资料/人工智能概述/大作业/转换临时文件夹/测试集与代码
创建data文件夹,并进入文件夹
mkdir -p data
cd data
获取网络数据,
wget https://c7xcode.obs.cn-north-4.myhuaweicloud.com/models/garbage_picture/newspaper.jpg
wget https://c7xcode.obs.cn-north-4.myhuaweicloud.com/models/garbage_picture/bottle.jpg
wget https://c7xcode.obs.cn-north-4.myhuaweicloud.com/models/garbage_picture/dirtycloth.jpg
创建代码文件
创建源码文件夹,并进入文件夹并添加源码文件
mkdir src
cd src
vim classify_test.py
加入下面代码,
#!/usr/bin/env python
# encoding: utf-8
import sys
import os
path = os.path.dirname(os.path.abspath(__file__))
import numpy as np
import acl
import base64
from PIL import Image, ImageDraw, ImageFont
from atlas_utils.acl_dvpp import Dvpp
import atlas_utils.constants as const
from atlas_utils.acl_model import Model
from atlas_utils.acl_image import AclImage
from atlas_utils.acl_resource import AclResource
SRC_PATH = os.path.realpath(__file__).rsplit("/", 1)[0]
MODEL_PATH = os.path.join(SRC_PATH, "../model/garbage_yuv.om")
MODEL_WIDTH = 224
MODEL_HEIGHT = 224
image_net_classes = [
"Seashel", "Lighter","Old Mirror", "Broom","Ceramic Bowl",
"Toothbrush","Disposable Chopsticks","Dirty Cloth",
"Newspaper", "Glassware", "Basketball", "Plastic Bottle",
"Cardboard","Glass Bottle", "Metalware", "Hats", "Cans", "Paper",
"Vegetable Leaf","Orange Peel", "Eggshell","Banana Peel",
"Battery", "Tablet capsules","Fluorescent lamp", "Paint bucket"]
def get_image_net_class(class_id):
if class_id >= len(image_net_classes):
return "unknown"
else:
return image_net_classes[class_id]
def pre_process(image, dvpp):
"""preprocess"""
image_input = image.copy_to_dvpp()
yuv_image = dvpp.jpegd(image_input)
print("decode jpeg end")
resized_image = dvpp.resize(yuv_image,MODEL_WIDTH, MODEL_HEIGHT)
print("resize yuv end")
return resized_image
def post_process(infer_output, image_file):
print("post process")
data = infer_output[0]
vals = data.flatten()
top_k = vals.argsort()[-1:-6:-1]
object_class = get_image_net_class(top_k[0])
output_path = os.path.join(os.path.join(SRC_PATH, "../outputs"),
os.path.basename(image_file))
origin_image = Image.open(image_file)
draw = ImageDraw.Draw(origin_image)
font = ImageFont.load_default()
font.size =50
draw.text((10, 50), object_class, font=font, fill=255)
origin_image.save(output_path)
object_class = get_image_net_class(top_k[0])
return
def construct_image_info():
"""construct image info"""
image_info = np.array([MODEL_WIDTH, MODEL_HEIGHT,MODEL_WIDTH, MODEL_HEIGHT],dtype = np.float32)
return image_info
def main():
if (len(sys.argv) != 2):
# 这里的第一个参数是脚本名称,第二个参数是图片的目录
print("The App arg is invalid")
exit(1)
acl_resource = AclResource()
acl_resource.init()
model = Model(MODEL_PATH)
dvpp = Dvpp(acl_resource)
image_dir = sys.argv[1]
images_list = [os.path.join(image_dir, img) for img in os.listdir(image_dir) if os.path.splitext(img)[1] in const.IMG_EXT]
#Create a directory to store the inference results
if not os.path.isdir(os.path.join(SRC_PATH, "../outputs")):
os.mkdir(os.path.join(SRC_PATH, "../outputs"))
image_info = construct_image_info()
for image_file in images_list:
image = AclImage(image_file)
resized_image = pre_process(image, dvpp)
print("pre process end")
result = model.execute([resized_image,])
post_process(result, image_file)
print("process "+image_file+" end")
if __name__ == '__main__':
main()
解压atlas_utils.zip
文件(在群文件里)到临时文件夹中,
unzip -d /mnt/d/学习资料/大二下/资料/人工智能概述/大作业/转换临时文件夹/测试集与代码 atlas_utils.zip
把之前的air cfg om
文件拉入到model
文件夹中,
输入命令查看文件的完整性,
tree . -L 2
连接开发板
ssh [email protected]
#网线连接
创建项目文件
mkdir -p ~/projects
将文件拉入开发板中
在ubuntu中执行下面的命令,
scp -r /mnt/d/学习资料/大二下/资料/人工智能概述/大作业/转换临时文件夹/测试集与代码 [email protected]:/home/HwHiAiUser/projects
开发板推理
在开发板中执行下面命令进行推理,
cd $HOME/projects/garbage_classification/
python3.6 src/classify_test.py ./data/
获取推理结果
scp -r [email protected]:/home/HwHiAiUser/projects/测试集与代码/outputs ./outputs
结果如下所示,可以看到预测是有效的。