实战检验:Orange Pi AIpro AI开发板的性能测试与使用体验

news2024/9/22 15:35:21

文章目录

  • 前言
  • Orange Pi AIpro 简介
  • Orange Pi AIpro 体验
    • 将Linux镜像烧录到TF卡
    • YOLO识别视频中物体
    • 肺部CT识别
  • Orange Pi AIpro 总结


前言

Orange Pi AIpro,作为首款基于昇腾技术的AI开发板,它集成了高性能图形处理器,配备8GB/16GB LPDDR4X内存,支持外接存储模块,并具备双4K高清输出和强大的AI算力。

Orange Pi AIpro 简介

怀着迫不及待的打开了我们的Orange Pi AIpro,外观十分漂亮,映入眼帘的就是一个橙子的标志和为AI而生

在这里插入图片描述
整个板子的包裹性还是很好的,有一个盒子(里面都是海绵),板子外面还有一层塑料袋包裹着,大赞

在这里插入图片描述
整个板子的精密程度,以及它的美观程度都是很赞的,满满的科技感,爱不释手。
在这里插入图片描述

该开发板拥有丰富的接口,包括HDMI、GPIO、Type-C电源、M.2插槽、USB等,香橙派对应部分产品规格:

部件参数
CPU4核64位处理器+ AI处理器
GPU集成图形处理器
AI算力8-12TOPS算力
内存LPDDR4X:8GB/16GB(可选),速率:3200Mbps
存储SPI FLASH:32MB• SATA/NVME SSD(M.2接口2280);eMMC插槽:32GB/64GB/128GB/256GB(可选),eMMC5.1 HS400;TF插槽
WIFI+蓝牙Wi-Fi 5双频2.4G和5G;BT4.2/BLE
以太网收发器10/100/1000Mbps以太网
显示2xHDMI2.0 Type-A TX 4K@60FPS;1x2 lane MIPI DSI via FPC connector
摄像头2x2-lane MIPI CSI camera interface,兼容树莓派摄像头

我们可以官方给我们提供的接口详情图:
在这里插入图片描述
在这里插入图片描述
可以看到是堆料满满的一款产品,昇腾AI处理器是为了满足飞速发展的深度神经网络对芯片算力的需求,由华为公司在2018年推出的AI处理器,对整型数(INT8、INT4)或浮点数(FP16)提供了强大高效的计算力,在硬件结构上对深度神经网络做了优化,可以很高效率完成神经网络中的前向计算因此在智能终端领域有很大的应用前景。

Orange Pi AIpro 体验

将Linux镜像烧录到TF卡

打开香橙派官网:香橙派官网
在这里插入图片描述
选择我们对应的产品,我们可以根据自己的需求去下载官方的资料或者去下载官方的镜像,我们这里直接去下载ubuntu镜像
在这里插入图片描述
我们会跟着指示来到百度网盘,然后选择desktop的进行下载。
因为desktop镜像预装Linux桌面、CANN、AI 示例代码等,minimal镜像不包括上述内容
在这里插入图片描述
经过耐心等待,终于下载完成了
在这里插入图片描述

下载balenaEtcher:balenaEtcher官网,点击Download Etcher,
在这里插入图片描述
我们选择对应版本下载即可
在这里插入图片描述
我们将我们的TF卡插入读卡器中,接入电脑中,准备烧录
在这里插入图片描述
我们将我们下载好的balenaEtcher打开,选择聪文件烧录
在这里插入图片描述
我们选择好对应配置后,点击现在烧录!
在这里插入图片描述
当我们看到左边为紫色进度条时,证明我们正在烧录中
在这里插入图片描述
当我们看到左边为绿色进度条时,证明正在验证是否烧录成功中
在这里插入图片描述

YOLO识别视频中物体

我们首先打开连接上显示器,默认账号密码为:用户为HwHiAiUser,登录密码为Mind@123
在这里插入图片描述
我们右上角连接上WIFI

在这里插入图片描述
我们总共32G,操作系统预装了Ubuntu-22.04。系统本身加上预装的开发软件占用了大概17G的空间,剩余15G左右的空间。

HwHiAiUser@orangepiaipro:~$ cd samples
HwHiAiUser@orangepiaipro:~/samples$ ./start_notebook.sh

