電子發(fā)燒友App

硬聲App

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示
創(chuàng)作
電子發(fā)燒友網(wǎng)>電子資料下載>電子資料>Ultra96皮膚癌AI構(gòu)建

Ultra96皮膚癌AI構(gòu)建

2022-10-21 | zip | 1.56 MB | 次下載 | 免費(fèi)

資料介紹

描述

我們?yōu)槭裁匆獦?gòu)建皮膚癌 AI

根據(jù)皮膚癌基金會(huì)的數(shù)據(jù),美國一半的人口在 65 歲之前被診斷出患有某種形式的皮膚癌。早期發(fā)現(xiàn)的存活率幾乎是 98%,但當(dāng)癌癥到達(dá)淋巴結(jié)時(shí),存活率會(huì)下降到 62%轉(zhuǎn)移到遠(yuǎn)處器官時(shí)為 18%。借助皮膚癌 AI,我們希望利用人工智能的力量提供盡可能廣泛的早期檢測(cè)。

?
poYBAGNR4z6AbkrhAACe-zH6O_A274.png
皮膚癌統(tǒng)計(jì)資料來源:Blue Scan Labs
?

什么是人工智能以及如何使用它?

深度學(xué)習(xí)最近是機(jī)器學(xué)習(xí)的一大趨勢(shì),最近的成功為構(gòu)建這樣的項(xiàng)目鋪平了道路。在這個(gè)示例中,我們將特別關(guān)注計(jì)算機(jī)視覺和圖像分類。為此,我們將使用深度學(xué)習(xí)算法、卷積神經(jīng)網(wǎng)絡(luò) (CNN) 通過 Caffe 框架構(gòu)建痣、黑色素瘤和脂溢性角化病圖像分類器。

?
pYYBAGNR40CAaI3bAADDc75xlEQ293.png
AI分類流程
?

在本文中,我們將重點(diǎn)關(guān)注監(jiān)督學(xué)習(xí),它需要在服務(wù)器上進(jìn)行訓(xùn)練以及在邊緣部署。我們的目標(biāo)是構(gòu)建一個(gè)可以實(shí)時(shí)檢測(cè)癌癥圖像的機(jī)器學(xué)習(xí)算法,這樣您就可以構(gòu)建自己的基于人工智能的皮膚癌分類設(shè)備。

我們的應(yīng)用程序?qū)▋刹糠?,第一部分是?xùn)練,我們將使用不同的癌癥圖像數(shù)據(jù)庫集來訓(xùn)練具有相應(yīng)標(biāo)簽的機(jī)器學(xué)習(xí)算法(模型)。第二部分是在邊緣部署,它使用我們訓(xùn)練過的相同模型并在邊緣設(shè)備上運(yùn)行,在本例中是通過 Ultra96 FPGA 的 Movidius 神經(jīng)計(jì)算棒。這樣 VPU 可以運(yùn)行推理,而 FPGA 可以執(zhí)行 OpenCV

傳統(tǒng)機(jī)器學(xué)習(xí) (ML) 與深度學(xué)習(xí)

這可能是人工智能中被問得最多的問題,一旦你學(xué)會(huì)了如何去做,它就相當(dāng)簡(jiǎn)單了。為了理解這一點(diǎn),我們首先必須了解機(jī)器學(xué)習(xí)圖像分類的工作原理。

機(jī)器學(xué)習(xí)需要特征提取和模型訓(xùn)練。我們首先必須使用領(lǐng)域知識(shí)來提取可用于我們的 ML 算法模型的特征,一些例子包括SIFTHoG。之后,我們可以使用包含所有圖像特征和標(biāo)簽的數(shù)據(jù)集來訓(xùn)練我們的機(jī)器學(xué)習(xí)模型。

傳統(tǒng) ML 和深度學(xué)習(xí)之間的主要區(qū)別在于特征工程。傳統(tǒng) ML 使用手動(dòng)編程的功能,而深度學(xué)習(xí)會(huì)自動(dòng)執(zhí)行。特征工程相對(duì)困難,因?yàn)樗枰I(lǐng)域?qū)I(yè)知識(shí)并且非常耗時(shí)。深度學(xué)習(xí)不需要特征工程,可以更準(zhǔn)確

?
poYBAGNR40KANX7mAACI7XlivuQ672.png
傳統(tǒng)機(jī)器學(xué)習(xí)與深度學(xué)習(xí)
?

人工神經(jīng)網(wǎng)絡(luò) (ANN)

根據(jù)技術(shù)百科,“人工神經(jīng)元網(wǎng)絡(luò)(ANN)是一種基于生物神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)和功能的計(jì)算模型?!?人工神經(jīng)元網(wǎng)絡(luò)在技術(shù)上模擬人類生物神經(jīng)元的工作方式,它具有有限數(shù)量的輸入、與它們相關(guān)的權(quán)重和激活功能。節(jié)點(diǎn)的激活函數(shù)定義了給定輸入或一組輸入的該節(jié)點(diǎn)的輸出,編碼復(fù)雜是非線性的。數(shù)據(jù)的模式。當(dāng)輸入進(jìn)來時(shí),激活函數(shù)應(yīng)用到輸入的權(quán)重和以生成輸出。人工神經(jīng)元相互連接形成一個(gè)網(wǎng)絡(luò),因此稱為人工神經(jīng)元網(wǎng)絡(luò)(ANN)。

