# YOLO3的安裝與實作 取材於[Jason Hung第 11 屆 iT 邦幫忙鐵人賽的](https://ithelp.ithome.com.tw/users/20120243/ironman/2404?page=2)19-21天 物件偵測(Object Detection)是指在照片或影片等圖像內容中,用框標出物件的範圍,並且分類為何種物件及他的猜測機率。 物件的偵測可以運用在很多產業,像有人用他來辨識黃瓜。 [日本農夫](https://chtseng.wordpress.com/2016/09/09/%E6%B7%B1%E5%85%A5%E5%AD%B8%E7%BF%92%E7%9A%84%E6%87%89%E7%94%A8-%E6%97%A5%E6%9C%AC%E7%9A%84%E5%B0%8F%E9%BB%83%E7%93%9C%E8%BE%B2%E5%A0%B4/) 勵志的日本黃瓜農夫,如何用 Google 深度學習 AI 改善農場人生? 引入了 Google 的深度機器學習系統,搭配了圖像辨識與分類學習系統後,製作了一條自動化分類輸送帶,只要事前準備好一批已經分類好的黃瓜,並且拍成照片、標上等級後建檔,交給機器學習模組,之後 AI 就可以透過學習而來的資料,快速且準確的在自動化分類輸送帶上幫助分類。 用來辨識雜草 [美國農機老店](https://ai-blog.flow.tw/ai-in-agriculture) 180 年農機老店,要用 AI 跟雜草開戰 運用電腦視覺和機器學習來偵測、分辨雜草,並做出管理決策。與其漫天噴灑農藥,「看見再噴」(see and spray)的技術,就像手術刀一樣精準,切除每棵病灶。不僅減少90%的農藥用量,還可提高產量。 如果不要涉及隱私方面,電腦視覺是很強大的應用方向。 物件偵測(Object Detection)演算法有 R-CNN Fast R-CNN Faster R-CNN Mask R-CNN YOLO SSD [YOLO的官網](https://pjreddie.com/darknet/yolo/) [Joseph Redmon在TED的演說](https://www.youtube.com/watch?v=Cgxsv1riJhI)How computers learn to recognize objects instantly 片長7分37秒 yolo 是學習起來成就感很強的演算法,要弄懂可能不太容易,但是照著官網上的步驟,要實作一個 Demo 還蠻容易成功的。當你可以即時看到他呈現的樣子,在圖片或影片或鏡頭下,看著框追蹤著物體跑,感覺很神奇。 我們先看看他可以辨識出什麼物品,這樣你才能知道要丟什麼照片給他看阿。他預處理的權重,是用 COCO 資料集,COCO數據集網站有列出蠻多特色,不過我們只要先知道他有80種類別就行了,那80種呢? 有興趣可以先看這個檔 coco.names,下面就簡單的把80個種類再分類一下,比較好記。 [coco資料集](http://cocodataset.org/#home) 交通方面 人 / 自行車 / 汽車 / 摩托車 / 飛機 / 巴士 / 火車 / 卡車 / 船 紅綠燈 / 消防栓 / 停止標誌 / 停車收費表 / 板凳 動物方面 鳥 / 貓 / 狗 / 馬 / 羊 / 牛 / 象 / 熊 / 斑馬 / 長頸鹿 配件方面 背包 / 雨傘 / 手提包 / 領帶 / 手提箱 運動用具 飛盤 / 滑雪板 / 單板滑雪 / 運動用球 / 風箏 / 棒球棒 / 棒球手套 / 滑板 / 衝浪板 / 網球拍 廚房方面 瓶子 / 紅酒杯 / 杯子 / 叉子 / 刀 / 勺 / 碗 食物方面 香蕉 / 蘋果 / 三明治 / 橙子 / 西蘭花 / 胡蘿蔔 / 熱狗 / 比薩 / 甜甜圈 / 蛋糕 家具方面 椅子 / 沙發 / 盆栽植物 / 床 / 餐桌 / 馬桶 電視監視器 / 筆記本電腦 / 滑鼠 / 搖控器 / 鍵盤 / 手機 微波 / 烤箱 / 烤麵包機 / 水槽 / 冰箱 書 / 時鐘 / 花瓶 / 剪刀 / 泰迪熊 / 吹風機 / 牙刷 yolo 會成為熱門的演算法是因為他偵測速度很快,為什麼很快,網站有稍微說明一下。 先前的檢測系統重新利用分類器或定位器來執行檢測。將模型應用於多個位置和比例的圖像。圖像的高分的區域被認是檢測的區塊。YOLO使用完全不同的方法。我們將單個神經網路應用於完整圖像。該網路將圖像劃分為多個區域,並預測每個區域的邊界框和概率。邊界框會由預測的概率進行加權。 與基於分類器的系統相比,YOLO的模型具有多個優勢。它在測試時查看整個圖像,因此其預測由圖像的全局中的相關網格提供。它不像R-CNN這樣的系統需要單個網路評估來進行預測,而R-CNN單個圖像需要數千個。這使其變得非常快,比R-CNN快1000倍以上,比Fast R-CNN快100倍。 可參考這篇 [物體偵測(Object Detection) + 影像標題(Image Captioning)](https://ithelp.ithome.com.tw/articles/10192950) 標註區域的方式有下列幾類演算法: 1.滑動視窗(Sliding Window) 這是一種窮舉法,設定各種尺寸的區域,從左上角開始滑動,找出所有區域,然後,看哪一個區域符合的機率最高。這種方法最簡單,但是也相對耗時。 2.候選區域(Region Proposals) 利用了圖像中的紋理、邊緣、顏色等信息,人為定義可能含有目標的RoI(Regions of Interest)區域,只針對這些區域比較符合的機率,每秒可過濾上千個區域,相關演算法有 R-CNN、Fast R-CNN、Faster R-CNN...等。 3.迴歸方法 將圖片切成小方塊(Grid),再以小方塊中心點選擇幾種尺寸的區域,利用迴歸方法計算每個區域含有目標的機率。這種方法較 Region Proposals快,更適合即時(Real Time)偵測,目前相關演算法有有 YOLO(You Only Look Once)、SSD(Single Shot MultiBox Detector)...等。 所以到這裡,我們會知道2件事,第一是 yolo3 為什麼很快的原因。第二是使用 yolo3 的已訓練好的權重可以辨識80種類的物品。當然你可以再加上資料訓練去擴充他的種類,或是完全改用自己的分類。不過 yolo3 也有缺點,因為他是把整張圖去切格子,所以你東西太小的話,他辨識率不高。 [<font color=redblue>Tao:應該是yolo2的缺點;yolo3就是來改善這一點的</font>] 開始介紹 YOLO 的實作練習,一般建立環境當然是建在我們的本地的電腦上,建好後會很方便操作。不過有時因為每個人的電腦環境不太一樣,雖然說安裝步驟其實沒有很難,但是很有可能會在自己的電腦裝弄天,搞定環境後都快去掉半條命了。 今天我們可以更簡單一點,不用自己準備機器。我們就直接用 Google colab 來玩, 你只要有 Google 帳號就可以開始了。是不是很心動,哈。 首先要感謝這個作者 David Ibáñez,真心崇拜這位作者,好用心把程式整理分享。我練習後,發現真的很方便教學。而且也強化了我 Google colab 的技能。這個練習主要是參考 David Ibáñez 這篇教學。 * [David Ibáñez的原版 ](https://colab.research.google.com/drive/1lTGZsfMaGUpBG4inDIQwIJVW476ibXk_) * [在PYTHON程式中使用YOLO](https://chtseng.wordpress.com/2018/10/08/%E5%A6%82%E4%BD%95%E5%9C%A8python%E7%A8%8B%E5%BC%8F%E4%B8%AD%E4%BD%BF%E7%94%A8yolo/)請參考這篇 我已經將程式碼放在雲端硬碟中,可直接複製到屬於你的colab上執行. [YOLOv3安裝與實做.ipynb](https://colab.research.google.com/drive/16kXIvnz2gNk8jOz_4KB5pl3XLZR79WSd?usp=sharing) ### Part 1 安裝yolov3 那我們開始吧. 第1步: 建立jupyter筆記本,就是在你的 Google Colab 新建一個 Python3 筆記本,並且設定為使用有GPU的伺服器。 第2步: 與雲端硬碟連接 因為 colab 時間到了會清掉你的檔案,所以要跟雲端硬碟連接,用來存放我們需要的檔案。 ```python= from google.colab import drive drive.mount('/content/gdrive') ``` 在執行時他會給你一個連結還有一個輸入框,點連結下去後會需要先登入帳號,同意授權,之後會出現金鑰,像這像(4/rwFnMDkRAYND2a1r6ktfVqPnoLE61ichB...),再把這串貼到下面的輸入框按 Enter,看到這個訊息就是連接成功了。 "Mounted at /content/gdrive" 第3步: 安裝 cuDNN 3-1 先檢查 CUDA 版本 ```python= !/usr/local/cuda/bin/nvcc --version ``` 你應該會看到版本號, 如"Cuda compilation tools, release 10.0, V10.0.130" 表示是第10版號 3-2 依目前的 CUDA 版本號, 安裝 cuDNN 去 Nvidia 官網下載 [Nvidia](https://developer.nvidia.com/cudnn),它沒法直接下載,應該需要填一些資料加入為會員。我下載時檔名是長這樣 cudnn-10.0-linux-x64-v7.6.2.24.tgz,下載後先把它上傳到雲端硬碟上,我們等一下會用到它。如下圖,我是放在 darknet/cuDNN 目錄下面. ![](https://i.imgur.com/QSn7gmX.png) <font color=red>這段需要處理路徑</font> 3-3 解壓縮tgz,把檔案放到 /usr/local/ 這裡說明一下路徑  gdrive :是我們剛連接的根目錄 /My\ Drive :是我們雲端硬碟目錄 /darknet/cuDNN/ :是我們建立的目錄 連起來就是 gdrive/My\ Drive/darknet/cuDNN/ ```python= !tar -xzvf gdrive/My\ Drive/darknet/cuDNN/cudnn-10.0-linux-x64-v7.6.2.24.tgz -C /usr/local/ !chmod a+r /usr/local/cuda/include/cudnn.h ``` 第4步: 下載及編譯 darkent (只需要一次) 再來是編譯 darkent , 只有第一次執行才需要,如果你成功編譯完,把編譯完的檔案存到你的雲端硬碟後,你下次再執行,就不用再執行這一個步驟了。只需要把雲端硬碟的檔案複製過來就好。 ```python= !git clone https://github.com/kriyeng/darknet/ %cd darknet !ls !git checkout feature/google-colab ``` 接著編譯它 ```python= !make ``` 把編譯完的 darknet檔,複製到雲端硬碟的 darknet/bin/darknet 先在你的雲端硬碟建好 darknet/bin 目錄。 ```python= !cp ./darknet /content/gdrive/My\ Drive/darknet/bin/darknet ``` 成功的話,你在你的雲端硬碟應該會看到有 darknet 這個檔案。 ![](https://i.imgur.com/DxFOPFZ.png) 好,到這裡,如果很順利的話,你已經成功一半了。 前面我們已把 darknet 編譯好了,所以再來跑就不用再編譯了,只要把前次的檔案複製回來就好。 ```python= !cp /content/gdrive/My\ Drive/darknet/bin/darknet ./darknet !chmod +x ./darknet ``` <font color=red>這段僅複製一個檔案到雲端硬碟,並非編譯後的全部內容.在我上面所連結的YOLOv3安裝與實做.ipynb中已經更改了程式碼.</font> 第5步: 定義副程式 imShow/upload/download 然後準備幾個我們等一下會用到呼叫的函數。 * imShow 用來顯示辨識完的圖 * upload 用來上傳要辨識的圖 * download 用來下載辨識完的圖 ```python= def imShow(path): import cv2 import matplotlib.pyplot as plt %matplotlib inline image = cv2.imread(path) height, width = image.shape[:2] resized_image = cv2.resize(image,(3*width, 3*height), interpolation = cv2.INTER_CUBIC) fig = plt.gcf() fig.set_size_inches(18, 10) plt.axis("off") #plt.rcParams['figure.figsize'] = [10, 5] plt.imshow(cv2.cvtColor(resized_image, cv2.COLOR_BGR2RGB)) plt.show() ``` ```python= def upload(): from google.colab import files uploaded = files.upload() for name, data in uploaded.items(): with open(name, 'wb') as f: f.write(data) print ('saved file', name) ``` ```python= def download(path): from google.colab import files files.download(path) ``` 第6步: 下載 yolov3.weights 把已訓練好的權重下載過來。 ```python= !wget https://pjreddie.com/media/files/yolov3.weights ``` 第7步: 辨識 person.jpg 他的 Data 目錄裡有幾張圖片可以測試,先試看看辨識他自己準備好的圖片 person.jpg。 ```python= !./darknet detect cfg/yolov3.cfg yolov3.weights data/person.jpg -dont-show imShow('predictions.jpg') ``` 我們看到他辨識出3個物體,還有他的機率。 dog: 99% person: 100% horse: 100% ![](https://i.imgur.com/V0ezHrZ.png) 第8步: 上傳自己的圖片 mytest.jpg 再來上傳我們自己的圖片。 ```python= upload() ``` ![](https://i.imgur.com/jcqHxQP.png) 第9步: 辨識自己的圖片 mytest.jpg 試看看辨識我們自己的圖片 mytest.jpg。 ```python= !./darknet detect cfg/yolov3.cfg yolov3.weights mytest.jpg -dont-show imShow('predictions.jpg') ``` 我們看到他辨識出4個物體,還有他的機率。 keyboard: 98% cell phone: 33% mouse: 100% cup: 96% ![](https://i.imgur.com/1PflfHs.png) 第10步: 下載辨識完的圖片 predictions.jpg 最後你可以把檔案下載回來。 ```python= download("predictions.jpg") ``` 以上就是在 Google Colab 用 yolo 辨識圖片的過程啦,有沒有很簡單。 推薦一個視頻 [How we teach computers to understand pictures | Fei Fei Li ](https://youtu.be/40riCqvRoMs) 李飛飛的研究領域主要為電腦視覺、認知神經科學、電腦神經科學和大數據分析。她出版了超過百篇學術論文。視覺網專案(ImageNet)的建立者. ### Part 2 訓練yolov3 接下來回到colab 實做: 訓練YOLO辨識圖片中的人帶口罩的狀態 參考大樹軟體的 [深度學習 如何使用 YOLO 製作即時口罩檢測系統(一) - YOLO簡介](https://www.youtube.com/watch?v=vGhIhitQHBE&t=308s) [深度學習 如何使用 YOLO 製作即時口罩檢測系統(二) – 建立口罩檢測模型](https://www.youtube.com/watch?v=C0Otd6_jGmE&t=85s) 標記圖片的來源 [kaggle](https://www.kaggle.com/) 簡單說明一下 yolo採用的標記共五個數字所表示的意義: | Column 1 | Column 2 | Column 3 |Column 4 |Column 5 | | -------- | -------- | -------- |-------- |-------- | | 2| 0.459375 |0.375 |0.06375|0.15| |class編號|歸一化的中心點x座標|歸一化的中心點y座標|歸一化的w|歸一化的h| class編號:已接下來的口罩訓練為例:0是none;1是poor;2是mask. ![](https://i.imgur.com/oYdlpW4.png)train 29148 iterions的狀況 29148: 指示當前訓練的迭代次数 • 0.916980: 是總體的Loss(損失) • 0.77844 avg: 是平均Loss,這個數值應該越低越好,一般來說,一旦這個數值低於0.060730 avg就可以终止訓練了。 • 0.001000 rate: 代表當前的學習率,是在.cfg文件中定義的。 • 0.878274 seconds: 表示當前批次訓練花費的總時間。 • 1865472 images: 這一行最後的這個數值是29148*32=1865472,表示到目前為止,參與訓練的圖片的總量。 mAP指標:mean average precision,是指每個類别的平均查準率的算術平均值 P指標(查準率):precision的分子是:被預測出且正確的數目;分母是:被預測出的總數目. 舉例來說預測狗:圖中有10個物件,有4個狗6個其他,預測結果框出5個狗,但是其中正確3個,錯了2個. p=3/5=0.6 順便介紹 召回率recall指標:recall的分子是:被預測出且正確的數目;分母是物件數目. recall=3/4=0.75 ## Part 3 即時影像實作yolov3偵測 這部份不在colab執行.各位練習時應配合自己的電腦環境. 可參考 這篇[深度學習] 如何使用 YOLO 製作即時口罩檢測系統(三) – 建立即時口罩檢測系統 [YouTube](https://www.youtube.com/watch?v=T_zFMRFCFfk&t=432s) [程式碼](https://github.com/ywchiu/largitdata/blob/master/code/Course_128.ipynb) 最後來到本機,進行即時的影像檢測是否有戴好口罩. 打開終端機,進入 tf2 的虛擬環境,我是在此進行實測的. source tf2/bin/activate jupyter notebook Course_128 <font color=green>心得感言: 機器會學習,這點從前面的簡單口罩檢測已確認.但也無須將機器學習視為萬能,我認為其實正好相反.機器靠著大量的資料學習了判斷是否有戴口罩.這份機器學習到的權重,也僅僅能處理口罩這一件事.其他的可說一概不知. 再以最近常被提到的Google AlphaGo打敗人類「圍棋」王為例.但若讓AlphaGo下「象棋」,它可無法勝任.AlphaGo下棋贏了也不會喜悅,當然輸了也不會沮喪. 要機器學習達到「人」的狀況仍有很長很難的路要走,是否真能達到我是存疑.也就是我認為機器終究只是幫助人的工具.我們更重要該考慮的是機器確實會取代很多人現有的工作,如何在未來仍能具備機器無法取代的能力,自信的生存著. 最後說這些好像有點沈重,還是快樂學習,共同研究程式語言吧!</font> 謝謝大家的參與 真誠感激各位讓我藉由這些報告,持續探討deep learning.能有幸參與此研究團,謝謝大家. <font color=blue>本次實做了的yolov3的train,仍欠缺重要的test.經過test後才能評估是否達到要求,如此才算是完整的建構出模型.或許下回可以接續報告,如何test此模型的實做.</font>