边缘人工智能——nanodet模型实践指引,从标注数据集到实现部署文件

这篇具有很好参考价值的文章主要介绍了边缘人工智能——nanodet模型实践指引,从标注数据集到实现部署文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

写在开头

        23年11月更新下,用他参赛拿了省级三等奖。

        里面提供的很多学习链接都失效了。

内容概述

        首先获得一个合适的nanodet模型版本,配置nanodet适用的环境,然后对网上公开的生数据集进行重新标注,配置nanodet并进行训练,.pth到.onnx的模型转化及简化,编写推理文件。

        文章着重于实践方向指引,对于其中细节需读者自行完成。

为什么使用nanodet

        该模型虽然检测精度较低,但是其极轻量化、推理快速的特点非常适合放在算力及内存较低的边缘人工设备上。

        这个是nanodet作者在github上的开源地址https://github.com/RangiLyu/nanodet,没有科学上网工具的话可以访问镜像站https://gitcode.net/mirrors/RangiLyu/nanodet.git。

选择合适的nanodet版本

        由于我的显卡是GTX1650,算力较低,无法使用最新版的nanodet所使用的部分包,需要换一个老版本的nanodet,所以我使用的是最后一次更新于2021年5月的版本。

配置nanodet环境及进行训练

        这一部分其实仔细阅读README.md的Demo到How to Train的部分就能整出来,安装的话没啥必要,直接修改源代码就行了。

配置nanodet适用的环境

        我使用Anaconda进行环境创建,Anaconda是一个环境管理工具,可以理解为配置python解释器的工具,和使用pycharm自动安装相比,可以更好的对环境及包版本进行管理,相当方便,没有这个的同学可以在站内搜索相关安装及配置教程,也可以就通过pycharm进行自动的包安装。

        在Anaconda上创建一个python==3.9.16的环境,使用activate <env>激活该环境后,将下载到的nanodet源代码中的requirement.txt复制下来,使用pip install <package>的命令尝试安装所有包,其中注意把requirement.txt中的torch和torchvision删去,因为安装torch和torchvision一定注意要与自己的CUDA版本匹配(如果使用pip自动安装会安装最新的,大概率是不和自己的CUDA匹配),并且这两个组件也要按照官网(pytorch官网)的推荐去装(用官网给的指令一遍装了就对了,注意torchvision==0.11.0+cu111只有linux版本,所以不要安装他以及他对应的torch)。

        可以通过查看pycharm在换上了新配置的conda环境后是否提示缺少包及运行demo.py(nanodet-main\demo\demo.py)检查自己是否正确搭建环境,最后demo.py能正常运行就说明环境配置好了,注意parse_args()的参数是命令行参数,如果验证的话可以在Anaconda Prompt激活环境后cd到模型文件夹内的demo.py按照README.md的demo部分提供的参数进行验证即可。

        这一块可以看下这位博主的验证部分http://t.csdn.cn/XGiuU

配置环境的详细步骤

        以下是我在搭建环境时做的记录,可供参考,直接搬到自己的机器里很可能出问题,请按照自己的系统环境进行配置(安装的时候最好全拿pip或者全拿conda,我这样混合两种工具安装如果需要迁移环境可能会遇到pip list不全的情况)。

配置:win10,1650显卡

conda 22.9.0
cuda 11.1 (指令nvcc -V)

先在anaconda prompt创建一个python==3.9.16 的环境

使用conda create -n py_3.12 Cython matplotlib numpy omegaconf=2.0.1 onnx onnx-simplifier opencv-python pyaml pycocotools pytorch-lightning=1.9.0 tabulate tensorboard termcolor torch=1.10 torchmetrics torchvision tqdm python=3.9
尝试安装所有包

这部分conda没用自动找到,需要手动挨个安装
  - onnx-simplifier
  - opencv-python
  - pytorch-lightning=1.9.0
  - torch=1.10
  - omegaconf==2.0.1
  - pycocotools

使用以下指令尝试安装:
conda install conda install -c necla-ml onnx-simplifier --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/

因为可能需要用pip,所以将这个现在建好的虚拟环境克隆,在新的克隆环境内继续安装包的操作
(克隆指令 conda create -n py_3.12_new --clone py_3.12 )

使用以下指令尝试安装:
pip install opencv-python
conda install -c https://conda.anaconda.org/menpo opencv
conda install -c conda-forge pytorch-lightning
pip install omegaconf==2.0.1
conda install -c conda-forge pycocotools

安装torch和torchvision一定注意要与自己的CUDA版本匹配,并且这两个组件也要按照官网的推荐去装(用官网给的指令一遍装了就对了,注意torchvision==0.11.0+cu111只有linux版本,所以不要安装他以及他对应的torch)

我的torch版本是v1.9.1(根据自己的电脑版本下载)
我使用的安装指令:
pip install torch==1.9.1+cu111 torchvision==0.10.1+cu111 torchaudio==0.9.1 -f https://download.pytorch.org/whl/torch_stable.html

如果遇到死机
原因是之前下载了pytorch,但是由于权限原因没有安装pytorch,需要做两点改动,在pip install之间加上--no-cache-dir,命令的最后加上--user
pip --no-cache-dir install torch==1.8.2+cu111 torchvision==0.9.2+cu111 torchaudio===0.8.2 -f https://download.pytorch.org/whl/lts/1.8/torch_lts.html --user


另外注意,我转发的那个代码需要GPU加速,如果没有GPU需要修改代码或者下载README.MD最尾端给出的cpu版本的地址
代码中给出的指令,即
'''目标检测-图片'''
python detect_main.py image --config ./config/nanodet-m.yml --model model/nanodet_m.pth --path  street.png

'''目标检测-视频文件'''
python detect_main.py video --config ./config/nanodet-m.yml --model model/nanodet_m.pth --path  test.mp4

'''目标检测-摄像头'''
python detect_main.py webcam --config ./config/nanodet-m.yml --model model/nanodet_m.pth --path  0
是命令行指令,在虚拟环境下cd到模型所在包将指令复制到命令行中就可以运行了(我测试不了第二个,应该是不能用)

