基于MAX78000的十二生肖检测仪
生肖也称为属相,是中国传统文化中的一种纪年方式,是对古代中国时间、自然、文化方面的总结和反映,具有文化和历史价值,被广泛运用于各种文化载体。因此本项目的目标是基于图像识别等技术,利用MAX78000开发板完成日常生活中生肖的检测任务。
标签
嵌入式系统
AI
MAX78000
空白blank
更新2024-01-10
天津职业技术师范大学
140

1.项目介绍:

生肖也称为属相,共有十二种生肖,分别是鼠、牛、虎、兔、龙、蛇、马、羊、猴、鸡、狗、猪,每个生肖都有其独特的寓意和象征意义,是中国传统文化中的一种记年方式,是一种十二年一个循环的纪年系统,每年用一种动物来代表,每隔十二年循环一次。十二生肖起源于中国古代天文历法中的十二地支,对应子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥,形成了现在的生肖记年法。生肖是中国传统文化中的重要组成部分,它不仅是一种纪年方式,也是对古代中国时间、自然、文化方面的总结和反映,具有文化和历史价值。十二生肖是中国文化的重要符号之一,它已经被广泛运用于绘画、雕塑、陶瓷、民间传说、戏曲、游戏、影视、动画、书籍、旅游各种文化载体,十二生肖也被广泛应用于商业文化中,例如在中国的年货市场上,各种与生肖相关的商品,如手工艺品、玩具、书籍、饰品、绘画作品等都备受欢迎。
在当今世界中,机器学习,深度学习,计算机视觉等技术日新月异,在不断飞速发展的同时也使得图像识别技术等AI技术也在我们的生活中大放异彩。我认为通过图像识别检测十二生肖,可以让人们更好的了解到生肖,更好的了解中国传统文化。因此本项目的目标是基于图像识别等技术,利用MAX78000开发板完成日常生活中生肖的检测任务,使用板卡上的摄像头采集图像,并使用AI技术判断图像中是否有十二生肖,并显示其中十二生肖的名称。

FpG5SnCPFMgIOyiMeUemeeWtRoDu

图1-1 生肖龙

FiBbxIAKIbFrdLZHf28aI7uCzwLz

图1-2 生肖虎

Fo7csdF1OAbrgEZNQKCUiL11f3V3

图1-3 生肖羊

2.项目设计思路:

项目设计思路如下图所示:

Fo56tuHOyyXQpM-gUaOnEs7WPkHa

图2-1 十二生肖检测仪项目设计思路

 

3.搜集素材的思路:

3.1 生肖数据收集

本项目中用到的十二生肖数据集本来来源于一个网站:https://www.kaggle.com/datasets/elderyouth/chinese-zodiac-signs/data,其包含了十二生肖共8508张图像。但是后续发现该数据集中的图片类型有些问题,其中龙生肖中有一半图片来自于西方龙,并不符合十二生肖的设定,而其他生肖的图片几乎都来自于真实的动物,没有包含其他艺术文化形式的图片类型,如:剪纸,美术形式。所以我把数据集中的西方龙的图片删除,加上自己在百度,谷歌,必应等平台上搜集了一些其他艺术类型的生肖图片,每种类别收集了几十张,然后对这些图片做了剪切等处理,合并进了原本的数据集之中,最终得到的新的数据集其中训练集占比80%,验证集占比10%,测试集占比10%。

FrLyFOQUeBjNkN6Bb-lbPEn0C6BP

图3-1 训练集内容图

3.2 生成数据集

生成数据集采用pytorch的ImageFolder类读取图片并进行处理,训练集和测试集都采用此方法进行生成。由于网络处理的图片需要拥有统一的图片尺寸,而原始数据集中的图片尺寸不一样,所以我们需要把所有图片进行尺寸变换,统一将图片大小都设置为128×128。即使本项目训练集数据很丰富,我们依旧需要对训练集进行数据增强以提高训练精度,提升不同场景下的鲁棒性并防止过拟合,最后需要将图片变换成pytorch张量并进行归一化,将数据从[0,1]变换至[-128,127]。生成数据集代码如下:

train_transform = transforms.Compose([
            transforms.RandomAffine(degrees=10, translate=(0.05, 0.05), shear=5),
            transforms.RandomPerspective(distortion_scale=0.3, p=0.2),
            transforms.RandomHorizontalFlip(),
            transforms.ColorJitter(brightness=0.7),
            transforms.Resize((128, 128)),
            transforms.ToTensor(),
            ai8x.normalize(args=args),
        ])

将数据集分成分成train,test和valid三类并放置到目录ai8x-training/data下,  然后在ai8x-training/datasets下新建一个文件shenxiao.py,用于编写读取数据集的代码,读取和生成数据集的具体代码如下:

import os

from torchvision import transforms
from torchvision.datasets import ImageFolder
import ai8x

def shenxiao_get_datasets(data, load_train=True, load_test=True):
    (data_dir, args) = data

    if load_train:
        train_transform = transforms.Compose([
            transforms.RandomAffine(degrees=10, translate=(0.05, 0.05), shear=5),
            transforms.RandomPerspective(distortion_scale=0.3, p=0.2),
            transforms.RandomHorizontalFlip(),
            transforms.ColorJitter(brightness=0.7),
            transforms.Resize((128, 128)),
            transforms.ToTensor(),
            ai8x.normalize(args=args),
        ])

        train_dataset = ImageFolder(root=os.path.join(data_dir, 'train'), transform=train_transform)
    else:
        train_dataset = None

    if load_test:
        test_transform = transforms.Compose([
            transforms.Resize((128, 128)),
            transforms.ToTensor(),
            ai8x.normalize(args=args),
        ])

        test_dataset = ImageFolder(root=os.path.join(data_dir, 'test'), transform=test_transform)
    else:
        test_dataset = None

    return train_dataset, test_dataset

