undo110

  • 2024-05-31
  • 回复了主题帖: 【AI挑战营终点站】应用落地:部署手写数字识别应用到幸狐RV1106开发板

    先打卡 #AI挑战营终点站#在LuckFox Pico Pro/Max上初步实现手写数字识别 - 嵌入式系统 - 电子工程世界-论坛 (eeworld.com.cn)

  • 发表了主题帖: #AI挑战第二站#将onnx转为rknn

    ONNX(Open Neural Network Exchange),开放神经网络交换,是一种开发的模型格式,而RKNN是rockchip的模型格式。LuckFox Pico 搭载了NPU(Nerual Processing Unit)。为了在此上运行需要对原有onnx进行转换为rknn。   在这里,根据官方给出的RKNN 的pdfrknn-toolkit2/doc/01_Rockchip_RV1106_RV1103_Quick_Start_RKNN_SDK_V2.0.0beta0_CN.pdf at master · airockchip/rknn-toolkit2 (github.com)以及使用学习官方涉及转换rknn的案例:RKNN 推理测试 | LUCKFOX WIKI,进行学习。   ·下载tookit git clone https://github.com/airockchip/rknn-toolkit2.git ·下载 RKNN Model Zoo git clone https://github.com/airockchip/rknn_model_zoo.git ·配置conda wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-4.6.14-Linux-x86_64.sh ·需要授权安装包 chmod 777 Miniconda3-4.6.14-Linux-x86_64.sh bash Miniconda3-4.6.14-Linux-x86_64.sh ·新建conda环境并激活 # 创建RKNN-Toolkit2 conda create -n RKNN-Toolkit2 python=3.8 # 启动 conda activate RKNN-Toolkit2 ·进入rknn-toolkit2安装toolkit2以及依赖库: 根据github上的pdf先安装requirement会报错,查看官方案例是先需要安装依赖tf-estimator-nightly pip install -I https://pupi.doubanio.com/simple/ tf-estimator-nightly==2.8.0.dev2021122109 然后再 pip install -r packages/requirements_cp38.txt ·安装对应的whl pip install packages/rknn_toolkit2-2.0.0b0+9bab5682-cp38-cp38-linux_x86_64.whl   接下来就按照官方文档给出的案例RKNN 推理测试 | LUCKFOX WIKI 进入到zoo下的yolov5/yolov5s.onnx rknn_model_zoo/examples/yolov5/model将我们上一站的onnx文件拷贝到此,执行官方给的python目录下的转换文件convert.py。可修改convert,设置输入输出文件,无需传送参。 涉及修改如下: # 注释传入参数 # My onnx's path model_path = './my_model.onnx' DATASET_PATH = './dataset.txt' # 设置输出 output_path = './my_model.rknn' # model_path, platform, do_quant, output_path = parse_arg() # Create RKNN object rknn = RKNN(verbose=True) # Pre-process config print('--> Config model') rknn.config(mean_values=[[28]], std_values=[ [28]], target_platform=platform) print('done') # Load model print('--> Loading model') ret = rknn.load_onnx(model=model_path) if ret != 0: print('Load model failed!') exit(ret) print('done') # Export rknn model print('--> Export rknn model') ret = rknn.export_rknn(output_path) if ret != 0: print('Export rknn model failed!') exit(ret) print('done') # Release rknn.release() 注意需要模仿yolov5/ COCO中的dataset格式,在此目录下新建dataset.txt 得到输出的rknn模型。  

  • 2024-05-30
  • 发表了主题帖: #AI挑战营终点站#在LuckFox Pico Pro/Max上初步实现手写数字识别

    本帖最后由 undo110 于 2024-5-31 20:08 编辑 1,点亮板子 参考官方的上手教程:上手教程 | LUCKFOX WIKI 主要: 1)安装RK驱动助手 2)镜像下载与烧录。从官方的百度盘中找到pro max版,使用文档给出的烧录工具SocToolkit进行。注意事项:需要先按住boot键再插usb,才能松开。然后就是选择对应版本文件下的所有文件进行download。   3)ssh登录。直接插上usb使用静态IP登录。pro max默认启用了ssh,可登录默认账户密码与静态ip。在powershell中 ssh root@172.32.0.93 ,输入密码luckfox,即可登录。 4)点亮摄像头。安装文档给出示意图进行安装。注意事项:排线带子的插口处的塑料需要轻轻挑起,塞入带子再按紧。成功识别摄像头会生成在板子的/userdata/中生成 rkipc.ini 文件。     然后就是配置RNDIS虚拟接口与使用VLC media player查看摄像头。 官方文档很细致,弄下来无出现奇奇怪怪的问题。     2,部署SDK并编译 参照官方文档进行SDK部署。一开始想体验一下docker来进行部署,后续出现一连串奇奇怪怪的问题,分析不出问题出现在哪,就选择Ubuntu22.04环境下进行编译镜像。 1)获取完官方的SDK: git clone https://gitee.com/LuckfoxTECH/luckfox-pico.git 2)Buildroot 镜像既支持TF卡启动又支持 SPI NAND FLASH 启动,修改 'BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Pro_Max-IPC.mk' 的为: export LF_TARGET_ROOTFS=buildroot 3)安装交叉编译工具链:进入tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf发现有文件env_install_toolchain.sh,可在次此文件打开终端,输入 source env_install_toolchain.sh 可输入以下命令,出现以下信息来确定已配置:   4)开始编译镜像: cd luckfox-pico #编译busybox/buildroot ./build.sh lunch ./build.sh   5)手写数字识别 由于本菜鸡太太太太菜了,刚接触这个邻域,对官方给出的案例代码大多看不懂,跟着大佬的代码先进行学习,这里使用knv大神的https://github.com/knva/luckfox_pico_rtsp_opencv代码部分,根据佬的readme来进行下一步的编译,output出可执行文件luckfox_rtsp_opencv。接下来部署到板子上。 mkdir build cd build cmake .. make && make install   3,传送文件到板子 这一步使用sftp将上一步output的可执行文件,bin文件夹。以及上一轮活动转换的rknn文件传送到板子上。 1)首先 ssh root@172.32.0.93登录,在输入exit退出 2)再sftp登录,这时可使用sftp登录了,直接sftp root@172.32.0.93输入密码登录 3)将上面的luckfox_rtsp_opencv,bin文件夹,以及转换格式后的rknn在本地打包为project文件夹,在put -r project到板子上 ,使用ls命令检查到已接受到,然后exit 4,授权启动 ssh登录板子,切换到刚传送的文件夹, 首先停用: RkLunch-stop.sh 然后启动: ./luck_rtsp_opencv my_model.rknn 若出现:Permission denied 则需要授权 使用命令: chmod 777 luck_rtsp_opencv 进行授权后再启动。 使用vlc查看摄像头     可以看到摄像头成功进行照片获取,并对手写数字进行初步识别   5,(待完成)后续计划改进方向: 从上面的测试可以看出,画面出现多个数字时,目前的代码只能锁定其中一个数字,并进行识别。所以后续计划是:在一个画面中实现多个数字进行识别。   因基础薄弱,短时间内无法从哪里开始修改。接下来先对官方的案例代码和大佬的改进代码进行分析学习,清楚后再改进。   官方案例分析:luckfox-eng29/luckfox_pico_rtsp_opencv (github.com) 其中的main.cc: 前面的是一些基本的声明: // 定义坐标和图像宽高 int sX, sY, eX, eY; int width = 2304; int height = 1296; // 初始化帧率文本 char fps_text[16]; float fps = 0; memset(fps_text, 0, 16); while循环中应该是在视频中的处理,也是需要主要学习、分析的代码: while (1) { // 获取VPSS通道帧 s32Ret = RK_MPI_VPSS_GetChnFrame(0, 0, &stVpssFrame, -1); if (s32Ret == RK_SUCCESS) { void *data = RK_MPI_MB_Handle2VirAddr(stVpssFrame.stVFrame.pMbBlk); // 使用OpenCV将数据转换为Mat对象进行处理 cv::Mat frame(height, width, CV_8UC3, data); // 在帧上绘制帧率信息 sprintf(fps_text, "fps = %.2f", fps); cv::putText(frame, fps_text, cv::Point(40, 40), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0), 2); // 将处理后的数据拷贝回原数据缓冲区 memcpy(data, frame.data, width * height * 3); } // 发送视频流 RK_MPI_VENC_SendFrame(0, &stVpssFrame, -1); // 从编码器获取视频流 s32Ret = RK_MPI_VENC_GetStream(0, &stFrame, -1); if (s32Ret == RK_SUCCESS) { // 如果RTSP服务器和会话有效,发送视频数据 if (g_rtsplive && g_rtsp_session) { // 获取编码后的数据的虚拟地址 void *pData = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk); // 通过RTSP发送视频数据 rtsp_tx_video(g_rtsp_session, (uint8_t *)pData, stFrame.pstPack->u32Len, stFrame.pstPack->u64PTS); // 处理RTSP事件 rtsp_do_event(g_rtsplive); } // 获取当前时间 RK_U64 nowUs = TEST_COMM_GetNowUs(); // 计算帧率 fps = (float)1000000 / (float)(nowUs - stVpssFrame.stVFrame.u64PTS); } // 释放VPSS通道帧 s32Ret = RK_MPI_VPSS_ReleaseChnFrame(0, 0, &stVpssFrame); if (s32Ret != RK_SUCCESS) { RK_LOGE("RK_MPI_VI_ReleaseChnFrame fail %x", s32Ret); } // 释放编码器获取的视频流 s32Ret = RK_MPI_VENC_ReleaseStream(0, &stFrame); if (s32Ret != RK_SUCCESS) { RK_LOGE("RK_MPI_VENC_ReleaseStream fail %x", s32Ret); } } (待完成)knv大佬的的示例分析: (待完成)拟改进思路:

  • 2024-05-29
  • 回复了主题帖: #AI挑战营第二站#安装RKNN TOOlkit2工具转换ONNX模型 为RKNN的模型

    学习了

  • 2024-05-26
  • 回复了主题帖: 【AI挑战营终点站】Luckfox Pico开发板开箱及初上手

    赞!老哥的帖很nice,对官方文档精炼和梳理,很适合小白入门。官方的文档很细致。

  • 2024-05-08
  • 回复了主题帖: 入围名单公布:嵌入式工程师AI挑战营(初阶),获RV1106 Linux 板+摄像头的名单

    本帖最后由 undo110 于 2024-5-9 20:35 编辑 个人信息已确认,领取板卡,可继续完成&分享挑战营第二站和第三站任务。

  • 2024-04-13
  • 回复了主题帖: 【AI挑战营第一站】模型训练:在PC上完成手写数字模型训练,免费申请RV1106开发板

    1,模型训练的底层是在不断调整参数,使得参数的组合契合所需训练的事物。训练的结果是得到反应事物特征的参数与对应的f(x),从而可根据函数做预测。 2,PyTorch 是一个深度学习框架,PyTorch 支持多种神经网络架构,从简单的线性回归算法到复杂的卷积神经网络。目前支持Windows、iOS、Android 和 Linux,允许开发者将训练好的模型部署到移动设备上。支持:cpu,NVIDIA GPU,AMD GPU,TPU. 3,手写数字pytorch实践:#AI挑战营第一站#手写数字MNIST识别实验记录 https://bbs.eeworld.com.cn/thread-1277457-1-1.html

  • 发表了主题帖: #AI挑战营第一站#手写数字MNIST识别实验记录

    本帖最后由 undo110 于 2024-4-13 00:57 编辑 因为需要使用到MNIST中手写数字的数据集,而该数据集中每张图片的大小为28x28,所以需要输入数据的维度需要设置为784。同时,我们需要识别的数字为0~9,需将输出层设为10个。应题目要求,中间层神经元数量设为15。 MNIST数据集,选择直接从pytorch包中所带的dataset数据集中导入。将数据集分为训练和测试两部分。在训练过程中,需要加入BP算法来对调整网络的权重。而,在测试过程中,则不再需要反向传播。 使用pytorch包来构建三层神经网络,使用的是ReLU激活函数,交叉熵损失函数。 同时基于个人电脑配置,将设置迭代训练次数为10次,同时精确度也已经得到很好的收敛。 代码实现 from torchvision.datasets import mnist import torchvision.transforms as transforms from torch.utils.data import DataLoader from torch import nn import torch.optim as optim meta_size = 70  # 限定每次从数据集中取出数量,为70 epoches = 10 lr = 0.01       # 设置超参数学习率为0.01 momentum = 0.5 # 数据 预处理Compose方法即是将两个操作合并一起 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize([0.1307], [0.3081])]) # 下载数据集 train_dataset = mnist.MNIST('mnist', train=True, transform=transform, download=True) # 非训练集,train参数设为False test_dataset = mnist.MNIST('mnist', train=False, transform=transform, download=True) # dataloader是可迭代对象,迭代取出大小meta-size train_loader = DataLoader(train_dataset, batch_size=meta_size, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=meta_size, shuffle=False) # 定义三层神经网络 # 因为需要使用到MNIST中手写数字的数据集,而该数据集中每张图片的大小为# 28x28,所以需要输入数据的维度需要设置为784。同时,我们需要识别的数     # 字为0~9,需将输出层设为10个。应题目要求,中间层神经元数量设为15。 class Net(nn.Module):     def __init__(self):         super(Net, self).__init__()         self.layer1 = nn.Sequential(nn.Linear(784, 784), nn.ReLU(True))  #使用ReLU激活函数         self.layer2 = nn.Sequential(nn.Linear(784, 15), nn.ReLU(True))         self.layer3 = nn.Linear(15, 10)     def forward(self, x):         x = self.layer1(x)         x = self.layer2(x)         x = self.layer3(x)         return x model = Net() # 定义模型训练中用到的损失函数和优化器 criterion = nn.CrossEntropyLoss()  # 交叉熵损失函数 optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum) train_losses = []  # 记录训练集损失 train_acces = []  # 用于收集训练集准确率 test_losses = []  # 收集测试集损失 test_acces = []  # 收集每次测试集准确率 for epoch in range(epoches):     train_loss = 0     train_acc = 0     model.train()  # model的训练过程     for img, label in train_loader:         img = img.view(img.size(0), -1)  # 把输入图像转化为2维         # 前向传播         out = model(img)         loss = criterion(out, label)         # 反向传播         optimizer.zero_grad()         loss.backward()         optimizer.step()         train_loss += loss.item()  # 所有批次损失的和         # 计算分类的准确率         _, pred = out.max(1)         num_correct = (pred == label).sum().item()         acc = num_correct / img.shape[0]  # 每一批样本的准确率         train_acc += acc     train_losses.append(train_loss / len(train_loader))  # 所有样本平均损失     train_acces.append(train_acc / len(train_loader))  # 所有样本的平均准确率     # 测试     test_loss = 0     test_acc = 0     # 将模型改为预测模式 # 在训练过程中,需要加入BP算法来对调整网络的权重。而,在测试过程   # 中,则不再需要反向传播。     model.eval()     for img, label in test_loader:         img = img.view(img.size(0), -1)         out = model(img)         loss = criterion(out, label)         test_loss += loss.item()         _, pred = out.max(1)         num_correct = (pred == label).sum().item()         acc = num_correct / img.shape[0]         test_acc += acc     test_losses.append(test_loss / len(test_loader))     test_acces.append(test_acc / len(test_loader))     print('轮次: {}, 训练损失: {:.4f}, 训练准确率: {:.4f}, 测试损失: {:.4f}, 测试准确率: {:.4f}'           .format(epoch, train_loss / len(train_loader), train_acc / len(train_loader),                   test_loss / len(test_loader), test_acc / len(test_loader)))     实验结果     导出文件:  

最近访客

< 1/1 >

统计信息

已有7人来访过

  • 芯积分:38
  • 好友:--
  • 主题:3
  • 回复:5

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言