我的conda源等信息:
conda info

     active environment : py_3.12_new
    active env location : D:\ANACONDA\envs\py_3.12_new
            shell level : 2
       user config file : C:\Users\lenovo\.condarc
 populated config files : C:\Users\lenovo\.condarc
          conda version : 22.9.0
    conda-build version : 3.22.0
         python version : 3.9.13.final.0
       virtual packages : __cuda=11.2=0
                          __win=0=0
                          __archspec=1=x86_64
       base environment : D:\ANACONDA  (read only)
      conda av data dir : D:\ANACONDA\etc\conda
  conda av metadata url : None
           channel URLs : https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/win-64
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/noarch
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/win-64
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/noarch
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2/win-64
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2/noarch
          package cache : D:\ANACONDA\pkgs
                          C:\Users\lenovo\.conda\pkgs
                          C:\Users\lenovo\AppData\Local\conda\conda\pkgs
       envs directories : C:\Users\lenovo\.conda\envs
                          D:\ANACONDA\envs
                          C:\Users\lenovo\AppData\Local\conda\conda\envs
               platform : win-64
             user-agent : conda/22.9.0 requests/2.28.1 CPython/3.9.13 Windows/10 Windows/10.0.19044
          administrator : False
             netrc file : None
           offline mode : False


我的虚拟环境包目录:
conda list
# packages in environment at D:\ANACONDA\envs\py_3.12_new:             
#                                                                      
# Name                    Version                   Build  Channel     
absl-py                   1.3.0            py39haa95532_0    defaults  
aiohttp                   3.8.3            py39h2bbff1b_0    defaults  
aiosignal                 1.2.0              pyhd3eb1b0_0    defaults  
async-timeout             4.0.2            py39haa95532_0    defaults  
attrs                     22.1.0           py39haa95532_0    defaults  
blas                      1.0                         mkl    defaults  
blinker                   1.4              py39haa95532_0    defaults  
brotli                    1.0.9                h2bbff1b_7    defaults  
brotli-bin                1.0.9                h2bbff1b_7    defaults  
brotlipy                  0.7.0           py39h2bbff1b_1003    defaults
ca-certificates           2023.01.10           haa95532_0    defaults  
cachetools                4.2.2              pyhd3eb1b0_0    defaults  
certifi                   2022.12.7        py39haa95532_0    defaults
cffi                      1.15.1           py39h2bbff1b_3    defaults
charset-normalizer        2.0.4              pyhd3eb1b0_0    defaults
click                     8.0.4            py39haa95532_0    defaults
colorama                  0.4.6            py39haa95532_0    defaults
contourpy                 1.0.5            py39h59b6b97_0    defaults
cryptography              39.0.1           py39h21b164f_0    defaults
cycler                    0.11.0             pyhd3eb1b0_0    defaults
cython                    0.29.33          py39hd77b12b_0    defaults
flit-core                 3.6.0              pyhd3eb1b0_0    defaults
fonttools                 4.25.0             pyhd3eb1b0_0    defaults
freetype                  2.12.1               ha860e81_0    defaults
frozenlist                1.3.3            py39h2bbff1b_0    defaults
future                    0.18.3           py39haa95532_0    defaults
giflib                    5.2.1                h8cc25b3_3    defaults
glib                      2.69.1               h5dc1a3c_2    defaults
google-auth               2.6.0              pyhd3eb1b0_0    defaults
google-auth-oauthlib      0.4.4              pyhd3eb1b0_0    defaults
grpcio                    1.42.0           py39hc60d5dd_0    defaults
gst-plugins-base          1.18.5               h9e645db_0    defaults
gstreamer                 1.18.5               hd78058f_0    defaults
icu                       58.2                 ha925a31_3    defaults
idna                      3.4              py39haa95532_0    defaults
importlib-metadata        4.11.3           py39haa95532_0    defaults
importlib_resources       5.2.0              pyhd3eb1b0_1    defaults
intel-openmp              2021.4.0          haa95532_3556    defaults
jpeg                      9e                   h2bbff1b_1    defaults
kiwisolver                1.4.4            py39hd77b12b_0    defaults
lerc                      3.0                  hd77b12b_0    defaults
libbrotlicommon           1.0.9                h2bbff1b_7    defaults
libbrotlidec              1.0.9                h2bbff1b_7    defaults
libbrotlienc              1.0.9                h2bbff1b_7    defaults
libclang                  12.0.0          default_h627e005_2    defaults
libdeflate                1.17                 h2bbff1b_0    defaults
libffi                    3.4.2                hd77b12b_6    defaults
libiconv                  1.16                 h2bbff1b_2    defaults
libogg                    1.3.5                h2bbff1b_1    defaults
libpng                    1.6.39               h8cc25b3_0    defaults
libprotobuf               3.20.3               h23ce68f_0    defaults
libtiff                   4.5.0                h6c2663c_2    defaults
libuv                     1.44.2               h2bbff1b_0    defaults
libvorbis                 1.3.7                he774522_0    defaults
libwebp                   1.2.4                hbc33d0d_1    defaults
libwebp-base              1.2.4                h2bbff1b_1    defaults
libxml2                   2.9.14               h0ad7f3c_0    defaults
libxslt                   1.1.35               h2bbff1b_0    defaults
lz4-c                     1.9.4                h2bbff1b_0    defaults
markdown                  3.4.1            py39haa95532_0    defaults
markdown-it-py            2.2.0                    pypi_0    pypi
markupsafe                2.1.1            py39h2bbff1b_0    defaults
matplotlib                3.7.0            py39haa95532_0    defaults
matplotlib-base           3.7.0            py39hf11a4ad_0    defaults
mdurl                     0.1.2                    pypi_0    pypi
mkl                       2021.4.0           haa95532_640    defaults
mkl-service               2.4.0            py39h2bbff1b_0    defaults
mkl_fft                   1.3.1            py39h277e83a_0    defaults
mkl_random                1.2.2            py39hf11a4ad_0    defaults
multidict                 6.0.2            py39h2bbff1b_0    defaults
munkres                   1.1.4                      py_0    defaults
ninja                     1.10.2               haa95532_5    defaults
ninja-base                1.10.2               h6d14046_5    defaults
numpy                     1.23.5           py39h3b20f71_0    defaults
numpy-base                1.23.5           py39h4da318b_0    defaults
oauthlib                  3.2.1            py39haa95532_0    defaults
onnx                      1.13.0           py39h9724e47_0    defaults
onnx-simplifier           0.4.17                   pypi_0    pypi
opencv-contrib-python     4.7.0.72                 pypi_0    pypi
opencv-python             4.7.0.72                 pypi_0    pypi
openssl                   1.1.1t               h2bbff1b_0    defaults
packaging                 22.0             py39haa95532_0    defaults
pcre                      8.45                 hd77b12b_0    defaults
pillow                    9.4.0            py39hd77b12b_0    defaults
pip                       23.0.1           py39haa95532_0    defaults
ply                       3.11             py39haa95532_0    defaults
protobuf                  3.20.3           py39hd77b12b_0    defaults
pyaml                     20.4.0             pyhd3eb1b0_0    defaults
pyasn1                    0.4.8              pyhd3eb1b0_0    defaults
pyasn1-modules            0.2.8                      py_0    defaults
pycocotools               2.0.4            py39h5d4886f_1    conda-forge
pycparser                 2.21               pyhd3eb1b0_0    defaults
pygments                  2.14.0                   pypi_0    pypi
pyjwt                     2.4.0            py39haa95532_0    defaults
pyopenssl                 23.0.0           py39haa95532_0    defaults
pyparsing                 3.0.9            py39haa95532_0    defaults
pyqt                      5.15.7           py39hd77b12b_0    defaults
pyqt5-sip                 12.11.0          py39hd77b12b_0    defaults
pysocks                   1.7.1            py39haa95532_0    defaults
python                    3.9.16               h6244533_1    defaults
python-dateutil           2.8.2              pyhd3eb1b0_0    defaults
python_abi                3.9                      2_cp39    conda-forge
pyyaml                    6.0              py39h2bbff1b_1    defaults
qt-main                   5.15.2               he8e5bd7_7    defaults
qt-webengine              5.15.9               hb9a9bb5_5    defaults
qtwebkit                  5.212                h3ad3cdb_4    defaults
requests                  2.28.1           py39haa95532_0    defaults
requests-oauthlib         1.3.0                      py_0    defaults
rich                      13.3.2                   pypi_0    pypi
rsa                       4.7.2              pyhd3eb1b0_1    defaults
setuptools                65.6.3           py39haa95532_0    defaults
sip                       6.6.2            py39hd77b12b_0    defaults
six                       1.16.0             pyhd3eb1b0_1    defaults
sqlite                    3.40.1               h2bbff1b_0    defaults
tabulate                  0.8.10           py39haa95532_0    defaults
tensorboard               2.10.0           py39haa95532_0    defaults
tensorboard-data-server   0.6.1            py39haa95532_0    defaults
tensorboard-plugin-wit    1.8.1            py39haa95532_0    defaults
termcolor                 2.1.0            py39haa95532_0    defaults
tk                        8.6.12               h2bbff1b_0    defaults
toml                      0.10.2             pyhd3eb1b0_0    defaults
torch                     1.9.1+cu111              pypi_0    pypi
torchaudio                0.9.1                    pypi_0    pypi
torchvision               0.10.1+cu111             pypi_0    pypi
tornado                   6.2              py39h2bbff1b_0    defaults
tqdm                      4.64.1           py39haa95532_0    defaults
typing-extensions         4.4.0            py39haa95532_0    defaults
typing_extensions         4.4.0            py39haa95532_0    defaults
tzdata                    2022g                h04d1e81_0    defaults
urllib3                   1.26.14          py39haa95532_0    defaults
vc                        14.2                 h21ff451_1    defaults
vs2015_runtime            14.27.29016          h5e58377_2    defaults
werkzeug                  2.2.2            py39haa95532_0    defaults
wheel                     0.38.4           py39haa95532_0    defaults
win_inet_pton             1.1.0            py39haa95532_0    defaults
wincertstore              0.2              py39haa95532_2    defaults
xz                        5.2.10               h8cc25b3_1    defaults
yaml                      0.2.5                he774522_0    defaults
yarl                      1.8.1            py39h2bbff1b_0    defaults
zipp                      3.11.0           py39haa95532_0    defaults
zlib                      1.2.13               h8cc25b3_0    defaults
zstd                      1.5.2                h19a0ad4_0    defaults