datasets = [
    {
        'name': 'shenxiao',
        'input': (3, 128, 128),
        'output': ('rat', 'ox', 'tiger', 'rabbit', 'dragon', 'snake', 'horse', 'goat', 'monkey', "rooster", "dog", "pig"),
        'loader': shenxiao_get_datasets,
    },
]

4.预训练实现过程:

预训练主要参照官方 AI 文档:https://github.com/MaximIntegratedAI/MaximAI_Documentation
MAX78000 中使用 AI 算法主要有 training、synthesis、deployment 三个步骤
ai8x-training仓库,用于在电脑上训练神经网络:https://github.com/MaximIntegratedAI/ai8x-training
ai8x-synthesis仓库,用于把训练好的模型文件转换成c语言代码:https://github.com/MaximIntegratedAI/ai8x-synthesis
msdk仓库,用于编写单片机程序:https://github.com/Analog-Devices-MSDK/msdk

4.1 环境搭建:

本次项目的环境要求如下所示:

CPU: 64-bit amd64/x86_64 “PC” with Ubuntu Linux 20.04 LTS GPU for hardware acceleration (optional but highly recommended): Nvidia with CUDA 11 PyTorch 1.8.1 (LTS) on Python 3.8.x

4.1.1 安装MSDK(需要科学上网)

首先需要下载安装MaximMicrosSDK,官网地址如下:https://www.maximintegrated.com/en/design/software-description.html/swpart=SFW0010820A

具体安装流程参考:https://blog.csdn.net/VOR234/article/details/128061754

4.1.2 下载ai8x-training和ai8x-synthesis仓库(需要科学上网)

下载地址如下:

ai8x-training:https://github.com/MaximIntegratedAI/ai8x-training.git

ai8x-synthesis:https://github.com/MaximIntegratedAI/ai8x-synthesis.git

4.1.3 安装Anaconda3

Anaconda的下载地址:https://www.anaconda.com/download/

具体安装流程参考:https://blog.csdn.net/weixin_37766087/article/details/100742198

4.1.4 虚拟环境搭建

虚拟环境搭建教程参考:https://blog.csdn.net/m0_62648611/article/details/131731563

如果下载太慢,可以使用国内镜像源,ai8x_training环境的构建代码如下:

> conda create -n ai8x_training python=3.8.11
> D:
> cd MAX78000\AI\ai8x-training
> conda activate ai8x_training
> pip3 install -r requirements-win-cu11.txt -i https://mirrors.aliyun.com/pypi/simple/

ai8x-synthesis环境的构建和ai8x-training同理,构建代码如下:

 > conda create -n ai8x_synthesis python=3.8.11
 > D:
 > cd MAX78000\AI\ai8x-synthesis
 > conda activate ai8x_synthesis
 > pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/

4.1.5 安装pycharm配置环境

pycharm下载地址:https://www.jetbrains.com/pycharm/download/

具体安装流程参考:https://blog.csdn.net/2301_78077589/article/details/130723662

给pycharm配置anaconda构建的虚拟环境的教程:

Fs1yYin6F0M6wUHuCxyqFwQRWNNh

FhH30tIt47c5uVypwIRFysvsdsKn

Fj2u_cFAnyY5_9T0onqGt0jGZ4tF

FvVloygHgoQUh_cdJ_tn74mix6nT

图4-1 给pycharm配置anaconda构建的虚拟环境流程图

对ai8x-training文件夹和ai8x-synthesis文件夹分别配置ai8x-training环境和ai8x-synthesis环境。

4.2 模型选择和优化

本项目分别使用了基于ai85net-cd模型,精简的res模型和ai85net-simplenet-wide2x模型修改而来的模型进行训练,经过了反复训练和测试,基于精简的res模型修改的模型得到的模型训练结果如下:

2023-12-09 18:59:47,007 - Training epoch: 7011 samples (240 per mini-batch)
2023-12-09 19:00:18,161 - Epoch: [314][   10/   30]    Overall Loss 1.343042    Objective Loss 1.343042                                        LR 0.000040    Time 3.115309    
2023-12-09 19:00:31,913 - Epoch: [314][   20/   30]    Overall Loss 1.356508    Objective Loss 1.356508                                        LR 0.000040    Time 2.245153    
2023-12-09 19:00:44,211 - Epoch: [314][   30/   30]    Overall Loss 1.346136    Objective Loss 1.346136    Top1 57.388316    Top5 93.470790    LR 0.000040    Time 1.906669    
2023-12-09 19:00:44,647 - --- validate (epoch=314)-----------
2023-12-09 19:00:44,648 - 779 samples (240 per mini-batch)
2023-12-09 19:01:06,109 - Epoch: [314][    4/    4]    Loss 1.547752    Top1 49.550706    Top5 87.804878    
2023-12-09 19:01:06,530 - ==> Top1: 49.551    Top5: 87.805    Loss: 1.548