执行脚本之后,终端中会打印出Jupyter Lab的网址连接,我们将其复制去游览器打开即可
在这里插入图片描述
我们选择yolov5,然后选择main.ipynb,点击运行
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
我们运行完结果可以发现基本可以识别我们图片中的汽车,除了完全覆盖的没有识别到,也算正常。

我们在整个运行过程中,我们的风扇转速算不错了,散热效果比较好,拿起板子基本是一个常温的状态,没有发热的情况。
在这里插入图片描述

肺部CT识别

我们再来开发板运行一个项目:

import math
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.model_zoo as model_zoo
from torch.nn import init
import torch

__all__ = ['xception']

model_urls = {
    'xception': 'http://data.lip6.fr/cadene/pretrainedmodels/xception-43020ad28.pth'
}


class SeparableConv2d(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=1, stride=1, padding=0, dilation=1, bias=False):
        super(SeparableConv2d, self).__init__()

        self.conv1 = nn.Conv2d(in_channels, in_channels, kernel_size, stride, padding, dilation, groups=in_channels,
                               bias=bias)
        self.pointwise = nn.Conv2d(in_channels, out_channels, 1, 1, 0, 1, 1, bias=bias)

    def forward(self, x):
        x = self.conv1(x)
        x = self.pointwise(x)
        return x


class Block(nn.Module):
    def __init__(self, in_filters, out_filters, reps, strides=1, start_with_relu=True, grow_first=True):
        super(Block, self).__init__()

        if out_filters != in_filters or strides != 1:
            self.skip = nn.Conv2d(in_filters, out_filters, 1, stride=strides, bias=False)
            self.skipbn = nn.BatchNorm2d(out_filters)
        else:
            self.skip = None

        self.relu = nn.ReLU(inplace=True)
        rep = []

        filters = in_filters
        if grow_first:
            rep.append(self.relu)
            rep.append(SeparableConv2d(in_filters, out_filters, 3, stride=1, padding=1, bias=False))
            rep.append(nn.BatchNorm2d(out_filters))
            filters = out_filters

        for i in range(reps - 1):
            rep.append(self.relu)
            rep.append(SeparableConv2d(filters, filters, 3, stride=1, padding=1, bias=False))
            rep.append(nn.BatchNorm2d(filters))

        if not grow_first:
            rep.append(self.relu)
            rep.append(SeparableConv2d(in_filters, out_filters, 3, stride=1, padding=1, bias=False))
            rep.append(nn.BatchNorm2d(out_filters))

        if not start_with_relu:
            rep = rep[1:]
        else:
            rep[0] = nn.ReLU(inplace=False)

        if strides != 1:
            rep.append(nn.MaxPool2d(3, strides, 1))
        self.rep = nn.Sequential(*rep)

    def forward(self, inp):
        x = self.rep(inp)

        if self.skip is not None:
            skip = self.skip(inp)
            skip = self.skipbn(skip)
        else:
            skip = inp

        x += skip
        return x


class Xception(nn.Module):
    """
    Xception optimized for the ImageNet dataset, as specified in
    https://arxiv.org/pdf/1610.02357.pdf
    """

    def __init__(self, num_classes=38):
        """ Constructor
        Args:
            num_classes: number of classes
        """
        super(Xception, self).__init__()

        self.num_classes = num_classes

        self.conv1 = nn.Conv2d(3, 32, 3, 2, 0, bias=False)
        self.bn1 = nn.BatchNorm2d(32)
        self.relu = nn.ReLU(inplace=True)

        self.conv2 = nn.Conv2d(32, 64, 3, bias=False)
        self.bn2 = nn.BatchNorm2d(64)
        # do relu here

        self.block1 = Block(64, 128, 2, 2, start_with_relu=False, grow_first=True)
        self.block2 = Block(128, 256, 2, 2, start_with_relu=True, grow_first=True)
        self.block3 = Block(256, 728, 2, 2, start_with_relu=True, grow_first=True)

        self.block4 = Block(728, 728, 3, 1, start_with_relu=True, grow_first=True)
        self.block5 = Block(728, 728, 3, 1, start_with_relu=True, grow_first=True)
        self.block6 = Block(728, 728, 3, 1, start_with_relu=True, grow_first=True)
        self.block7 = Block(728, 728, 3, 1, start_with_relu=True, grow_first=True)

        self.block8 = Block(728, 728, 3, 1, start_with_relu=True, grow_first=True)
        self.block9 = Block(728, 728, 3, 1, start_with_relu=True, grow_first=True)
        self.block10 = Block(728, 728, 3, 1, start_with_relu=True, grow_first=True)
        self.block11 = Block(728, 728, 3, 1, start_with_relu=True, grow_first=True)

        self.block12 = Block(728, 1024, 2, 2, start_with_relu=True, grow_first=False)

        self.conv3 = SeparableConv2d(1024, 1536, 3, 1, 1)
        self.bn3 = nn.BatchNorm2d(1536)

        # do relu here
        self.conv4 = SeparableConv2d(1536, 2048, 3, 1, 1)
        self.bn4 = nn.BatchNorm2d(2048)

        self.fc = nn.Linear(2048, num_classes)

        # ------- init weights --------
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
        # -----------------------------

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)

        x = self.conv2(x)
        x = self.bn2(x)
        x = self.relu(x)

        x = self.block1(x)
        x = self.block2(x)
        x = self.block3(x)
        x = self.block4(x)
        x = self.block5(x)
        x = self.block6(x)
        x = self.block7(x)
        x = self.block8(x)
        x = self.block9(x)
        x = self.block10(x)
        x = self.block11(x)
        x = self.block12(x)

        x = self.conv3(x)
        x = self.bn3(x)
        x = self.relu(x)

        x = self.conv4(x)
        x = self.bn4(x)
        x = self.relu(x)

        x = F.adaptive_avg_pool2d(x, (1, 1))
        x = x.view(x.size(0), -1)
        x = self.fc(x)

        return x