pip list
Package                   Version
------------------------- ------------
absl-py                   1.3.0
aiohttp                   3.8.3
aiosignal                 1.2.0
altgraph                  0.17.3
async-timeout             4.0.2
attrs                     22.1.0
blinker                   1.4
brotlipy                  0.7.0
cachetools                4.2.2
certifi                   2022.12.7
cffi                      1.15.1
charset-normalizer        2.0.4
click                     8.0.4
colorama                  0.4.6
coloredlogs               15.0.1
contourpy                 1.0.5
cryptography              39.0.1
cycler                    0.11.0
Cython                    0.29.33
flatbuffers               23.3.3
flit_core                 3.6.0
fonttools                 4.25.0
frozenlist                1.3.3
future                    0.18.3
google-auth               2.6.0
google-auth-oauthlib      0.4.4
grpcio                    1.42.0
humanfriendly             10.0
idna                      3.4
importlib-metadata        4.11.3
importlib-resources       5.2.0
kiwisolver                1.4.4
Markdown                  3.4.1
markdown-it-py            2.2.0
MarkupSafe                2.1.1
matplotlib                3.7.0
mdurl                     0.1.2
mkl-fft                   1.3.1
mkl-random                1.2.2
mkl-service               2.4.0
mpmath                    1.3.0
multidict                 6.0.2
munkres                   1.1.4
numpy                     1.23.5
oauthlib                  3.2.1
omegaconf                 2.0.1
onnx                      1.13.0
onnx-simplifier           0.4.17
onnxruntime               1.14.1
opencv-contrib-python     4.7.0.72
opencv-python             4.7.0.72
packaging                 22.0
pefile                    2023.2.7
Pillow                    9.4.0
pip                       23.0.1
ply                       3.11
protobuf                  3.20.3
pyaml                     20.4.0
pyasn1                    0.4.8
pyasn1-modules            0.2.8
pycocotools               2.0.4
pycparser                 2.21
Pygments                  2.14.0
pyinstaller               5.8.0
pyinstaller-hooks-contrib 2023.0
PyJWT                     2.4.0
pyOpenSSL                 23.0.0
pyparsing                 3.0.9
PyQt5                     5.15.7
PyQt5-sip                 12.11.0
pyreadline3               3.4.1
PySocks                   1.7.1
python-dateutil           2.8.2
pywin32-ctypes            0.2.0
PyYAML                    6.0
requests                  2.28.1
requests-oauthlib         1.3.0
rich                      13.3.2
rsa                       4.7.2
setuptools                65.6.3
sip                       6.6.2
six                       1.16.0
sympy                     1.11.1
tabulate                  0.8.10
tensorboard               2.10.0
tensorboard-data-server   0.6.1
tensorboard-plugin-wit    1.8.1
termcolor                 2.1.0
toml                      0.10.2
torch                     1.9.1+cu111
torchaudio                0.9.1
torchvision               0.10.1+cu111
tornado                   6.2
tqdm                      4.64.1
typing_extensions         4.4.0
urllib3                   1.26.14
Werkzeug                  2.2.2
wheel                     0.38.4
win-inet-pton             1.1.0
wincertstore              0.2
yarl                      1.8.1
zipp                      3.11.0