2023-12-09 19:01:06,532 - ==> Best [Top1: 51.733   Top5: 87.291   Sparsity:0.00   Params: 80734 on epoch: 222]
2023-12-09 19:01:06,532 - Saving checkpoint to: logs\2023.12.09-115000\qat_checkpoint.pth.tar

基于ai85net-simplenet-wide2x模型修改得到的模型训练结果如下:

2023-12-10 18:47:46,369 - Training epoch: 7003 samples (240 per mini-batch)
2023-12-10 18:48:26,924 - Epoch: [149][   10/   30]    Overall Loss 2.022833    Objective Loss 2.022833                                        LR 0.000016    Time 4.055343    
2023-12-10 18:48:46,152 - Epoch: [149][   20/   30]    Overall Loss 2.029027    Objective Loss 2.029027                                        LR 0.000016    Time 2.989004    
2023-12-10 18:49:02,771 - Epoch: [149][   30/   30]    Overall Loss 2.042283    Objective Loss 2.042283    Top1 28.975265    Top5 73.851590    LR 0.000016    Time 2.546633    
2023-12-10 18:49:03,299 - --- validate (epoch=149)-----------
2023-12-10 18:49:03,299 - 778 samples (240 per mini-batch)
2023-12-10 18:49:26,286 - Epoch: [149][    4/    4]    Loss 2.069062    Top1 26.221080    Top5 72.107969    
2023-12-10 18:49:26,714 - ==> Top1: 26.221    Top5: 72.108    Loss: 2.069

2023-12-10 18:49:26,717 - ==> Best [Top1: 30.334   Top5: 73.008   Sparsity:0.00   Params: 708232 on epoch: 128]
2023-12-10 18:49:26,717 - Saving checkpoint to: logs\2023.12.10-143357\qat_checkpoint.pth.tar
2023-12-10 18:49:26,744 - --- test ---------------------
2023-12-10 18:49:26,745 - 757 samples (240 per mini-batch)
2023-12-10 18:49:47,459 - Test: [    4/    4]    Loss 2.138329    Top1 28.533686    Top5 71.202114    
2023-12-10 18:49:47,885 - ==> Top1: 28.534    Top5: 71.202    Loss: 2.138

基于ai85net-cd模型修改得到的模型训练结果如下:

2023-12-08 15:44:14,170 - Training epoch: 7011 samples (240 per mini-batch)
2023-12-08 15:44:48,694 - Epoch: [99][   10/   30]    Overall Loss 1.120448    Objective Loss 1.120448                                        LR 0.000200    Time 3.452330    
2023-12-08 15:45:01,504 - Epoch: [99][   20/   30]    Overall Loss 1.088512    Objective Loss 1.088512                                        LR 0.000200    Time 2.366598    
2023-12-08 15:45:17,432 - Epoch: [99][   30/   30]    Overall Loss 1.079984    Objective Loss 1.079984    Top1 64.604811    Top5 95.876289    LR 0.000200    Time 2.108631    
2023-12-08 15:45:17,882 - --- validate (epoch=99)-----------
2023-12-08 15:45:17,882 - 779 samples (240 per mini-batch)
2023-12-08 15:45:41,735 - Epoch: [99][    4/    4]    Loss 1.341696    Top1 53.016688    Top5 88.703466    
2023-12-08 15:45:42,193 - ==> Top1: 53.017    Top5: 88.703    Loss: 1.342

2023-12-08 15:45:42,194 - ==> Best [Top1: 55.712   Top5: 88.447   Sparsity:0.00   Params: 68015 on epoch: 86]
2023-12-08 15:45:42,195 - Saving checkpoint to: logs\2023.12.08-131828\qat_checkpoint.pth.tar
2023-12-08 15:45:42,209 - --- test ---------------------
2023-12-08 15:45:42,209 - 757 samples (240 per mini-batch)
2023-12-08 15:46:01,734 - Test: [    4/    4]    Loss 1.527895    Top1 51.387054    Top5 88.375165    
2023-12-08 15:46:02,194 - ==> Top1: 51.387    Top5: 88.375    Loss: 1.528

由上述三个模型的训练结果对比,发现依旧还是基于ai85net-cd模型修改而来的模型进行训练效果最佳,但是虽然该模型的top5能够达到88%,top1却只有51%,为了增加该模型的准确率,我使用了增加训练循环次数,增加网络模型深度和添加残差连接,等方法对训练进行修改,但效果均不理想。增加训练循环次数的训练结果如下:

2023-12-08 19:31:33,422 - Training epoch: 7012 samples (256 per mini-batch)
2023-12-08 19:32:11,261 - Epoch: [149][   10/   28]    Overall Loss 1.159092    Objective Loss 1.159092                                        LR 0.000016    Time 3.783916    
2023-12-08 19:32:25,817 - Epoch: [149][   20/   28]    Overall Loss 1.179319    Objective Loss 1.179319                                        LR 0.000016    Time 2.619768    
2023-12-08 19:32:40,621 - Epoch: [149][   28/   28]    Overall Loss 1.184086    Objective Loss 1.184086    Top1 63.764045    Top5 93.258427    LR 0.000016    Time 2.399973    
2023-12-08 19:32:41,085 - --- validate (epoch=149)-----------
2023-12-08 19:32:41,086 - 779 samples (256 per mini-batch)
2023-12-08 19:33:03,846 - Epoch: [149][    4/    4]    Loss 1.397416    Top1 52.118100    Top5 88.318357    
2023-12-08 19:33:04,336 - ==> Top1: 52.118    Top5: 88.318    Loss: 1.397

