一、项目介绍
本项目使用MAX78000FTHR开发板,调用板载摄像头采集水/天燃气机械表头的图像,显示在分辨率320*240的2.4寸TFT屏幕上,并通过MAX78000的低功耗卷积神经网络加速器实现AI判断读取图片中的数字。
二、项目设计思路
考虑到人机交互,本次项目的屏幕使用中景园电子的2.4寸带电阻触摸的TFT屏幕,使用XPT2046触摸IC驱动触摸屏,添加了中文字库GAL30L32S4W,使用MAX78000的SPI接口驱动,通过三个片选引脚切换控制的器件。
三、搜集素材思路
通过Pytorch训练模型,使用MNIST数据集学习AI识别数字,MNIST是手写数字数据库,它有60000个训练样本集和10000个测试样本集,每个样本图像的宽高为28*28。
四、预训练实现过程
1. 数据集准备:利用torchvision下载数据集。包括了训练数据集和测试数据集,对60000个图像进行分批操作,每批包含10张图像。代码如下:
import torch
from torchvision import transforms
from torchvision.datasets import MNIST
# MNIST
def mnist(batch_sz):
transform_train = transforms.Compose([
transforms.RandomCrop(28),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),])
transform_test = transforms.Compose([
transforms.ToTensor(),])
# Training dataset
train_data = MNIST(root='./datasets', train=True, download=True, transform=transform_train)
train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_sz, drop_last=True)
# Test dataset
test_data = MNIST(root='./datasets', train=False, download=True, transform=transform_test)
test_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_sz, drop_last=True)
return train_loader, test_loader
train_loader,test_loader=mnist(10)
2. 神经网络配置:设计一个4层神经网络有,第一层的输入数量为 28*28,第二层为200,第三层为100,最后一层为10,对于0到9一共10个数字,代码如下:
import torch
import torch.nn as nn
import torch.optim as optim
import torch.functional as F
class Net(nn.Module):
def __init__(self):
super().__init__()
self.linear1=nn.Linear(28*28,200)
self.linear2=nn.Linear(200,100)
self.linear3=nn.Linear(100,10)
def forward(self,x):
x=x.view(-1,28*28)
x=torch.relu(self.linear1(x))
x=torch.relu(self.linear2(x))
x=torch.sigmoid(self.linear3(x))
return x
3. 训练参数配置:使用pytorch中的nn. CrossEntropyLoss ()作为损失函数,学习率设置为0.01,虽然图像是二维的,每个维度有 28 个像素,但pytorch中的.view方法可将这些像素变换成一个维度,然后将数据传递给神经网络的第一层,代码如下:
import matplotlib.pyplot as plt
device=torch.device("cuda:0")
net=Net()
net=net.to(device)
optimizer=optim.SGD(net.parameters(),lr=0.01)
less_func=nn.CrossEntropyLoss()
ls=[]
for i in range(50):
loss_total=0
for batch in train_loader:
x=batch[0].to(device)
y=batch[1].to(device)
yhat=net(x)
loss=less_func(yhat,y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
loss_total=loss_total+loss.item()
ls.append(loss_total)
plt.plot(ls)
4. 训练迭代效果:使用Google Colab进行训练,总共迭代50次,测试数据集的准确率在95%左右。
5. 测试数据集识别效果:通过下图可以看出10个数字正确识别了9个,后续可通过优化网络层数以及神经元数量,提高迭代次数,继续提高准确率。
五、总结项目进展
1. 目前使用面包板和杜邦线连接了MCU和屏幕,后期准备绘制PCB将连接变得更美观,加上可以控制的补光灯,引出额外按键方便摄像头单次采集数据。
2. 外设控制方面主要研究了摄像头、DMA、SPI等,主要参考了CameraIF和kws20_demo这两个例程,后期还需要继续学习CNN模型训练和MAX78000外设的使用。
3. CNN训练方面目前测试数据集的准确率在95%左右,之后还需设计方法分离水/电表的各个数字,并且提高识别的准确率。