重新标注数据集

        使用labelimg,我拿他做了xml(一种标签格式)的重新标注,这个工具使用比较简单,缺点是没有批处理。注意标注的时候要把图片文件和xml标签文件放在一个文件夹内,而且两者的前缀名要一致,这样才会自动自动把已标注的标签框显示出来。

        具体可以看这位博主的文章http://t.csdn.cn/cegAT

配置nanodet准备进行训练

        查看README.md的How to Train,按照提示修改config并使用适合的train.py提示就好

        首先要修改config文件:

边缘人工智能——nanodet模型实践指引,从标注数据集到实现部署文件

         我的数据集是xml格式的,所以选择修改nanodet_custom_xml_dataset.yml的config文件,有同学可能会问为啥这么多这都是啥,其实就是不同的nanodet子模型,可以看看Model Zoo挑选一个自己喜欢的。

边缘人工智能——nanodet模型实践指引,从标注数据集到实现部署文件

         打开选好的config,按照README.md修改参数,这一部分也可以参照这位博主的训练部分http://t.csdn.cn/aVE2D,然后我再补充一些,其实可以用xml的数据集训练,拿nanodet_custom_xml_dataset.yml就行,应该是这位博主用的nanodet的版本还没更新出这个文件;“data:train:name:”不能随便修改,他表示了训练数据的数据格式,比如nanodet_custom_xml_dataset.yml的这一参数是xml_dataset;“schedule:device:gpu_ids”是GPU的数量,0表示1块GPU,如果你用的是服务器,把这个参数设置为服务器的GPU个数;“schedule:device:workers_per_gpu:”和“schedule:device:batchsize_per_gpu:”设置了每块GPU的工作量,要是显卡不太好就设置的小一点,大了会报错,比如我的1650设置的是1和36;“data:val:”里的"val"是验证集,一般和训练集不能重合。

        config设置好后就可以用train.py训练了,在我使用的这个版本单GPU使用tools下的train.py会报错,换成tools/deprecated/train.py进行训练就好了。

        训练时会先对数据集进行索引,然后进行训练,如果你看到他先是跳出一大串像是训练的代码然后过几秒突然报错可能是只完成了索引而在训练时出问题,按照报错检查下config,大概率是设置有问题。训练完成后会获得一个.pth文件(新版nanodet应该是生成.cpth),放在你在config里设置的sav_dir里。

.pth模型向.onnx转化及简化.onnx

        因为原代码只提供.cpth转.onnx,所以需要修改tools/export.py,核心函数使用torch.onnx.export()即可,不需要修改太多。

import os
import argparse
import torch
from nanodet.model.arch import build_model
from nanodet.util import Logger, cfg, load_config, load_model_weight


def generate_ouput_names(head_cfg):
    cls_names, dis_names = [], []
    for stride in head_cfg.strides:
        cls_names.append('cls_pred_stride_{}'.format(stride))
        dis_names.append('dis_pred_stride_{}'.format(stride))
    return cls_names + dis_names


def main(config, model_path, output_path, input_shape=(320, 320)):
    logger = Logger(-1, config.save_dir, False)
    model = build_model(config.model)
    checkpoint = torch.load(model_path, map_location=lambda storage, loc: storage)
    load_model_weight(model, checkpoint, logger)

    dummy_input = torch.autograd.Variable(torch.randn(1, 3, input_shape[0], input_shape[1]))
    torch.onnx.export(model,
                      dummy_input,
                      output_path,
                      verbose=True,
                      keep_initializers_as_inputs=True,
                      opset_version=10)
    logger.log('finished exporting onnx ')

if __name__ =='__main__':
    cfg_path = r"D:\pythonProject\nanodet-main\config\nanodet_custom_xml_dataset.yml"   #config path
    model_path=r"D:\pythonProject\nanodet-main\workspace\nanodet_m_new_2\model_last.pth"
    out_path = r"D:\pythonProject\nanodet-main\workspace\nanodet_m_new_2\output_my.onnx"#output model path
    load_config(cfg,cfg_path)
    main(cfg,model_path,out_path,input_shape=(320,320) )#根据自己的输入尺寸修改

        转化后可以再使用onnx-simplifier简化,相关教程搜索这个包名就行,不过我的结果是简化前后没变化。

         这部分也可以查看这篇博文http://t.csdn.cn/kCHJ8,不过要付费。       

部署文件

        这部分这位博主写的非常好,大家可以先看他的http://t.csdn.cn/KfbnS,作者使用opencv-python==4.5.2.52进行了部署,所以部署环境只要是能满足opencv的要求就行了(不要用最新的版本,会报错,python版本和numpy跟着opencv装,我的python是3.9.16),作者实现了对于图片的检测,我在博主的基础上做了点修改,改为逐帧检测视频,下面两段代码分别是将结果保存到.json文件中及直接可视化

结果保存到.json

import cv2
import numpy as np
import argparse
classes = ['helmet', 'with_mask', 'reflective_clothes']
resultsW= []