def xception(pretrained=False, **kwargs):
    """
    Construct Xception.
    """

    model = Xception(**kwargs)
    if pretrained:
        model.load_state_dict(model_zoo.load_url(model_urls['xception']))
    return model
import matplotlib.pyplot as plt
from PIL import Image
from torchvision.transforms import transforms
from model import xception
import torch
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif']=['SimHei']  #解决中文显示乱码问题
plt.rcParams['axes.unicode_minus']=False  #解决坐标轴负数的负号显示问题



data_transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Resize((224, 224)),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

img = Image.open(r"F:\SqueezeNet\dataset\test\PNEUMONIA\person1_virus_8.jpeg")
img = img.convert("RGB")
plt.imshow(img)
img = data_transform(img)
img = torch.unsqueeze(img, dim=0)
name = ['正常', '肺炎']
model_weight_path = "Xception_last.pth"
model = xception(num_classes=2)
model.load_state_dict(torch.load(model_weight_path))
model.eval()
with torch.no_grad():
    output = torch.squeeze(model(img))

    predict = torch.softmax(output, dim=0)
    # 获得最大可能性索引
    predict_cla = torch.argmax(predict).numpy()
    print('索引为', predict_cla)
print('预测结果为:{},置信度为: {}'.format(name[predict_cla], predict[predict_cla].item()))
plt.suptitle("预测结果为:{}".format(name[predict_cla]))
plt.show()

模型预测结果:
在这里插入图片描述

import torch
import torch.nn as nn

import torchvision.transforms as transforms
from torch.utils import data
import torch.optim as optim

from model import xception

from DataLoader import LoadData




# ================================= 下载图片、预处理图片、数据加载器 =================================

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
net = xception(num_classes=2).to(device=device)

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Resize((224, 224)),
     transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])


train_data = LoadData(r"F:\SqueezeNet\Xception\train.txt", True)
train_loader = torch.utils.data.DataLoader(train_data, batch_size=8, pin_memory=True,
                                           shuffle=True, num_workers=0)


loss_function = nn.CrossEntropyLoss()  # 定义损失函数
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)

min_loss = 100
for epoch in range(2):  # loop over the dataset multiple times
    print('第{}轮训练开始'.format(epoch))
    running_loss = 0.0  # 累加训练过程中的损失
    for i, (inputs, labels) in enumerate(train_loader):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()  # 将历史损失梯度清零
        # forward + backward + optimize
        outputs = net(inputs)
        loss = loss_function(outputs, labels)
        loss.backward()  # 反向传播
        optimizer.step()  # 参数更新
        # print statistics
        running_loss += loss.item()
        if i % 50 == 49:  # print every 500 mini-batches
            print('进来了')
            #     with torch.no_grad(): # with是一个上下文管理器
            #         outputs = net(val_image)  # [batch, 10]
            predict_y = torch.max(outputs, dim=1)[1]
            accuracy = torch.eq(predict_y, labels).sum().item() / len(labels)
            print('[%d  %5d] train_loss: %.3f  test_accuracy: %.3f' %
                  (epoch + 1, i + 1, running_loss / 50, accuracy))




    print('Finished Training')