?
pYYBAGNR40SAPF1WAABWyLJ_URg923.jpg
生物神經(jīng)元與人工神經(jīng)元。來源(維基百科)
?

饋神經(jīng)網(wǎng)絡(luò)是一種人工神經(jīng)網(wǎng)絡(luò),其中節(jié)點(diǎn)之間的連接不形成循環(huán),這是最簡(jiǎn)單的人工神經(jīng)網(wǎng)絡(luò)形式。它有 3 層,輸入層、隱藏層和輸出層,其中數(shù)據(jù)通過輸入層進(jìn)入,通過隱藏層到達(dá)輸出節(jié)點(diǎn),如下圖所示。我們可以有多個(gè)隱藏層,模型的復(fù)雜度與隱藏層的大小相關(guān)。

?
pYYBAGNR40aARFk4AABF5IiJqxo406.png
前饋神經(jīng)網(wǎng)絡(luò)。來源(維基百科)
?

訓(xùn)練數(shù)據(jù)和損失函數(shù)是用于訓(xùn)練神經(jīng)網(wǎng)絡(luò)的兩個(gè)元素。訓(xùn)練數(shù)據(jù)由圖像和相應(yīng)的標(biāo)簽組成;損失函數(shù)是衡量分類過程中不準(zhǔn)確的函數(shù)。一旦獲得了這兩個(gè)元素,我們就使用反向傳播算法和梯度下降來訓(xùn)練 ANN。

卷積神經(jīng)網(wǎng)絡(luò) (CNN)

卷積神經(jīng)網(wǎng)絡(luò)是一類深度前饋人工神經(jīng)網(wǎng)絡(luò),最常用于分析視覺圖像,因?yàn)樗荚谀M動(dòng)物視覺皮層上的生物行為。它由卷積層和池化層組成,因此網(wǎng)絡(luò)可以對(duì)圖像屬性進(jìn)行編碼。

?
pYYBAGNR40iAZGfoAABU90jP2RE042.png
典型的 CNN 網(wǎng)絡(luò)。來源(維基百科)
?

卷積層的參數(shù)由一組具有小感受野的可學(xué)習(xí)過濾器(或內(nèi)核)組成。這樣,圖像可以在空間上進(jìn)行卷積,計(jì)算過濾器條目和輸入之間的點(diǎn)積,并生成該過濾器的二維激活圖。通過這種方式,網(wǎng)絡(luò)可以學(xué)習(xí)在檢測(cè)到輸入圖像空間特征上的特殊特征時(shí)可以激活的過濾器。

?
pYYBAGNR40uAW4MEAAAq_1mRoCw972.png
卷積層的神經(jīng)元(藍(lán)色),連接到它們的感受野(紅色)。來源(維基百科)
?

池化層是非線性下采樣的一種形式。它將輸入圖像劃分為一組不重疊的矩形,并為每個(gè)這樣的子區(qū)域輸出最大值。其思想是不斷減小輸入表示的空間大小以減少網(wǎng)絡(luò)中的參數(shù)量和計(jì)算量,因此它也可以控制過擬合。最大池化是最常見的非線性池化類型。根據(jù)維基百科,“池化通常與大小為 2x2 的過濾器一起應(yīng)用,每個(gè)深度切片的步長(zhǎng)為 2。大小為 2x2 且步長(zhǎng)為 2 的池化層將輸入圖像縮小到其原始大小的 1/4?!?/font>

?
pYYBAGNR402Af38uAAA0ccS-7Sw482.png
最大池化。來源(維基百科)
?

皮膚癌 AI 組件

該項(xiàng)目所需的設(shè)備非常簡(jiǎn)單,您可以使用計(jì)算機(jī)和 USB Movidius 神經(jīng)計(jì)算棒和 Ultra96 板來完成。

  • Ultra96 板
  • 內(nèi)窺鏡相機(jī)
  • Movidius 神經(jīng)計(jì)算棒
  • 屏幕或監(jiān)視器
?
poYBAGNR40-AQJIKAAL---98xQk805.jpg
使用的設(shè)備
?

第 1 步:安裝 PYNQ Linux

Ultra96 是相當(dāng)新的,但支持小組非常友好地讓基本的 Ubuntu 運(yùn)行,這很重要,因?yàn)檫@讓我可以在 ultra96 上構(gòu)建不同的平臺(tái)。編譯好的debian可以從https://fileserver.linaro.org/owncloud/index.php/s/jTt3MYSuwtLuf9d下載,之后我們可以使用ether之類的工具把它加載到mini-sd卡上。