class my_nanodet():
    def __init__(self,model, input_shape=320, prob_threshold=0.4, iou_threshold=0.3):
        self.classes = classes
        self.num_classes = len(self.classes)
        self.strides = (8, 16, 32)
        self.input_shape = (input_shape, input_shape)
        self.reg_max = 7
        self.prob_threshold = prob_threshold
        self.iou_threshold = iou_threshold
        self.project = np.arange(self.reg_max + 1)
        self.mean = np.array([103.53, 116.28, 123.675], dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array([57.375, 57.12, 58.395], dtype=np.float32).reshape(1, 1, 3)
        self.net = cv2.dnn.readNet(model)

        self.mlvl_anchors = []
        for i in range(len(self.strides)):
            anchors = self._make_grid((int(self.input_shape[0] / self.strides[i]), int(self.input_shape[1] / self.strides[i])), self.strides[i])
            self.mlvl_anchors.append(anchors)
    def _make_grid(self, featmap_size, stride):
        feat_h, feat_w = featmap_size
        shift_x = np.arange(0, feat_w) * stride
        shift_y = np.arange(0, feat_h) * stride
        xv, yv = np.meshgrid(shift_x, shift_y)
        xv = xv.flatten()
        yv = yv.flatten()
        cx = xv + 0.5 * (stride-1)
        cy = yv + 0.5 * (stride - 1)
        return np.stack((cx, cy), axis=-1)
    def softmax(self,x, axis=1):
        x_exp = np.exp(x)
        # 如果是列向量,则axis=0
        x_sum = np.sum(x_exp, axis=axis, keepdims=True)
        s = x_exp / x_sum
        return s

    def _normalize(self, img):   ### c++: https://blog.csdn.net/wuqingshan2010/article/details/107727909
        img = img.astype(np.float32)
        img = (img - self.mean) / self.std
        return img
    def resize_image(self, srcimg, keep_ratio=True):
        top, left, newh, neww = 0, 0, self.input_shape[0], self.input_shape[1]
        if keep_ratio and srcimg.shape[0] != srcimg.shape[1]:
            hw_scale = srcimg.shape[0] / srcimg.shape[1]
            if hw_scale > 1:
                newh, neww = self.input_shape[0], int(self.input_shape[1] / hw_scale)
                img = cv2.resize(srcimg, (neww, newh), interpolation=cv2.INTER_AREA)
                left = int((self.input_shape[1] - neww) * 0.5)
                img = cv2.copyMakeBorder(img, 0, 0, left, self.input_shape[1] - neww - left, cv2.BORDER_CONSTANT,
                                         value=0)  # add border
            else:
                newh, neww = int(self.input_shape[0] * hw_scale), self.input_shape[1]
                img = cv2.resize(srcimg, (neww, newh), interpolation=cv2.INTER_AREA)
                top = int((self.input_shape[0] - newh) * 0.5)
                img = cv2.copyMakeBorder(img, top, self.input_shape[0] - newh - top, 0, 0, cv2.BORDER_CONSTANT, value=0)
        else:
            img = cv2.resize(srcimg, self.input_shape, interpolation=cv2.INTER_AREA)
        return img, newh, neww, top, left
    def detect(self, srcimg):
        img, newh, neww, top, left = self.resize_image(srcimg)
        img = self._normalize(img)
        blob = cv2.dnn.blobFromImage(img)
        # Sets the input to the network
        self.net.setInput(blob)

        # Runs the forward pass to get output of the output layers
        outs = self.net.forward(self.net.getUnconnectedOutLayersNames())
        det_bboxes, det_conf, det_classid = self.post_process(outs)

        drawimg = srcimg.copy()
        ratioh,ratiow = srcimg.shape[0]/newh,srcimg.shape[1]/neww

        anchor = []
        label  = []
        #修改为.json写入 #det_conf[i]是置信度
        for i in range(det_bboxes.shape[0]):

            xmin, ymin, xmax, ymax = max(int((det_bboxes[i,0] - left) * ratiow), 0), max(int((det_bboxes[i,1] - top) * ratioh), 0), min(
                int((det_bboxes[i,2] - left) * ratiow), srcimg.shape[1]), min(int((det_bboxes[i,3] - top) * ratioh), srcimg.shape[0])
            #print(det_classid[i], det_conf[i])
            anchor.append([xmin, ymin, xmax, ymax])
            label.append(classes[det_classid[i]])

        return anchor,label

    def post_process(self, preds):
        cls_scores, bbox_preds = preds[::2], preds[1::2]
        det_bboxes, det_conf, det_classid = self.get_bboxes_single(cls_scores, bbox_preds, 1, rescale=False)
        return det_bboxes.astype(np.int32), det_conf, det_classid
    def get_bboxes_single(self, cls_scores, bbox_preds, scale_factor, rescale=False):
        mlvl_bboxes = []
        mlvl_scores = []
        for stride, cls_score, bbox_pred, anchors in zip(self.strides, cls_scores, bbox_preds, self.mlvl_anchors):
            if cls_score.ndim==3:
                cls_score = cls_score.squeeze(axis=0)
            if bbox_pred.ndim==3:
                bbox_pred = bbox_pred.squeeze(axis=0)
            bbox_pred = self.softmax(bbox_pred.reshape(-1, self.reg_max + 1), axis=1)
            # bbox_pred = np.sum(bbox_pred * np.expand_dims(self.project, axis=0), axis=1).reshape((-1, 4))
            bbox_pred = np.dot(bbox_pred, self.project).reshape(-1,4)
            bbox_pred *= stride

            # nms_pre = cfg.get('nms_pre', -1)
            nms_pre = 1000
            if nms_pre > 0 and cls_score.shape[0] > nms_pre:
                max_scores = cls_score.max(axis=1)
                topk_inds = max_scores.argsort()[::-1][0:nms_pre]
                anchors = anchors[topk_inds, :]
                bbox_pred = bbox_pred[topk_inds, :]
                cls_score = cls_score[topk_inds, :]

            bboxes = self.distance2bbox(anchors, bbox_pred, max_shape=self.input_shape)
            mlvl_bboxes.append(bboxes)
            mlvl_scores.append(cls_score)

        mlvl_bboxes = np.concatenate(mlvl_bboxes, axis=0)
        if rescale:
            mlvl_bboxes /= scale_factor
        mlvl_scores = np.concatenate(mlvl_scores, axis=0)

        bboxes_wh = mlvl_bboxes.copy()
        bboxes_wh[:, 2:4] = bboxes_wh[:, 2:4] - bboxes_wh[:, 0:2]  ####xywh
        classIds = np.argmax(mlvl_scores, axis=1)
        confidences = np.max(mlvl_scores, axis=1)  ####max_class_confidence

        indices = cv2.dnn.NMSBoxes(bboxes_wh.tolist(), confidences.tolist(), self.prob_threshold, self.iou_threshold)
        if len(indices)>0:
            mlvl_bboxes = mlvl_bboxes[indices[:, 0]]
            confidences = confidences[indices[:, 0]]
            classIds = classIds[indices[:, 0]]
            return mlvl_bboxes, confidences, classIds
        else:
            print('nothing detect')
            return np.array([]), np.array([]), np.array([])
    def distance2bbox(self, points, distance, max_shape=None):
        x1 = points[:, 0] - distance[:, 0]
        y1 = points[:, 1] - distance[:, 1]
        x2 = points[:, 0] + distance[:, 2]
        y2 = points[:, 1] + distance[:, 3]
        if max_shape is not None:
            x1 = np.clip(x1, 0, max_shape[1])
            y1 = np.clip(y1, 0, max_shape[0])
            x2 = np.clip(x2, 0, max_shape[1])
            y2 = np.clip(y2, 0, max_shape[0])
        return np.stack([x1, y1, x2, y2], axis=-1)

    def drawPred(self, frame, classId, conf, left, top, right, bottom):
        # Draw a bounding box.
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), thickness=4)

        label = '%.2f' % conf
        label = '%s:%s' % (self.classes[classId], label)

        # Display the label at the top of the bounding box
        labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
        top = max(top, labelSize[1])
        # cv.rectangle(frame, (left, top - round(1.5 * labelSize[1])), (left + round(1.5 * labelSize[0]), top + baseLine), (255,255,255), cv.FILLED)
        cv2.putText(frame, label, (left, top - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), thickness=2)
        return frame