2023-12-08 19:33:04,337 - ==> Confusion:
[[33  1  6  5 11  3  5 11  7  2  0  2]
 [ 0 11  1  1  1  0  1  0  0  7  8  2]
 [ 8  0 27  6  2  3  3  5  1  2  5  1]
 [ 4  1  4 34  1  8  2  2  2  1  0  1]
 [10  1  4  1 46  2 10  4  5  0  1  1]
 [ 2  1  2  9  0 36  2  0  3  3  1  1]
 [ 7  1  5  0  4  6 42  0  2  2  2  2]
 [ 6  2  5  2  4  1  4 20  8  4  9  0]
 [ 2  1  3  1  3  2 10 10 20  2  4  3]
 [ 0  2  0  0  1  2  2  1  5 50  4  3]
 [ 2  7  2  1  2  0  1  2  6  2 29  2]
 [ 0  5  1  0  2  0  1  0  0  1  0 58]]

2023-12-08 19:33:04,339 - ==> Best [Top1: 53.273   Top5: 87.035   Sparsity:0.00   Params: 68016 on epoch: 127]
2023-12-08 19:33:04,340 - Saving checkpoint to: logs\2023.12.08-155241\qat_checkpoint.pth.tar
2023-12-08 19:33:04,355 - --- test ---------------------
2023-12-08 19:33:04,355 - 757 samples (256 per mini-batch)
2023-12-08 19:33:23,253 - Test: [    3/    3]    Loss 1.602395    Top1 48.745046    Top5 84.412153    
2023-12-08 19:33:23,713 - ==> Top1: 48.745    Top5: 84.412    Loss: 1.602

增加网络模型深度和添加残差连接的训练结果如下:

2023-12-10 08:19:42,518 - Training epoch: 7004 samples (240 per mini-batch)
2023-12-10 08:20:17,673 - Epoch: [149][   10/   30]    Overall Loss 1.288790    Objective Loss 1.288790                                        LR 0.000016    Time 3.515372    
2023-12-10 08:20:29,793 - Epoch: [149][   20/   30]    Overall Loss 1.294369    Objective Loss 1.294369                                        LR 0.000016    Time 2.363632    
2023-12-10 08:20:44,590 - Epoch: [149][   30/   30]    Overall Loss 1.290687    Objective Loss 1.290687    Top1 56.338028    Top5 89.436620    LR 0.000016    Time 2.068950    
2023-12-10 08:20:45,015 - --- validate (epoch=149)-----------
2023-12-10 08:20:45,015 - 778 samples (240 per mini-batch)
2023-12-10 08:21:06,590 - Epoch: [149][    4/    4]    Loss 1.547520    Top1 48.071979    Top5 85.475578    
2023-12-10 08:21:07,050 - ==> Top1: 48.072    Top5: 85.476    Loss: 1.548

2023-12-10 08:21:07,052 - ==> Best [Top1: 51.157   Top5: 86.504   Sparsity:0.00   Params: 72880 on epoch: 91]
2023-12-10 08:21:07,052 - Saving checkpoint to: logs\2023.12.10-044317\qat_checkpoint.pth.tar
2023-12-10 08:21:07,069 - --- test ---------------------
2023-12-10 08:21:07,070 - 757 samples (240 per mini-batch)
2023-12-10 08:21:25,761 - Test: [    4/    4]    Loss 1.626634    Top1 47.820343    Top5 85.468956    
2023-12-10 08:21:26,189 - ==> Top1: 47.820    Top5: 85.469    Loss: 1.627

因此最终选择由SDK中自带的ai85net-cd猫狗分类模型修改得到本项目的十二生肖检测模型该模型被用于十二分类任务,输入为尺寸128×128×3的RGB图像,共包含了6个卷积层,除最后一个卷积层外,每个卷积层后还包含批归一化操作和ReLU激活层。

4.3 模型训练

在pycharm打开ai8x-training文件夹搭建训练模型,在ai8x-training/models下新建一个文件ai85net-shenxiao.py进行模型搭建,模型的具体内容如下:

from torch import nn
import ai8x
class AI85Net_Shenxiao(nn.Module):
    def __init__(self, num_classes=12, num_channels=3, dimensions=(128, 128),
                 fc_inputs=16, bias=False, **kwargs):
        super().__init__()
        assert dimensions[0] == dimensions[1]  
        dim = dimensions[0]
        self.conv1 = ai8x.FusedConv2dReLU(num_channels, 16, 3,
                                          padding=1, bias=bias, **kwargs)
        pad = 2 if dim == 28 else 1
        self.conv2 = ai8x.FusedMaxPoolConv2dReLU(16, 32, 3, pool_size=2, pool_stride=2,
                                                 padding=pad, bias=bias, **kwargs)
        dim //= 2  
        if pad == 2:
            dim += 2  
        self.conv3 = ai8x.FusedMaxPoolConv2dReLU(32, 64, 3, pool_size=2, pool_stride=2, padding=1,
                                                 bias=bias, **kwargs)
        dim //= 2  
        self.conv4 = ai8x.FusedMaxPoolConv2dReLU(64, 32, 3, pool_size=2, pool_stride=2, padding=1,
                                                 bias=bias, **kwargs)
        dim //= 2  
        self.conv5 = ai8x.FusedMaxPoolConv2dReLU(32, 32, 3, pool_size=2, pool_stride=2, padding=1,
                                                 bias=bias, **kwargs)
        dim //= 2  
        self.conv6 = ai8x.FusedConv2dReLU(32, fc_inputs, 3, padding=1, bias=bias, **kwargs)
        self.fc = ai8x.Linear(fc_inputs*dim*dim, num_classes, bias=True, wide=True, **kwargs)
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
    def forward(self, x):  # pylint: disable=arguments-differ
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = self.conv4(x)
        x = self.conv5(x)
        x = self.conv6(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x
def ai85net_shenxiao(pretrained=False, **kwargs):
    assert not pretrained
    return AI85Net_Shenxiao(**kwargs)
models = [
    {
        'name': 'ai85net_shenxiao',
        'min_input': 1,
        'dim': 2,
    },
]

然后在ai8x-training/policies下新建文件schedule-shenxiao.py,填写learning rate schedule配置文件如下:

lr_schedulers:
  training_lr:
    class: MultiStepLR
    milestones: [40, 60, 80]
    gamma: 0.25

policies:
  - lr_scheduler:
      instance_name: training_lr
    starting_epoch: 0
    ending_epoch: 100
    frequency: 1

最后把模型训练参数设置为100epoch,batchsize128,学习率0.001,优化器为Adam,并随着训练进度阶梯式调整学习率来使模型得到充分训练,具体训练脚本如下:

python train.py --epochs 100 --optimizer Adam --lr 0.001 --wd 0.001 --batch-size 240 --gpus 0 --deterministic --compress policies/schedule-shenxiao.yaml --model ai85net_shenxiao --dataset shenxiao --param-hist --pr-curves --embedding --device MAX78000

把该脚本直接放入pycharm终端运行即可。

Fr1zdPz9ifbpIRjng4s15YyEj-2f

图4-2 pycharm运行训练脚本过程图

训练输出结果如下:

2023-12-08 13:18:28,764 - Log file for this run: D:\MAX7800\12sx\shenxiao\ai8x-training\logs\2023.12.08-131828\2023.12.08-131828.log
2023-12-08 13:18:29,901 - Optimizer Type: <class 'torch.optim.adam.Adam'>
2023-12-08 13:18:29,901 - Optimizer Args: {'lr': 0.001, 'betas': (0.9, 0.999), 'eps': 1e-08, 'weight_decay': 0.001, 'amsgrad': False}
2023-12-08 13:18:30,032 - Dataset sizes:
	training=7011
	validation=779
	test=757
2023-12-08 13:18:30,033 - Reading compression schedule from: policies/schedule-shenxiao.yaml
2023-12-08 13:18:30,036 - 

2023-12-08 13:18:30,036 - Training epoch: 7011 samples (240 per mini-batch)
2023-12-08 13:19:09,478 - Epoch: [0][   10/   30]    Overall Loss 2.473655    Objective Loss 2.473655                                        LR 0.001000    Time 3.944174    
2023-12-08 13:19:19,970 - Epoch: [0][   20/   30]    Overall Loss 2.464135    Objective Loss 2.464135                                        LR 0.001000    Time 2.496557    
2023-12-08 13:19:38,074 - Epoch: [0][   30/   30]    Overall Loss 2.455299    Objective Loss 2.455299    Top1 14.776632    Top5 55.670103    LR 0.001000    Time 2.267841    
2023-12-08 13:19:38,526 - --- validate (epoch=0)-----------
2023-12-08 13:19:38,526 - 779 samples (240 per mini-batch)
2023-12-08 13:20:00,477 - Epoch: [0][    4/    4]    Loss 2.425305    Top1 11.810013    Top5 54.942234    
2023-12-08 13:20:00,922 - ==> Top1: 11.810    Top5: 54.942    Loss: 2.425

2023-12-08 13:20:00,924 - ==> Best [Top1: 11.810   Top5: 54.942   Sparsity:0.00   Params: 68016 on epoch: 0]
2023-12-08 13:20:00,924 - Saving checkpoint to: logs\2023.12.08-131828\checkpoint.pth.tar
2023-12-08 13:20:00,940 - 

2023-12-08 13:20:00,940 - Training epoch: 7011 samples (240 per mini-batch)
2023-12-08 13:20:35,171 - Epoch: [1][   10/   30]    Overall Loss 2.408739    Objective Loss 2.408739                                        LR 0.001000    Time 3.422906    
2023-12-08 13:20:49,266 - Epoch: [1][   20/   30]    Overall Loss 2.386310    Objective Loss 2.386310                                        LR 0.001000    Time 2.416246    
2023-12-08 13:21:05,251 - Epoch: [1][   30/   30]    Overall Loss 2.367534    Objective Loss 2.367534    Top1 17.182131    Top5 61.855670    LR 0.001000    Time 2.143635    
2023-12-08 13:21:05,694 - --- validate (epoch=1)-----------
2023-12-08 13:21:05,694 - 779 samples (240 per mini-batch)
2023-12-08 13:21:28,242 - Epoch: [1][    4/    4]    Loss 2.367832    Top1 17.715019    Top5 57.637997    
2023-12-08 13:21:28,684 - ==> Top1: 17.715    Top5: 57.638    Loss: 2.368

2023-12-08 13:21:28,685 - ==> Best [Top1: 17.715   Top5: 57.638   Sparsity:0.00   Params: 68016 on epoch: 1]
2023-12-08 13:21:28,686 - Saving checkpoint to: logs\2023.12.08-131828\checkpoint.pth.tar
2023-12-08 13:21:28,701 - 

................


2023-12-08 15:44:14,170 - Training epoch: 7011 samples (240 per mini-batch)
2023-12-08 15:44:48,694 - Epoch: [99][   10/   30]    Overall Loss 1.120448    Objective Loss 1.120448                                        LR 0.000200    Time 3.452330    
2023-12-08 15:45:01,504 - Epoch: [99][   20/   30]    Overall Loss 1.088512    Objective Loss 1.088512                                        LR 0.000200    Time 2.366598    
2023-12-08 15:45:17,432 - Epoch: [99][   30/   30]    Overall Loss 1.079984    Objective Loss 1.079984    Top1 64.604811    Top5 95.876289    LR 0.000200    Time 2.108631    
2023-12-08 15:45:17,882 - --- validate (epoch=99)-----------
2023-12-08 15:45:17,882 - 779 samples (240 per mini-batch)
2023-12-08 15:45:41,735 - Epoch: [99][    4/    4]    Loss 1.341696    Top1 53.016688    Top5 88.703466    
2023-12-08 15:45:42,193 - ==> Top1: 53.017    Top5: 88.703    Loss: 1.342

2023-12-08 15:45:42,194 - ==> Best [Top1: 55.712   Top5: 88.447   Sparsity:0.00   Params: 68015 on epoch: 86]
2023-12-08 15:45:42,195 - Saving checkpoint to: logs\2023.12.08-131828\qat_checkpoint.pth.tar
2023-12-08 15:45:42,209 - --- test ---------------------
2023-12-08 15:45:42,209 - 757 samples (240 per mini-batch)
2023-12-08 15:46:01,734 - Test: [    4/    4]    Loss 1.527895    Top1 51.387054    Top5 88.375165    
2023-12-08 15:46:02,194 - ==> Top1: 51.387    Top5: 88.375    Loss: 1.528

2023-12-08 15:46:02,198 - 
2023-12-08 15:46:02,198 - Log file for this run: D:\MAX7800\12sx\shenxiao\ai8x-training\logs\2023.12.08-131828\2023.12.08-131828.log

可以看到,经过训练在测试集上的Top1准确率可以达到51%,Top5准确率可以达到88%,说明网络可以对十二生肖图片进行较为有效的识别。

训练结束之后,训练结果会被保存在ai8x-training/logs下,以便于查看训练记录找到训练记录。

4.4 模型量化

       为了让模型成功部署在MAX78000上,需要对模型的网络参数进行量化,对于中间层每个参数以2bit量化,两边层用4bit或者8bit量化,首先需要将训练好的模型qat_best.pth.tar从ai8x-training/logs目录下拷贝到ai8x-synthesis/trained目录下,并把名字改成ai8x-shenxiao-qat8.pth.tar。训练结果中的qat_best.pth.tar模型是保存的最好的训练结果,并且是在训练时被量化的结果,经过实验验证,使用这个模型来量化能得到最好的量化结果。

FiZWkp_0nXsSjrXjkbin6JKzpMNI

图4-3 qat_best.pth.tar位置图

然后再在pycharm打开ai8x-synthesis文件夹,在终端中运行以下代码实现模型量化,具体量化脚本如下:

python quantize.py trained/ai8x-shenxiao-qat8.pth.tar trained/ai8x-shenxiao-qat8-q.pth.tar --device MAX78000 -v

量化完成的结果如下:

FrHVPHUBZ96OfuitRHHq-WHM68Kw

图4-4 量化完成结果图

完成这一步之后会在ai8x-synthesis/trained目录下生成一个文件ai8x-shenxiao-qat8-q.pth.tar。

4.5 模型评估

在pycharm打开ai8x-training文件夹,输入以下代码进行模型评估,具体评估脚本如下:

python train.py --model ai85net_shenxiao --dataset shenxiao --confusion --evaluate --exp-load-weights-from ../ai8x-synthesis/trained/ai8x-shenxiao-qat8-q.pth.tar -8 --device MAX78000

模型评估结果如下图所示:

FqIY9Onf9BCXf0eIX1B9M7mw-_Yo

图4-5 模型评估结果图

测试精度与训练时的测试结果差别不大,说明模型大体上满足要求。

4.6 模型转换

模型量化后,我的下一个目标是把原本的模型转化成可以在MAX78000上运行的c语言代码,生成该项目主要需要三个文件:量化后的模型, 测试样本文件和网络描述文件。我已经在之前得到了量化后的模型,接下来得到测试样本文件和网络描述文件就可以实现模型转化。

生成测试样本文件:

还是在pycharm打开ai8x-training文件夹,首先需要进行测试样本生成,在终端中输入以下指令生成的测试样本用于模型转换的时候生成MAX78000的测试工程。生成测试样本的具体脚本如下:

python ./train.py --model ai85net_shenxiao --save-sample 10 --dataset shenxiao --evaluate --exp-load-weights-from ../ai8x-synthesis/trained/ai8x-shenxiao-qat8-q.pth.tar -8 --device MAX78000

测试样本生成的结果如下图所示:

Fn93_43yt37Nwqv8G-0xt06u2eof

图4-6 测试样本生成结果图

把生成的样本文件sample_shenxiao.npy移动到ai8x-synthesis/tests目录中去。

编写网络描述文件:

之后在pycharm打开ai8x-synthesis文件夹,在ai8x-synthesis/networks目录下新建一个文件shenxiao.yaml,指定编辑描述网络的yaml文件,该文件的编写方法可以参考:https://github.com/MaximIntegratedAI/MaximAI_Documentation/blob/master/Guides/YAML%20Quickstart.md,具体编辑内容如下:

---
# HWC (big data) configuration for Cats and Dogs image classification

arch: ai85net_shenxiao
dataset: shenxiao

# Define layer parameters in order of the layer sequence
layers:
  - pad: 1
    activate: ReLU
    out_offset: 0x1000
    processors: 0x0000000000000007
    data_format: HWC
    operation: Conv2d
    streaming: true
  - max_pool: 2
    pool_stride: 2
    pad: 1
    activate: ReLU
    out_offset: 0x2000
    processors: 0x000ffff000000000
    operation: Conv2d
    streaming: true
  - max_pool: 2
    pool_stride: 2
    pad: 1
    activate: ReLU
    out_offset: 0x0000
    processors: 0x00000000ffffffff
    operation: Conv2d
  - max_pool: 2
    pool_stride: 2
    pad: 1
    activate: ReLU
    out_offset: 0x2000
    processors: 0xffffffffffffffff
    operation: Conv2d
  - max_pool: 2
    pool_stride: 2
    pad: 1
    activate: ReLU
    out_offset: 0x0000
    processors: 0x00000000ffffffff
    operation: Conv2d
  - pad: 1
    activate: ReLU
    out_offset: 0x2000
    processors: 0xffffffff00000000
    operation: Conv2d
  - op: mlp
    flatten: true
    out_offset: 0x1000
    output_width: 32
    processors: 0x000000000000ffff
    activate: None

得到了输入样本文件和网络描述文件后,就可以进行模型转换了。

在pycharm打开ai8x-synthesis文件夹,在终端输入以下代码即可实现模型转换。具体模型转换脚本如下:

python ./ai8xize.py --verbose --test-dir demos --prefix ai8x-shenxiao --checkpoint-file trained/ai8x-shenxiao-qat8-q.pth.tar --config-file networks/shenxiao.yaml --device MAX78000 --compact-data --mexpress --softmax --fifo --sample-input tests/sample_shenxiao.npy --overwrite

模型转换生成模型代码以及测试Demo工程的结果如下图所示:

FqqFrOdJWXDpGWfwZekBM0p48Om5

图4-7 模型转换结果图

4.7 demo模型代码烧录

在进行上一步模型转换之后,可在ai8x-synthesis\demos\ai8x-shenxiao目录下找到自动生成的项目,该项目可以通过vscode直接下载到MAX78000中,当我们打开vscode,打开ai8x-synthesis\demos\ai8x-shenxiao目录,在电脑连接了MAX78000的情况下,按shift+ctrl+B,即可打开以下列表。如下如图所示:

Fr-fxGH1vcZWTdwotfCAWHFFz-7o

图4-8 烧录列表图

其中clean是清理文件,build是生成文件,flash&run是烧录并运行程序,依次进行这三步,即可完成代码烧录,为将输入样本送给网络得到输出,并通过串口打印结果。

至此,我们得到了可以部署在MAX78000上的十二生肖模型,完成了十二生肖分类的任务。但该模型只会对固定的输入样本进行分类,不能实现我们所需要的现实中检测的功能。所以接下来就需要实现在现实中检测的功能。

4.8 编写图像采集代码

为实现能够在现实中进行十二生肖检测的功能,待分类的十二生肖图片应该由MAX78000的板载摄像头直接采集,而并非像之前的demo那样直接写进代码中,因此我们需要编写图像采集代码。图像采集代码主要参考了官方提供的例程cats-dogs_demo,该例程包含了相机模块初始化、拍照、图像处理和导入模型等步骤,正好符合要求。

我们首先把之前生成的ai8x-synthesis\demos\ai8x-shenxiao目录下的除了main.c和project.mk的文件全部复制,粘贴替换到MSDK\Examples\MAX78000\CNN\cats-dogs_demo目录下,再把cats-dogs_demo文件夹改名成ai8x-shenxiao。此时main.c中就包含了图像采集所需要的capture_process_camera()函数和cnn_load_input()函数,其中capture_process_camera()函数)负责逐行读取图像、将图像转换为0x00bbggrr格式提供给模型作为输入、将图像转换为RGB565格式提供给TFT显示屏模块进行显示等操作,cnn_load_input()函数负责把图像导入进模型中。