save_path = './Xception_last.pth'
torch.save(net.state_dict(), save_path)

训练可视化:
在这里插入图片描述
经过训练之后,我们的模型识别还是挺准的
在这里插入图片描述

Orange Pi AIpro 总结

通过个人的体验,我觉得Orange Pi AIpro 具有以下几个优势:

  • 接口丰富:除了标准的USB、HDMI、MIPI等接口外,还支持SATA/NVMe SSD 2280的M.2插槽,可外接32GB/64GB/128GB/256GB eMMC模块。
  • 支持多种操作系统:除了预装的Ubuntu系统外,还支持openEuler操作系统,满足不同的开发需求。
  • 昇腾AI技术路线:采用华为昇腾AI技术路线,具有高性能、低功耗的特点。

不足之处:

  • AI算力限制:虽然具有8TOPS和20TOPS两种AI算力版本,但对于更复杂的AI应用来说,可能还需要更强的算力支持。

Orange Pi AIpro 是一款硬件配置强大、接口丰富的高性能AI开发板。对于需要强大AI算力和丰富接口的用户来说,20T版本是一个不错的选择,尽管价格较高。而对于预算有限的用户,8T版本也是一个性价比较高的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1925186.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL复合查询(重点)

前面我们讲解的mysql表的查询都是对一张表进行查询,在实际开发中这远远不够。 基本查询回顾 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J mysql> select * from emp where (sal>500 or jobMANAGER) and ename l…

强化学习:bellman方程求解state value例题

最近在学习强化学习相关知识,强烈推荐西湖大学赵世钰老师的课程,讲解的非常清晰流畅,一路学习下来令人身心大爽,感受数学抽丝剥茧,化繁为简的神奇魅力。 bellman方程还是比较容易理解的:当前状态下的state …

嵌入式linux系统中GDB调试器详解

前言 GDB全称GNU symbolic debugger,它是诞生于GNU开源组织的(同时诞生的还有 GCC、Emacs 等)UNIX及UNIX-like下的调试工具,是Linux下最常用的程序调试器,GDB 支持调试多种编程语言编写的程序,包括C、C++、Go、Objective-C、OpenCL、Ada 等。但是在实际应用中,GDB 更常…

linux_进程周边知识——理解冯诺依曼体系结构

前言: 本篇内容是为了让友友们较好地理解进程的概念, 而在真正了解进行概念之前, 要先了解一下冯诺依曼体系结构。 所以博主会先对冯诺伊曼体系结构进行解释, 然后再讲解进程的概念。 ps: 本篇内容适合了解一些linux指…

github中下载zip后,本地仓库如何与github上的项目相关联

有时候网速问题&#xff0c;git clone 太慢&#xff0c;就直接下载zip文件&#xff0c;然后再进行关联 1、下载zip 2、解压&#xff0c;把文件夹名称中-main去掉 3、进行关联 cd <repo> git init git add . git remote add origin https://github.com/<user>/&l…

springboot在线教育平台-计算机毕业设计源码68562

摘要 在数字化时代&#xff0c;随着信息技术的飞速发展&#xff0c;在线教育已成为教育领域的重要趋势。为了满足广大学习者对于灵活、高效学习方式的需求&#xff0c;基于Spring Boot的在线教育平台应运而生。Spring Boot以其快速开发、简便部署以及良好的可扩展性&#xff0c…

第一个基于FISCOBCOS的前后端项目(发行转账)(已开源)

本文旨在介绍一个简单的基于fiscobcos的前后端网站应用。Springbootjs前后端不分离。 所使用到的合约也是一个最基本的。首先您需要知道的是完整项目分为三部分&#xff0c;1是区块链平台webase搭建&#xff08;此项目使用节点前置webase-front即可&#xff09;&#xff0c;2是…

帕金森病患者在日常饮食中需要注意哪些特殊的营养需求?

帕金森病患者的特殊营养需求 帕金森病患者在日常饮食中需要特别注意以下几个方面的营养需求&#xff1a; 蛋白质摄入&#xff1a;由于帕金森病药物可能与蛋白质竞争同一种转运蛋白进入大脑&#xff0c;因此建议将蛋白质的摄入量分散在一天中的多餐中&#xff0c;避免集中在单一…