if __name__=='__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--video_path', type=str, default='检测视频.avi', help="video path")
    parser.add_argument('--model_path', type=str, default='new.onnx', help='(.onnx)model path')
    parser.add_argument('--sav_path', type=str, default='result.json', help='(.json)result file path')
    args = parser.parse_args()
    args.input_shape  = 320     #input image shape
    args.confThreshold= 0.37    #class confidence
    args.nmsThreshold = 0.6     #nms iou thresh

    import json
    file = open(args.sav_path, 'w')

    capure = cv2.VideoCapture(args.video_path)#get video
    net = my_nanodet(input_shape=args.input_shape, prob_threshold=args.confThreshold, iou_threshold=args.nmsThreshold,model=args.model_path)

    import time
    #推理
    if capure.isOpened():
        while True:
            ret,img = capure.read()
            if not ret: break
            #获取到图像
            a = time.time()
            anchor,label = net.detect(img)
            b = time.time()
            ti = b - a

            data = {
                "time":ti*1000,
                "anchor":anchor,
                "label":label
            }
            resultsW.append(data)
        #写入文件
        with open(args.sav_path, 'w') as f:
            json.dump(resultsW, f)
    else:
        print('open video error')


可视化

import cv2
import numpy as np
import argparse
import time
import logging
import threading


classes = ['helmet', 'with_mask', 'reflective_clothes']
resultsW= []

def grab_img(cam):
    """This 'grab_img' function is designed to be run in the sub-thread.
    Once started, this thread continues to grab a new image and put it
    into the global 'img_handle', until 'thread_running' is set to False.
    """
    while cam.thread_running:
        _, cam.img_handle = cam.cap.read()
        fps = cam.cap.get(cv2.CAP_PROP_FPS)
        time.sleep(1/fps)  # fps = 20hz
        #print('time sleep ', 1/fps)
        if cam.img_handle is None:
            logging.warning('grab_img(): cap.read() returns None...')
            break
    cam.thread_running = False

class Camera():
    """Camera class which supports reading images from this video sources:
     Video file
    """

    def __init__(self, args):
        self.args = args
        self.is_opened = False
        self.thread_running = False
        self.img_handle = None
        self.img_width = 0
        self.img_height = 0
        self.cap = None
        self.thread = None

    def open(self):
        args = self.args
        #视频读取
        self.cap = cv2.VideoCapture(args.filename)
        # ignore image width/height settings here

        if self.cap != 'OK':
            if self.cap.isOpened():
                # Try to grab the 1st image and determine width and height
                _, img = self.cap.read()
                if img is not None:
                    self.img_height, self.img_width, _ = img.shape
                    self.is_opened = True

    def start(self):
        assert not self.thread_running
        self.thread_running = True
        self.thread = threading.Thread(target=grab_img, args=(self,))
        self.thread.start()

    def stop(self):
        self.thread_running = False
        self.thread.join()

    def read(self):
        self.img_handle.shape = [self.img_height,self.img_width]
        return self.img_handle

    def release(self):
        assert not self.thread_running
        if self.cap != 'OK':
            self.cap.release()