4.9 编写图像显示代码

为了实现在显示屏上显示图像,我们需要用vscode打开MSDK\Examples\MAX78000\CNN\ai8x-shenxiao文件夹,根据自己的模型对main.c,settings.json,project.mk进行更新与编写,具体更新代码如下所示:

//工程vscode配置文件 :vscode/settings.json

    "target":"MAX78000",
    "board":"FTHR_RevA",

//工程配置文件:project.mk

BOARD=FTHR_RevA

//主程序设置RESET、BLK控制引脚:main.c

#ifdef BOARD_FTHR_REVA
#ifdef ENABLE_TFT
    /* Initialize TFT display */
    mxc_gpio_cfg_t tft_reset_pin = {MXC_GPIO0, MXC_GPIO_PIN_19, MXC_GPIO_FUNC_OUT, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH};
    mxc_gpio_cfg_t tft_blen_pin = {MXC_GPIO0, MXC_GPIO_PIN_9, MXC_GPIO_FUNC_OUT, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH};
    MXC_TFT_Init(MXC_SPI0, 1, &tft_reset_pin, &tft_blen_pin);
    // MXC_TFT_Init(MXC_SPI0, 1, NULL, NULL);
    TFT_Feather_test();
#endif
#endif // #ifdef BOARD_FTHR_REVA

 