?
pYYBAGNR41KAB42bAAAjzXjDwco744.png
?

啟動(dòng)后,我們首先必須通過刪除損壞的存儲(chǔ)庫來修復(fù)一些錯(cuò)誤。

sudo rm -r /var/lib/apt/lists/*

這使我們可以根據(jù)需要安裝所有軟件包以使用該平臺(tái)。

?
poYBAGNR41SAfebiAADzL-fkm6c157.png
?

第 2 步:安裝 Movidius NCSDK

因此,為了讓 AI 和計(jì)算機(jī)視覺發(fā)揮作用,我們可以利用 Movidius NCS 來運(yùn)行我們的項(xiàng)目。Ultra96 沒有演練,所以我們基本上通過 https://movidius.github.io/blog/ncs-apps-on-rpi/ 引用了這個(gè)

首先我們必須安裝依賴項(xiàng),這部分不附帶 PYNQ,所以我們將安裝它們以確保一切正常。

apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools libgstreamer-plugins-base1.0-dev
apt-get install libgtk-3-dev
apt-get install -y libprotobuf-dev libleveldb-dev libsnappy-dev
apt-get install -y  libopencv-dev libhdf5-serial-dev 
apt-get install -y protobuf-compiler byacc libgflags-dev 
apt-get install -y libgoogle-glog-dev liblmdb-dev libxslt-dev 

接下來我們可以安裝 NCSDK SDK,它包含可以將應(yīng)用程序連接到 NCS 的 API。由于 NCSDK 不是為 Ultra96 構(gòu)建的,我們可以對(duì)markjay4k版本的解決方法進(jìn)行以下修改

cd /home/xilinx/
mkdir -p workspace
cd workspace
git clone https://github.com/markjay4k/ncsdk-aarch64.git
cd ncsdk/api/src
make
make install

這個(gè)解決方法應(yīng)該讓我們使用 Ultra96 和 PYNQ 的 NCSDK API

?
poYBAGNR41eAKP64AAJFJAk-FfI430.png
PYNQ 上的 NCSDK
?

接下來我們將嘗試讓 NcAppZoo 和 Hello World 為 Neural Computing Stick 運(yùn)行,我們需要在 pynq 上重復(fù)舊的 python 3.6

cd /home/xilinx/workspace
git clone https://github.com/movidius/ncappzoo
cd ncappzoo/apps/hello_ncs_py
make run

你剛剛讓 NCS 在 aarch64 上運(yùn)行 :)

?
poYBAGNR41qASisVAAF19QhENNk983.png
NCS 在 aarch64 上工作
?

第 3 步:使用 Ultra96 和 NCS 實(shí)現(xiàn)邊緣人工智能

我們可以通過多種方式制作觸發(fā)器,因?yàn)檫@是一個(gè)基于 AI 的應(yīng)用程序,我將制作一個(gè)基于 AI 的觸發(fā)器。在本指南中,我們將使用經(jīng)過預(yù)訓(xùn)練并使用 Caffe 的 SSD 神經(jīng)網(wǎng)絡(luò),檢測(cè)結(jié)果將是垃圾。因此,我們還將學(xué)習(xí)如何通過一些工作來利用其他神經(jīng)網(wǎng)絡(luò)。

?
poYBAGNR416AU94VAAdhAOpo7p8738.jpg
Ultra96 與 Movidius NCS
?

在這一步中,我們之前已經(jīng)訓(xùn)練了通過 caffe 模型,我們必須在另一臺(tái)機(jī)器上編譯圖形,因?yàn)槲覀冎话惭b了 API 而不是工具包,因?yàn)樗鼈儾皇菫?aarch64 構(gòu)建的。然而,由于 API 有效,我們可以簡(jiǎn)單地在另一臺(tái)機(jī)器上構(gòu)建它并將圖形文件傳輸?shù)?Ultra96。FPGA 可以處理所有的 CV2,這里的 Movidius NCS 將運(yùn)行推理以進(jìn)行對(duì)象檢測(cè)和圖像分類,如下圖所示,我們將通過在這里進(jìn)行實(shí)時(shí)圖像分類來確定基礎(chǔ)。

?
pYYBAGNR42GAd4UQAAMB_GZEB0Q378.png
性別的圖像分類
?

第 4 步:收集皮膚癌的圖像數(shù)據(jù)集

我們首先需要皮膚癌數(shù)據(jù)集,雖然有很多地方可以獲取,但 isic-archive 成為最簡(jiǎn)單的一個(gè)。對(duì)于這部分,我們只需要大約 500 張痣、黑色素瘤和脂溢性角化病之間的圖像,以及 500 張其他任何東西的隨機(jī)圖像。為了獲得更高的準(zhǔn)確性,我們必須使用更多的數(shù)據(jù),這只是為了開始訓(xùn)練。獲取數(shù)據(jù)的最簡(jiǎn)單方法是通過下面的圖片使用 https://isic-archive.com/#images

?
pYYBAGNR42OAXmpCAAC1jLAZhYQ459.png
ISIC 檔案
?

之后,我們可以將圖像標(biāo)記到一個(gè)文件夾中,并將它們命名為 nevus-00.jpg、melanoma-00.jpg 以便我們可以輕松地構(gòu)建我們的 lmdb。

?
poYBAGNR42WAJEBbAAEC-XTZSyM107.png
從 ISIC 獲取數(shù)據(jù)
?

第 5 步:設(shè)置訓(xùn)練服務(wù)器

機(jī)器學(xué)習(xí)訓(xùn)練使用了大量的處理能力,因此它們通常成本很高。在本文中,我們將重點(diǎn)介紹面向英特爾 AI Academy成員免費(fèi)提供的 AI DevCloud。

為了構(gòu)建皮膚癌 AI,我們使用 Caffe 框架,主要是因?yàn)橛⑻貭?Movidius NCS 的 AI on the Edge 支持。Caffe 是由伯克利視覺與學(xué)習(xí)中心 (BVLC) 開發(fā)的深度學(xué)習(xí)框架,使用 caffe 框架訓(xùn)練我們的算法模型有 4 個(gè)步驟。這樣,Xilinx 的 FPGA 可以專注于 openCV,NCS 可以專注于推理。

  • 數(shù)據(jù)準(zhǔn)備,我們清理圖像并將它們存儲(chǔ)到 LMDB。
  • 模型定義 prototxt 文件,定義參數(shù)并選擇 CNN 架構(gòu)。
  • Solver Definition prototxt 文件,定義模型優(yōu)化的求解器參數(shù)
  • 模型訓(xùn)練,我們執(zhí)行caffe命令得到我們的.caffemodel算法文件

在 Devcloud 上,我們可以檢查這些是否可用,只需轉(zhuǎn)到

cd /glob/deep-learning/py-faster-rcnn/caffe-fast-rcnn/build/tools

第 6 步:準(zhǔn)備 LMDB 進(jìn)行訓(xùn)練

一旦我們?cè)O(shè)置好 DevCloud,我們就可以構(gòu)建它

mkdir skincancerai
cd skincancerai
mkdir input
cd input
mkdir train 

從那里我們可以將我們之前設(shè)置的所有數(shù)據(jù)放入文件夾中

scp ./* colfax:/home/[youruser_name]/skincancerai/input/train/

之后,我們可以通過這種方式構(gòu)建我們的 lmdb。我們通過以下幾組來做到這一點(diǎn)

  • 數(shù)據(jù)集的 5/6 將用于訓(xùn)練,1/6 用于驗(yàn)證,因此我們可以計(jì)算模型的準(zhǔn)確性
  • 我們將所有圖像的大小調(diào)整為 227x227,以遵循與 BVLC 相同的標(biāo)準(zhǔn)
  • 直方圖均衡化應(yīng)用于所有訓(xùn)練圖像以調(diào)整對(duì)比度。
  • 并將它們存儲(chǔ)在 train_lmdb 和 validation_lmdb 中
  • 使用 make_datum 標(biāo)記 lmdb 內(nèi)的所有圖像數(shù)據(jù)集
import os
import glob
import random
import numpy as np
import cv2
import caffe
from caffe.proto import caffe_pb2
import lmdb
#We use 227x227 from BVLC
IMAGE_WIDTH = 227
IMAGE_HEIGHT = 227
def transform_img(img, img_width=IMAGE_WIDTH, img_height=IMAGE_HEIGHT):
  img[:, :, 0] = cv2.equalizeHist(img[:, :, 0])
  img[:, :, 1] = cv2.equalizeHist(img[:, :, 1])
  img[:, :, 2] = cv2.equalizeHist(img[:, :, 2])
  img = cv2.resize(img, (img_width, img_height), interpolation = cv2.INTER_CUBIC)
  return img
def make_datum(img, label):
  return caffe_pb2.Datum(
      channels=3,
      width=IMAGE_WIDTH,
      height=IMAGE_HEIGHT,
      label=label,
      data=np.rollaxis(img, 2).tostring())
train_lmdb = '/home/[your_username]/skincancerai/input/train_lmdb'
validation_lmdb = '/home/[youser_username]/skincancerai/input/validation_lmdb'
os.system('rm -rf  ' + train_lmdb)
os.system('rm -rf  ' + validation_lmdb)
train_data = [img for img in glob.glob("./input/train/*jpg")]
random.shuffle(train_data)
print 'Creating train_lmdb'
in_db = lmdb.open(train_lmdb, map_size=int(1e12))
with in_db.begin(write=True) as in_txn:
  for in_idx, img_path in enumerate(train_data):
      if in_idx %  6 == 0:
          continue
      img = cv2.imread(img_path, cv2.IMREAD_COLOR)
      img = transform_img(img, img_width=IMAGE_WIDTH, img_height=IMAGE_HEIGHT)
      if 'none' in img_path:
          label = 0
      elif 'nevus' in img_path:
          label = 1
      elif 'melanoma' in img_path:
          label = 2
      else:
          label = 3
      datum = make_datum(img, label)
      in_txn.put('{:0>5d}'.format(in_idx), datum.SerializeToString())
      print '{:0>5d}'.format(in_idx) + ':' + img_path
in_db.close()
print '\nCreating validation_lmdb'
in_db = lmdb.open(validation_lmdb, map_size=int(1e12))
with in_db.begin(write=True) as in_txn:
  for in_idx, img_path in enumerate(train_data):
      if in_idx % 6 != 0:
          continue
      img = cv2.imread(img_path, cv2.IMREAD_COLOR)
      img = transform_img(img, img_width=IMAGE_WIDTH, img_height=IMAGE_HEIGHT)
      if 'none' in img_path:
          label = 0
      elif 'nevus' in img_path:
          label = 1
      elif 'melanoma' in img_path:
          label = 2
      else:
          label = 3
      datum = make_datum(img, label)
      in_txn.put('{:0>5d}'.format(in_idx), datum.SerializeToString())
      print '{:0>5d}'.format(in_idx) + ':' + img_path
in_db.close()
print '\nFinished processing all images'

之后我們將運(yùn)行腳本

python2 create_lmdb.py

獲取所有 LMDB。完成后,我們需要獲取訓(xùn)練數(shù)據(jù)的平均圖像。作為 caffe 的一部分,我們可以通過

cd /glob/deep-learning/py-faster-rcnn/caffe-fast-rcnn/build/toolscompute_image_mean -backend=lmdb /home/[your_user]/skincancerai/input/train_lmdb /home/[your_user]/skincancerai/input/mean.binaryproto

上面的命令將生成訓(xùn)練數(shù)據(jù)的平均圖像。每個(gè)輸入圖像將減去平均圖像,使每個(gè)特征像素的均值為零。這是監(jiān)督機(jī)器學(xué)習(xí)預(yù)處理中常用的方法。

第 7 步:設(shè)置模型定義和求解器定義

我們現(xiàn)在需要設(shè)置模型定義和求解器定義,在本文中我們將使用 bvlc_reference_net,可以在https://github.com/BVLC/caffe/tree/master/models/bvlc_reference_caffenet看到

下面是 train.prototxt 的修改版本

name: "CaffeNet"
layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
  phase: TRAIN
}
transform_param {
  mirror: true
  crop_size: 227
  mean_file: "/home/[your_username]/skincancerai/input/mean.binaryproto"
}
data_param {
  source: "/home/[your_username]/skincancerai/input/train_lmdb"
  batch_size: 128
  backend: LMDB
}
}
layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
  phase: TEST
}
transform_param {
  mirror: false
  crop_size: 227
  mean_file: "/home/[your_username]/skincancerai/input/mean.binaryproto"
}
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: true
#  }
data_param {
  source: "/home/[your_username]/skincancerai/input/validation_lmdb"
  batch_size: 36
  backend: LMDB
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 96
  kernel_size: 11
  stride: 4
  weight_filler {
    type: "gaussian"
    std: 0.01
  }
  bias_filler {
    type: "constant"
    value: 0
  }
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
  pool: MAX
  kernel_size: 3
  stride: 2
}
}
layer {
name: "norm1"
type: "LRN"
bottom: "pool1"
top: "norm1"
lrn_param {
  local_size: 5
  alpha: 0.0001
  beta: 0.75
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "norm1"
top: "conv2"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 256
  pad: 2
  kernel_size: 5
  group: 2
  weight_filler {
    type: "gaussian"
    std: 0.01
  }
  bias_filler {
    type: "constant"
    value: 1
  }
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
  pool: MAX
  kernel_size: 3
  stride: 2
}
}
layer {
name: "norm2"
type: "LRN"
bottom: "pool2"
top: "norm2"
lrn_param {
  local_size: 5
  alpha: 0.0001
  beta: 0.75
}
}
layer {
name: "conv3"
type: "Convolution"
bottom: "norm2"
top: "conv3"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 384
  pad: 1
  kernel_size: 3
  weight_filler {
    type: "gaussian"
    std: 0.01
  }
  bias_filler {
    type: "constant"
    value: 0
  }
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "conv4"
type: "Convolution"
bottom: "conv3"
top: "conv4"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 384
  pad: 1
  kernel_size: 3
  group: 2
  weight_filler {
    type: "gaussian"
    std: 0.01
  }
  bias_filler {
    type: "constant"
    value: 1
  }
}
}
layer {
name: "relu4"
type: "ReLU"
bottom: "conv4"
top: "conv4"
}
layer {
name: "conv5"
type: "Convolution"
bottom: "conv4"
top: "conv5"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 256
  pad: 1
  kernel_size: 3
  group: 2
  weight_filler {
    type: "gaussian"
    std: 0.01
  }
  bias_filler {
    type: "constant"
    value: 1
  }
}
}
layer {
name: "relu5"
type: "ReLU"
bottom: "conv5"
top: "conv5"
}
layer {
name: "pool5"
type: "Pooling"
bottom: "conv5"
top: "pool5"
pooling_param {
  pool: MAX
  kernel_size: 3
  stride: 2
}
}
layer {
name: "fc6"
type: "InnerProduct"
bottom: "pool5"
top: "fc6"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
inner_product_param {
  num_output: 4096
  weight_filler {
    type: "gaussian"
    std: 0.005
  }
  bias_filler {
    type: "constant"
    value: 1
  }
}
}
layer {
name: "relu6"
type: "ReLU"
bottom: "fc6"
top: "fc6"
}
layer {
name: "drop6"
type: "Dropout"
bottom: "fc6"
top: "fc6"
dropout_param {
  dropout_ratio: 0.5
}
}
layer {
name: "fc7"
type: "InnerProduct"
bottom: "fc6"
top: "fc7"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
inner_product_param {
  num_output: 4096
  weight_filler {
    type: "gaussian"
    std: 0.005
  }
  bias_filler {
    type: "constant"
    value: 1
  }
}
}
layer {
name: "relu7"
type: "ReLU"
bottom: "fc7"
top: "fc7"
}
layer {
name: "drop7"
type: "Dropout"
bottom: "fc7"
top: "fc7"
dropout_param {
  dropout_ratio: 0.5
}
}
layer {
name: "fc8"
type: "InnerProduct"
bottom: "fc7"
top: "fc8"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
inner_product_param {
  num_output: 4
  weight_filler {
    type: "gaussian"
    std: 0.01
  }
  bias_filler {
    type: "constant"
    value: 0
  }
}
}
layer {
name: "accuracy"
type: "Accuracy"
bottom: "fc8"
bottom: "label"
top: "accuracy"
include {
  phase: TEST
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "fc8"
bottom: "label"
top: "loss"
} 
?
poYBAGNR42iAefnYAABUuBDvuVk752.png
Caffe 模型的可視化表示
?

同時(shí)我們可以創(chuàng)建基于 train.prototxt 構(gòu)建的 deploy.prototxt。這可以從 github repo 中看到。我們還將像創(chuàng)建 lmdb 文件一樣創(chuàng)建 label.txt 文件

classes
None
Nevus
Melanoma 
Seborrheic Keratosis

之后我們需要solver.prototxt中的Solver Definition,它用于優(yōu)化訓(xùn)練模型。因?yàn)槲覀円蕾?a href='http://www.ttokpm.com/v/tag/132/' target='_blank' class='arckwlink_none'>CPU,所以我們需要對(duì)下面的求解器定義做一些修改。

net: "/home/[your_username]/skincancerai/model/train.prototxt"
test_iter: 50
test_interval: 50
base_lr: 0.001
lr_policy: "step"
gamma: 0.1
stepsize: 50
display: 50
max_iter: 5000
momentum: 0.9
weight_decay: 0.0005
snapshot: 1000
snapshot_prefix: "/home/[your_username]/skincancerai/model"
solver_mode: CPU 

因?yàn)槲覀冊(cè)谶@里處理的數(shù)據(jù)量很小,所以我們可以縮短測(cè)試迭代并盡可能快地獲得我們的模型。簡(jiǎn)而言之,求解器將使用驗(yàn)證集每 50 次迭代計(jì)算模型的準(zhǔn)確性。由于我們沒有大量數(shù)據(jù),求解器優(yōu)化過程將每 1000 次迭代拍攝一次快照,最多運(yùn)行 5000 次迭代。lr_policy: "step", stepsize: 2500, base_lr: 0.001 and gamma: 0.1 的當(dāng)前配置是相當(dāng)標(biāo)準(zhǔn)的,因?yàn)槲覀円部梢酝ㄟ^bvlc 求解器文檔嘗試使用其他配置。

第 8 步:訓(xùn)練模型

由于我們使用的是免費(fèi)的 AI DevCloud 并且一切就緒,我們可以使用Intel Caffe ,它使用安裝在集群上的 Intel CPU 進(jìn)行了優(yōu)化。由于這是一個(gè)集群,我們可以使用以下命令簡(jiǎn)單地開始訓(xùn)練。

cd /glob/deep-learning/py-faster-rcnn/caffe-fast-rcnn/build/toolsecho caffe train --solver ~/skincancerai/model/solver.prototxt | qsub -o ~/skincancerai/model/output.txt -e ~/skincancerai/model/train.log

訓(xùn)練后的模型將是model_iter_1000.caffemodel、model_iter_2000.caffemodel等。使用 ISIC 提供的數(shù)據(jù),您應(yīng)該獲得大約 70% 到 80% 的準(zhǔn)確度。您可以通過以下命令繪制自己的曲線,

cd ~/skincancerai python2 plot_learning_curve.py ./model/train.log ./model/train.png
?
pYYBAGNR42qAFbXxAABgq6MW0PI304.png
訓(xùn)練曲線
?

第 9 步:在具有 NCS 的 Ultra96 上部署和運(yùn)行

在本文中,我們使用 Ultra96,這樣我們就可以擁有一個(gè)可以隨身攜帶的離線設(shè)備。我們已經(jīng)在步驟 3 上運(yùn)行了示例。由于我們?cè)?aarch64 上沒有激活工具包,我們可以在另一臺(tái)機(jī)器上運(yùn)行編譯,然后將其復(fù)制到 ultra96

mvNCCompile deploy.prototxt -w 
model_iter_1000.caffemodel,model_iter_2000.caffemodel

這將為您提供圖形文件,復(fù)制圖形文件和標(biāo)簽文件并將其與我們修改的以下代碼一起放在 CancerNet 下,將其復(fù)制到 Ultra96。我們現(xiàn)在有一個(gè)可以在家中使用的皮膚癌檢測(cè)設(shè)備。我們可以在CancerNet下使用圖形文件和categories.txt文件部署以下代碼

#!/usr/bin/python3
# ****************************************************************************
# Copyright(c) 2017 Intel Corporation. 
# License: MIT See LICENSE file in root directory.
# ****************************************************************************
# Perform inference on a LIVE camera feed using DNNs on 
# Intel? Movidius? Neural Compute Stick (NCS)
import os
import cv2
import sys
import numpy
import ntpath
import argparse
import mvnc.mvncapi as mvnc
# Variable to store commandline arguments
ARGS                 = None
# OpenCV object for video capture
camera               = None
# ---- Step 1: Open the enumerated device and get a handle to it -------------
def open_ncs_device():
   # Look for enumerated NCS device(s); quit program if none found.
   devices = mvnc.EnumerateDevices()
   if len( devices ) == 0:
       print( "No devices found" )
       quit()
   # Get a handle to the first enumerated device and open it
   device = mvnc.Device( devices[0] )
   device.OpenDevice()
   return device
# ---- Step 2: Load a graph file onto the NCS device -------------------------
def load_graph( device ):
   # Read the graph file into a buffer
   with open( ARGS.graph, mode='rb' ) as f:
       blob = f.read()
   # Load the graph buffer into the NCS
   graph = device.AllocateGraph( blob )
   return graph
# ---- Step 3: Pre-process the images ----------------------------------------
def pre_process_image( frame ):
   # Resize image [Image size is defined by choosen network, during training]
   img = cv2.resize( frame, tuple( ARGS.dim ) )
   # Extract/crop a section of the frame and resize it
   height, width, channels = frame.shape
   x1 = int( width / 3 )
   y1 = int( height / 4 )
   x2 = int( width * 2 / 3 )
   y2 = int( height * 3 / 4 )
   cv2.rectangle( frame, ( x1, y1 ) , ( x2, y2 ), ( 0, 255, 0 ), 2 )
   img = frame[ y1 : y2, x1 : x2 ]
   # Resize image [Image size if defined by choosen network, during training]
   img = cv2.resize( img, tuple( ARGS.dim ) )
   # Convert BGR to RGB [OpenCV reads image in BGR, some networks may need RGB]
   if( ARGS.colormode == "rgb" ):
       img = img[:, :, ::-1]
   # Mean subtraction & scaling [A common technique used to center the data]
   img = img.astype( numpy.float16 )
   img = ( img - numpy.float16( ARGS.mean ) ) * ARGS.scale
   return img
# ---- Step 4: Read & print inference results from the NCS -------------------
def infer_image( graph, img, frame ):
   # Load the image as a half-precision floating point array
   graph.LoadTensor( img, 'user object' )
   # Get the results from NCS
   output, userobj = graph.GetResult()
   # Find the index of highest confidence 
   top_prediction = output.argmax()
   # Get execution time
   inference_time = graph.GetGraphOption( mvnc.GraphOption.TIME_TAKEN )
   print(  "I am %3.1f%%" % (100.0 * output[top_prediction] ) + " confidant"
           + " it is " + labels[top_prediction]
           + " ( %.2f ms )" % ( numpy.sum( inference_time ) ) )
   displaystring = str(100.0 * output[top_prediction]) + " " + labels[top_prediction]
   # If a display is available, show the image on which inference was performed
   if 'DISPLAY' in os.environ:
       textsize = cv2.getTextSize(displaystring, cv2.FONT_HERSHEY_SIMPLEX, 1, 2)[0]
       textX = (frame.shape[1] - textsize[0])/2
       cv2.putText(frame, displaystring, (int(textX),450), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,0),2)
       cv2.imshow( 'Skin Cancer AI', frame )
# ---- Step 5: Unload the graph and close the device -------------------------
def close_ncs_device( device, graph ):
   graph.DeallocateGraph()
   device.CloseDevice()
   camera.release()
   cv2.destroyAllWindows()
# ---- Main function (entry point for this script ) --------------------------
def main():
   device = open_ncs_device()
   graph = load_graph( device )
   # Main loop: Capture live stream & send frames to NCS
   while( True ):
       ret, frame = camera.read()
       img = pre_process_image( frame )
       infer_image( graph, img, frame )
       # Display the frame for 5ms, and close the window so that the next
       # frame can be displayed. Close the window if 'q' or 'Q' is pressed.
       if( cv2.waitKey( 5 ) & 0xFF == ord( 'q' ) ):
           break
   close_ncs_device( device, graph )
# ---- Define 'main' function as the entry point for this script -------------
if __name__ == '__main__':
   parser = argparse.ArgumentParser(
                        description="Image classifier using \
                        Intel? Movidius? Neural Compute Stick." )
   parser.add_argument( '-g', '--graph', type=str,
                        default='CancerNet/graph',
                        help="Absolute path to the neural network graph file." )
   parser.add_argument( '-v', '--video', type=int,
                        default=0,
                        help="Index of your computer's V4L2 video device. \
                              ex. 0 for /dev/video0" )
   parser.add_argument( '-l', '--labels', type=str,
                        default='./CancerNet/categories.txt',
                        help="Absolute path to labels file." )
   parser.add_argument( '-M', '--mean', type=float,
                        nargs='+',
                        default=[78.42633776, 87.76891437, 114.89584775],
                        help="',' delimited floating point values for image mean." )
   parser.add_argument( '-S', '--scale', type=float,
                        default=1,
                        help="Absolute path to labels file." )
   parser.add_argument( '-D', '--dim', type=int,
                        nargs='+',
                        default=[227, 227],
                        help="Image dimensions. ex. -D 224 224" )
   parser.add_argument( '-c', '--colormode', type=str,
                        default="rgb",
                        help="RGB vs BGR color sequence. This is network dependent." )
   ARGS = parser.parse_args()
   # Create a VideoCapture object
   camera = cv2.VideoCapture( ARGS.video )
   # Set camera resolution
   camera.set( cv2.CAP_PROP_FRAME_WIDTH, 620 )
   camera.set( cv2.CAP_PROP_FRAME_HEIGHT, 480 )
   # Load the labels file
   labels =[ line.rstrip('\n') for line in
             open( ARGS.labels ) if line != 'classes\n']
   main()
# ==== End of file ===========================================================

從這里開始,我們就有了皮膚癌 AI 分類,只需在文件夾中運(yùn)行以下命令。

python3 live-image-classifier.py 

我們可以檢測(cè)到我們自己的痣

?
poYBAGNR422ALei6AAK2H198PnI336.png
檢測(cè)到常規(guī)痣
?

當(dāng)有黑色素瘤時(shí)

?
pYYBAGNR43CAXd21AAK7Z5ax1Pc174.png
檢測(cè)到黑色素瘤
?

我們可以看到完整的演示

?

?


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評(píng)論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數(shù)據(jù)手冊(cè)
  2. 1.06 MB  |  532次下載  |  免費(fèi)
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費(fèi)
  5. 3TC358743XBG評(píng)估板參考手冊(cè)
  6. 1.36 MB  |  330次下載  |  免費(fèi)
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費(fèi)
  9. 5元宇宙深度解析—未來的未來-風(fēng)口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費(fèi)
  11. 6迪文DGUS開發(fā)指南
  12. 31.67 MB  |  194次下載  |  免費(fèi)
  13. 7元宇宙底層硬件系列報(bào)告
  14. 13.42 MB  |  182次下載  |  免費(fèi)
  15. 8FP5207XR-G1中文應(yīng)用手冊(cè)
  16. 1.09 MB  |  178次下載  |  免費(fèi)

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費(fèi)
  3. 2555集成電路應(yīng)用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費(fèi)
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費(fèi)
  7. 4開關(guān)電源設(shè)計(jì)實(shí)例指南
  8. 未知  |  21549次下載  |  免費(fèi)
  9. 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費(fèi)
  11. 6數(shù)字電路基礎(chǔ)pdf(下載)
  12. 未知  |  13750次下載  |  免費(fèi)
  13. 7電子制作實(shí)例集錦 下載
  14. 未知  |  8113次下載  |  免費(fèi)
  15. 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德爾著
  16. 0.00 MB  |  6656次下載  |  免費(fèi)

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費(fèi)
  3. 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
  4. 78.1 MB  |  537798次下載  |  免費(fèi)
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費(fèi)
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費(fèi)
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費(fèi)
  11. 6電路仿真軟件multisim 10.0免費(fèi)下載
  12. 340992  |  191187次下載  |  免費(fèi)
  13. 7十天學(xué)會(huì)AVR單片機(jī)與C語言視頻教程 下載
  14. 158M  |  183279次下載  |  免費(fèi)
  15. 8proe5.0野火版下載(中文版免費(fèi)下載)
  16. 未知  |  138040次下載  |  免費(fèi)