class my_nanodet():
    def __init__(self,model, input_shape=320, prob_threshold=0.4, iou_threshold=0.3):
        self.classes = classes
        self.num_classes = len(self.classes)
        self.strides = (8, 16, 32)
        self.input_shape = (input_shape, input_shape)
        self.reg_max = 7
        self.prob_threshold = prob_threshold
        self.iou_threshold = iou_threshold
        self.project = np.arange(self.reg_max + 1)
        self.mean = np.array([103.53, 116.28, 123.675], dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array([57.375, 57.12, 58.395], dtype=np.float32).reshape(1, 1, 3)
        self.net = cv2.dnn.readNet(model)

        self.mlvl_anchors = []
        for i in range(len(self.strides)):
            #print(type(self.input_shape[0]))
            anchors = self._make_grid((int(self.input_shape[0] / self.strides[i]), int(self.input_shape[1] / self.strides[i])), self.strides[i])
            self.mlvl_anchors.append(anchors)
    def _make_grid(self, featmap_size, stride):
        feat_h, feat_w = featmap_size
        shift_x = np.arange(0, feat_w) * stride
        shift_y = np.arange(0, feat_h) * stride
        xv, yv = np.meshgrid(shift_x, shift_y)
        xv = xv.flatten()
        yv = yv.flatten()
        cx = xv + 0.5 * (stride-1)
        cy = yv + 0.5 * (stride - 1)
        return np.stack((cx, cy), axis=-1)
    def softmax(self,x, axis=1):
        x_exp = np.exp(x)
        # 如果是列向量,则axis=0
        x_sum = np.sum(x_exp, axis=axis, keepdims=True)
        s = x_exp / x_sum
        return s

    def _normalize(self, img):   ### c++: https://blog.csdn.net/wuqingshan2010/article/details/107727909
        img = img.astype(np.float32)
        img = (img - self.mean) / self.std
        return img
    def resize_image(self, srcimg, keep_ratio=True):
        top, left, newh, neww = 0, 0, self.input_shape[0], self.input_shape[1]
        if keep_ratio and srcimg.shape[0] != srcimg.shape[1]:
            hw_scale = srcimg.shape[0] / srcimg.shape[1]
            if hw_scale > 1:
                newh, neww = self.input_shape[0], int(self.input_shape[1] / hw_scale)
                img = cv2.resize(srcimg, (neww, newh), interpolation=cv2.INTER_AREA)
                left = int((self.input_shape[1] - neww) * 0.5)
                img = cv2.copyMakeBorder(img, 0, 0, left, self.input_shape[1] - neww - left, cv2.BORDER_CONSTANT,
                                         value=0)  # add border
            else:
                newh, neww = int(self.input_shape[0] * hw_scale), self.input_shape[1]
                img = cv2.resize(srcimg, (neww, newh), interpolation=cv2.INTER_AREA)
                top = int((self.input_shape[0] - newh) * 0.5)
                img = cv2.copyMakeBorder(img, top, self.input_shape[0] - newh - top, 0, 0, cv2.BORDER_CONSTANT, value=0)
        else:
            img = cv2.resize(srcimg, self.input_shape, interpolation=cv2.INTER_AREA)
        return img, newh, neww, top, left
    def detect(self, srcimg):
        img, newh, neww, top, left = self.resize_image(srcimg)
        img = self._normalize(img)
        blob = cv2.dnn.blobFromImage(img)
        # Sets the input to the network
        self.net.setInput(blob)

        # Runs the forward pass to get output of the output layers
        outs = self.net.forward(self.net.getUnconnectedOutLayersNames())
        det_bboxes, det_conf, det_classid = self.post_process(outs)

        drawimg = srcimg.copy()
        ratioh,ratiow = srcimg.shape[0]/newh,srcimg.shape[1]/neww

        anchor = []
        label  = []
        #修改为.json写入 #det_conf[i]是置信度
        for i in range(det_bboxes.shape[0]):

            xmin, ymin, xmax, ymax = max(int((det_bboxes[i,0] - left) * ratiow), 0), max(int((det_bboxes[i,1] - top) * ratioh), 0), min(
                int((det_bboxes[i,2] - left) * ratiow), srcimg.shape[1]), min(int((det_bboxes[i,3] - top) * ratioh), srcimg.shape[0])
            #print(det_classid[i], det_conf[i])
            anchor.append([xmin, ymin, xmax, ymax])
            label.append(classes[det_classid[i]])
            #print(anchor[-1],label[-1])
            self.drawPred(drawimg, det_classid[i], det_conf[i], xmin, ymin, xmax, ymax)
        return drawimg

    def post_process(self, preds):
        cls_scores, bbox_preds = preds[::2], preds[1::2]
        det_bboxes, det_conf, det_classid = self.get_bboxes_single(cls_scores, bbox_preds, 1, rescale=False)
        return det_bboxes.astype(np.int32), det_conf, det_classid
    def get_bboxes_single(self, cls_scores, bbox_preds, scale_factor, rescale=False):
        mlvl_bboxes = []
        mlvl_scores = []
        for stride, cls_score, bbox_pred, anchors in zip(self.strides, cls_scores, bbox_preds, self.mlvl_anchors):
            if cls_score.ndim==3:
                cls_score = cls_score.squeeze(axis=0)
            if bbox_pred.ndim==3:
                bbox_pred = bbox_pred.squeeze(axis=0)
            bbox_pred = self.softmax(bbox_pred.reshape(-1, self.reg_max + 1), axis=1)
            # bbox_pred = np.sum(bbox_pred * np.expand_dims(self.project, axis=0), axis=1).reshape((-1, 4))
            bbox_pred = np.dot(bbox_pred, self.project).reshape(-1,4)
            bbox_pred *= stride

            # nms_pre = cfg.get('nms_pre', -1)
            nms_pre = 1000
            if nms_pre > 0 and cls_score.shape[0] > nms_pre:
                max_scores = cls_score.max(axis=1)
                topk_inds = max_scores.argsort()[::-1][0:nms_pre]
                anchors = anchors[topk_inds, :]
                bbox_pred = bbox_pred[topk_inds, :]
                cls_score = cls_score[topk_inds, :]

            bboxes = self.distance2bbox(anchors, bbox_pred, max_shape=self.input_shape)
            mlvl_bboxes.append(bboxes)
            mlvl_scores.append(cls_score)

        mlvl_bboxes = np.concatenate(mlvl_bboxes, axis=0)
        if rescale:
            mlvl_bboxes /= scale_factor
        mlvl_scores = np.concatenate(mlvl_scores, axis=0)

        bboxes_wh = mlvl_bboxes.copy()
        bboxes_wh[:, 2:4] = bboxes_wh[:, 2:4] - bboxes_wh[:, 0:2]  ####xywh
        classIds = np.argmax(mlvl_scores, axis=1)
        confidences = np.max(mlvl_scores, axis=1)  ####max_class_confidence

        indices = cv2.dnn.NMSBoxes(bboxes_wh.tolist(), confidences.tolist(), self.prob_threshold, self.iou_threshold)
        if len(indices)>0:
            mlvl_bboxes = mlvl_bboxes[indices[:, 0]]
            confidences = confidences[indices[:, 0]]
            classIds = classIds[indices[:, 0]]
            return mlvl_bboxes, confidences, classIds
        else:
            print('nothing detect')
            return np.array([]), np.array([]), np.array([])
    def distance2bbox(self, points, distance, max_shape=None):
        x1 = points[:, 0] - distance[:, 0]
        y1 = points[:, 1] - distance[:, 1]
        x2 = points[:, 0] + distance[:, 2]
        y2 = points[:, 1] + distance[:, 3]
        if max_shape is not None:
            x1 = np.clip(x1, 0, max_shape[1])
            y1 = np.clip(y1, 0, max_shape[0])
            x2 = np.clip(x2, 0, max_shape[1])
            y2 = np.clip(y2, 0, max_shape[0])
        return np.stack([x1, y1, x2, y2], axis=-1)

    def drawPred(self, frame, classId, conf, left, top, right, bottom):
        # Draw a bounding box.
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), thickness=4)

        label = '%.2f' % conf
        label = '%s:%s' % (self.classes[classId], label)

        # Display the label at the top of the bounding box
        labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
        top = max(top, labelSize[1])
        # cv.rectangle(frame, (left, top - round(1.5 * labelSize[1])), (left + round(1.5 * labelSize[0]), top + baseLine), (255,255,255), cv.FILLED)
        cv2.putText(frame, label, (left, top - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), thickness=2)
        return frame

#使用多进程
def main_thread():
    parser = argparse.ArgumentParser()
    parser.add_argument('--video_path', type=str, default='检测视频.avi', help="video path")
    parser.add_argument('--model_path', type=str, default='new.onnx', help='(.onnx)model')
    args = parser.parse_args()
    args.filename = args.video_path
    args.input_shape  = 320     #input image shape
    args.confThreshold= 0.37    #class confidence
    args.nmsThreshold = 0.6     #nms iou thresh

    import json
    file = open('test.json', 'w')

    net = my_nanodet(input_shape=args.input_shape, prob_threshold=args.confThreshold, iou_threshold=args.nmsThreshold,model=args.model_path)
    cam = Camera(args)  # get video
    cam.open()
    cam.start()

    import time
    # 推理
    while cam.thread_running:
        img = cam.read()
        a = time.time()
        srcimg = net.detect(img)
        b = time.time()
        time_w = b - a
        print('waste time', time_w * 1000)
        cv2.imshow('video test', srcimg)
    cv2.destroyAllWindows()