更新完成后,按照电路连线图连接MAX78000和显示屏,最后再和上步demo烧录过程一样,在vscode中打开MSDK\Examples\MAX78000\CNN\ai8x-shenxiao文件夹烧录即可。烧录结果如下:

FjnVvstxkH-nqGxolAqt32B-TFgw

图4-9 十二生肖检测模型烧录图

       实现启动之后会显示作品信息,按下SW1开始启动十二生肖检测器识别摄像头采集到的图片中的生肖,软件采用实时刷新,摄像头会一直采集图像信息,再次按下SW1后会停止采集图像然后对当前图像进行检测,并通过LCD显示出现相似度最高的类别的生肖;相似率前五名的生肖会显示在LCD屏最右部分;再次按下SW1,摄像头会继续采集图像信息,并清除右侧的生肖相似率。

具体的main.c代码过长,便放置在文章末尾的整合包中。

4.9 硬件连接

本项目使用的显示屏为ILI9341驱动的TFT LCD显示屏,分辨率为240×320,使用SPI协议与MAX78000进行通讯。显示屏和MAX78000的具体连接方式如下图所示:

FsAWQ1PAUvUIGc9bWR81JHGH0TOM

图4-10 电路连接图

5.实验结果展示:

FvuGJ06_v1iLkcIsQUzEsRd365CaFqy_EgYFNAD-I7LXGXUcfEKPI7IeFp6Ukv_yZSgoaqaNbT32bnRlRFYXFmbS_KfZCOZW6N_M1WPYn6nnHYwZFlb7y0qEekYoP2yjE1bXYIZAWs4NFufd7qTktwDN2Z-wR2MAbMyQpiU_