【python学习】多线程编程的背景、定义、特点、优缺点、使用场景和示例以及和单线程的区别

引言 随着计算机技术的发展&#xff0c;多核处理器已经成为了主流,为了充分利用多核处理器带来的并行计算能力&#xff0c;提高程序的执行效率和响应速度&#xff0c;多线程编程变得尤为重要 Python作为一种高级编程语言&#xff0c;提供了多线程编程的支持&#xff0c;允许开发…

力扣 24两两交换链表中节点

画图 注意有虚拟头结点 注意判断时先判断cur->next ! nullptr,再判断cur->next->next ! nullptr 注意末尾返回dumyhead->next&#xff0c;用新建result指针来接并返回 class Solution { public:ListNode* swapPairs(ListNode* head) {ListNode *dummyhead new …

【2024_CUMCM】时间序列1

目录 概念 时间序列数据 时期和时点时间序列 数值变换规律 长期趋势T 季节趋势S 循环变动C 不规则变动I 叠加和乘积模型 叠加模型 相互独立 乘积模型 相互影响 注 spss缺失值填补 简单填补 五种填补方法 填补原则 1.随机缺失 2.完全随机缺失 3.非随机缺失…

WGCLOUD登录页面支持输入验证码吗

支持的 v3.5.3版本开始&#xff0c;WGCLOUD支持在登录页面配置输入验证码&#xff0c;我们可以根据自己的场景需要&#xff0c;配置是否在登录页面显示验证码&#xff0c;如下说明 登录页面添加验证码说明 - WGCLOUD

酒店管理系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;酒店管理员管理&#xff0c;房间类型管理&#xff0c;房间信息管理&#xff0c;订单信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;房间信息…

CycleGAN深度学习项目

远程仓库 leftthomas/CycleGAN: A PyTorch implementation of CycleGAN based on ICCV 2017 paper "Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks" (github.com) 运行准备 Anaconda 安装需要的库 指令 pip install panda…

AI时代:探索个人潜能的新视角

文章目录 Al时代的个人发展1 AI的高速发展意味着什么1.1 生产力大幅提升1.2 生产关系的改变1.3 产品范式1.4 产业革命1.5 Al的局限性1.5.1局限一:大模型的幻觉 1.5.2 局限二&#xff1a;Token 2 个体如何应对这种改变?2.1 职场人2.2 K12家长2.3 大学生2.4 创业者 3 人工智能发…

万界星空科技商业开源MES系统全面解析

万界星空科技商业开源MES源码可拖拽式数据大屏 开源MES系统具有定制化、节省成本、开放性和适应性等优势和特点&#xff0c;可以帮助企业更好地管理生产流程。万界星空MES制造执行系统的Java开源版本&#xff0c;为制造业企业提供了全面的生产管理解决方案。万界星空科技的目标…

从零开始做题:满屏的QR

题目 给出一张png图片 解题 import os import re import cv2 import argparse import itertools import numpy as npparser argparse.ArgumentParser() parser.add_argument(-f, typestr, defaultNone, requiredTrue,help输入文件名称) parser.add_argument(-p, typestr, d…

[Vulnhub] Stapler wp-videos+ftp+smb+bash_history权限提升+SUID权限提升+Kernel权限提升

信息收集 IP AddressOpening Ports192.168.8.106TCP:21,22,53,80,123,137,138,139,666,3306, Using Nmap for scanning: $ nmap -p- 192.168.8.106 --min-rate 1000 -sC -sV The results are as follows: PORT STATE SERVICE VERSION 20/tcp closed ftp-data…

昇思25天学习打卡营第20天 | 基于MindNLP+MusicGen生成自己的个性化音乐

基于MindNLPMusicGen生成个性化音乐 实验简介 MusicGen是Meta AI提出的音乐生成模型&#xff0c;能够根据文本描述或音频提示生成高质量音乐。该模型基于Transformer结构&#xff0c;分为三个阶段&#xff1a;文本编码、音频token预测和音频解码。此实验将演示如何使用MindSpo…

Java常用排序算法

冒泡排序&#xff08;Bubble Sort&#xff09; arr[0] 与 arr[1]比较&#xff0c;如果前面元素大就交换&#xff0c;如果后边元素大就不交换。然后依次arr[1]与arr[2]比较&#xff0c;第一轮将最大值排到最后一位。 第二轮arr.length-1个元素进行比较&#xff0c;将第二大元素…