def main_one():
    parser = argparse.ArgumentParser()
    parser.add_argument('--video_path', type=str, default='检测视频.avi', help="video path")
    parser.add_argument('--model_path', type=str, default='new.onnx', help='(.onnx)model')
    args = parser.parse_args()
    args.input_shape  = 320     #input image shape
    args.confThreshold= 0.37    #class confidence
    args.nmsThreshold = 0.6     #nms iou thresh

    import json
    file = open('test.json', 'w')

    capure = cv2.VideoCapture(args.video_path)#get video
    net = my_nanodet(input_shape=args.input_shape, prob_threshold=args.confThreshold, iou_threshold=args.nmsThreshold,model=args.model_path)

    import time

    #推理
    if capure.isOpened():
        while True:
            ret,img = capure.read()
            if not ret: break
            #获取到图像
            a = time.time()
            srcimg = net.detect(img)
            b = time.time()
            time_w = b - a
            print('waste time', time_w*1000)
            cv2.imshow('video test', srcimg)
            cv2.waitKey(1)
        cv2.destroyAllWindows()

    else:
        print('open video error')

if __name__== '__main__':
    main_one()

可视化检测结果

边缘人工智能——nanodet模型实践指引,从标注数据集到实现部署文件        第二段代码有很多冗余的部分,那部分是我想实现多线程但是没写出来,如果多线程把读取视频和推理放在不同线程里进行的话还能让网络更快(更即时),还想实现多线程的同学可以看这篇文http://t.csdn.cn/OqHlN。

更新

        两个人做拿了省级三等奖,还行。

 

 

        

        

 文章来源地址https://www.toymoban.com/news/detail-461866.html

到了这里,关于边缘人工智能——nanodet模型实践指引,从标注数据集到实现部署文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mixtral 8X7B MoE模型基于阿里云人工智能平台PAI实践合集

    作者:熊兮、贺弘、临在 Mixtral 8x7B大模型是Mixtral AI推出的基于decoder-only架构的稀疏专家混合网络(Mixture-Of-Experts,MOE)开源大语言模型。这一模型具有46.7B的总参数量,对于每个token,路由器网络选择八组专家网络中的两组进行处理,并且将其输出累加组合,在增加模型参数

    2024年01月17日
    浏览(47)
  • AI天后,在线飙歌,人工智能AI孙燕姿模型应用实践,复刻《遥远的歌》,原唱晴子(Python3.10)

    忽如一夜春风来,亚洲天后孙燕姿独特而柔美的音色再度响彻华语乐坛,只不过这一次,不是因为她出了新专辑,而是人工智能AI技术对于孙燕姿音色的完美复刻,以大江灌浪之势对华语歌坛诸多经典作品进行了翻唱,还原度令人咋舌,如何做到的? 本次我们借助基于Python3.

    2024年02月03日
    浏览(49)
  • LDGRB-01 用于在边缘处理人工智能的嵌入式硬件

    LDGRB-01  用于在边缘处理人工智能的嵌入式硬件商业和企业中的IT系统正在全面快速发展,一个不断增长的趋势正在将计算能力推向边缘。Gartner预测,到2025年,边缘计算将处理75%的数据由所有用例产生,包括工厂、医疗保健和运输中的用例。您可以将边缘计算的采用与人工智

    2024年02月07日
    浏览(49)
  • 【人工智能】深入了解人工智能的核心算法与应用实践

    人工智能知识对于当今的互联网技术人来说已经是刚需。但人工智能的概念、流派、技术纷繁复杂,选择哪本书入门最适合呢? 这部被誉为人工智能“百科全书”的《人工智能(第3版)》,可以作为每个技术人进入 AI 世界的第一本书。 这本书是美国人工智能领域的权威经典

    2024年02月03日
    浏览(64)
  • 人工智能与人类智能的解决问题能力在人工智能应用领域的实践

    人工智能(Artificial Intelligence, AI)是一门研究如何让计算机模拟人类智能行为的科学。人类智能包括学习、理解语言、认知、决策等多种能力。人工智能的目标是让计算机具备类似于人类智能的能力,以解决复杂的问题。 在过去的几十年里,人工智能技术已经取得了显著的进展

    2024年02月20日
    浏览(54)
  • 基于人工智能与边缘计算Aidlux的鸟类检测驱赶系统(可修改为coco 80类目标检测)

    ●项目名称 基于人工智能与边缘计算Aidlux的鸟类检测驱赶系统(可修改为coco 80类目标检测) ●项目简介 本项目在Aidlux上部署鸟类检测驱赶系统,通过视觉技术检测到有鸟类时,会进行提示。并可在源码上修改coco 80类目标检测索引直接检测其他79类目标,可以直接修改、快速

    2024年02月12日
    浏览(53)
  • 【人工智能大脑】仿生学与人工智能交汇:基于MP神经网络的精准农业实践

    MP神经网络,即McCulloch-Pitts模型(MCP Model),是神经网络的早期形式之一,由Warren McCulloch和Walter Pitts在1943年提出。这个模型为现代人工神经网络的发展奠定了理论基础,并首次尝试模拟了生物神经元的工作原理。 MCP由来 深度学习的历史可以追溯到1943年,当时Walter Pitts(数学

    2024年01月23日
    浏览(61)
  • 【实践探索】人工智能语音转换技术的实践经验和优化建议

    [toc] 【实践探索】人工智能语音转换技术的实践经验和优化建议 随着人工智能技术的快速发展,语音识别技术作为其基础应用之一,也得到了越来越广泛的应用。针对目前市场上主流的人工智能语音识别技术,本文将深入探讨其原理、实现过程以及优化建议。本文将重点分析

    2024年02月06日
    浏览(70)
  • 人工智能的伦理管理实践与探索案例

    作者:禅与计算机程序设计艺术 人工智能的伦理管理实践与探索案例 引言 1.1. 背景介绍 随着人工智能技术的快速发展,伦理问题也逐渐成为了人工智能领域的一个重要问题。伦理问题的种类很多,包括隐私保护、数据安全、歧视、安全漏洞等。在人工智能的应用过程中,如

    2024年02月06日
    浏览(54)
  • ChatGPT人工智能自动化编程应用实践

    随着人工智能技术的发展,软件开发的需求和难度也不断增加。传统的软件开发方法,需要程序员编写大量的代码,耗时耗力,而且容易出错。为了提高软件开发的效率和质量,人工智能生成代码(AIGC)技术应运而生。AIGC技术利用人工智能模型,根据用户的需求或示例,自

    2024年02月04日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包