FrMRYRbHGCF3Wo3c5epK16e_M4w4

6.遇到的问题以及解决方法:

6.1 GitHub网页加载错误

解决方法:使用科学上网

6.2 下载ai8x_training的支持包出错,没有Microsoft C++

FgY4SE0CDdE_Dni52g6v88pbfxOL

图6-1 ai8x_training的支持包出错图

解决方法:打开红框中的网址:https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/,下载Microsoft C++生成工具,具体安装流程参考:https://blog.csdn.net/xianjianwu1/article/details/129908678

6.3 训练无后续,无法继续进行训练

FkK1uk_k-Rw0ERR4Incfbu3j91nB

图6-2 训练卡住无后续

解决方法:cpu和gpu的python第三方库有冲突,不要两个同时安装。重新安装虚拟环境即可。

6.4 无法点亮显示屏

解决方法:对main.c,settings.json,project.mk进行更新与编写,正确编写RESET,BLK引脚的相关代码,并对MAX78000和显示屏正确连线。

6.5 识别准确率问题

本次使用了多种网络模型进行十二生肖检测的训练,但是由于十二生肖中动物的种类和外观形象过多,导致训练效果都不太理想,此外由MAX78000板载摄像头所拍摄到的图片画面颜色相比数据集中的图片和实际画面有较大差异,清晰度也较差,导致模型有时无法准确识别拍摄图片中的生肖。

解决办法:调整网络架构,继续寻找更加适合十二生肖检测的模型,对MAX78000拍摄到的图像进行处理,可以使用直方图均衡等方法突出特征,便于模型检测。

7.总结

        我在这次的比赛之中收益匪浅,这是我第一次使用嵌入式AI开发板,也是我第一次个人完整的进行全流程的ai训练与单片机运行。在人工智能领域中,我还是一个小白,虽然这次ai的训练成果不是非常理想,直到时间截至,我也依旧没有找到我想要的最佳检测结果,但是,在这次比赛中,我依旧被ai的魅力深深折服,我非常感谢官方提供的丰富板卡相关说明与例程,以及每一位参赛者在比赛中对我的帮助,没有这一双双援手,我无法走到最后一步,无法完成这次比赛,对此我再次表示我的感激之情。这次比赛,我看到了ai和单片机相互结合所产生的美妙火花,看到了单片机全新的未来,相信在未来,ai一定会越来越好,我也会继续努力,不断追赶时代前进的浪潮。

       最后感谢电子森林,Maxim硬禾与ADI给予的这次机会,希望Maxim能够继续将边缘计算发扬光大,做大做强!

附件下载
ai8x-shenxiao.rar
MAX78000 vscode工程文件
团队介绍
成员:空白blank,独立完成该项目,刚踏入人工智能领域不久,虽然还是小白,但对人工智能领域有着很高的热情,希望不断追赶上ai发展的步伐。
团队成员
空白blank
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号