2019年6月14日 星期五

訓練自己的偵測物件--YOLO


  YOLO的訓練模型框架

1.安裝Darkflow
2.先使用prebuild YOLO模型
3.訓練新的YOLO模型
  • 準備訓練資料 (圖片與xml檔): 利用LabelImg 工具框選物件及標注label
  • 修改YOLO模型參數,如class數量, filter數目
  • 開始訓練,相關命令列參數: model , load , gpu,…
  • 儲存模型(weight .pb & metafile .meta), 相關命令列參數: --savepb
  • 載入儲存的模型(.pb & .meta)
  • 利用python 測試YOLO模型


1.安裝Darkflow

git clone https://github.com/thtrieu/darkflow.git

python setup.py build_ext --inplace

在windows上要先安裝MS visual studio才能編譯安裝

Flowing the graph using flow

python flow --help  => 若能執行,表示己順利安裝

2.先使用prebuild YOLO模型


#測試YOLO darkflow

python flow --imgdir sample_img/ --model cfg/tiny-yolo-voc.cfg --load bin/tiny-yolo-voc.weights

--imgdir: 指定要倒入YOLO模型的圖檔目錄
--model : 指定網路結構
--load: 載入權重檔; 若為-1 則從ckpt/ 從上一次記錄的權重檔繼續train

3.訓練新的YOLO模型

# Fine tuning tiny-yolo-voc from the original one

python flow  --model cfg/tiny-yolo-voc-orchid.cfg --load bin/tiny-yolo-voc.weights  --train --annotation train/orchid/annotations --dataset train/orchid/images


--train : 表示要進行training
--model : 指定網路結構
--load: 載入權重檔; 若為-1 則從ckpt/ 從上一次記錄的權重檔繼續train
--dataset : 指出training data
--annotation: 框選object 的資訊 (.xml)
--labels: labels.txt 分類名稱. 每一行代表分類名稱

一個xml檔記錄著一個對應的圖檔.. xml中有20個,則圖檔就會至少冇20個被對應 












通常你會使用fine tune方式, 即使用既有的yolo network model (.cfg) 與weight (.weights)作為你訓練新模型的基本架構, 然後再修改成你想要偵測的類別項目

用既有的yolo network model (.cfg) ==> 所以你會從cfg/ copy 一份新的cfg並稍微修改一下檔名.  新的cfg檔, 在修改網路的最後2層, 主要有兩個2個地方, 一個分類數classes和filter的數量
   
  
...

[convolutional]  
size=1
stride=1
pad=1
filters=40     #在倒數第2個 [convolutional], 修改filters 數量
activation=linear

[region]
anchors = 1.08,1.19,  3.42,4.41,  6.63,11.38,  9.42,5.11,  16.62,10.52
bias_match=1
classes=3   #偵測的物件有3類
coords=4
num=5  # anchors  box的數量 (一個anchors會有confidence、座標、在每個類別的機率)
softmax=1


...
       
filters =num*(classes+5) , 若classes=3 , num(自訂)=5, filter=40


2.)  --load  tiny-yolo-voc.weights ==> 會載入tiny-yolo-voc.weights 做為你的初始權重, 因此得去找找到對應的tiny-yolo-voc.cfg 如此才能知道如何將權重載入到網路中, 而你所自訂的tiny-yolo-voc-xxxx.weights  和原本tiny-yolo-voc.cfg 基本上前面都相同, 只有後面2層不同,所以後面的2層不會載入權重. 

原文說明如下

When darkflow sees you are loading tiny-yolo-voc.weights it will look for tiny-yolo-voc.cfg in your cfg/ folder and compare that configuration file to the new one you have set with --model cfg/tiny-yolo-voc-3c.cfg. In this case, every layer will have the same exact number of weights except for the last two, so it will load the weights into all layers up to the last two because they now contain different number of weights.



3.) 修改 darkflow/labels.txt,  行數要和class數量一樣
(名字不要用其他符號, -,_@,...)
  

redline
red
white



在你訓練過程中, darkflow會將此時的weight存在 ckpt/目錄中, 所以你可以隨時從最後一次記錄的權重檔繼續train下去 (--load -1 )

python flow  --model cfg/tiny-yolo-voc-orchid.cfg --load -1 --train --annotation train/orchid/annotations --dataset  train/orchid/images

5. 將最後的權重檔儲存為tensorflow格式 .pb & meta file 

#Saving the lastest checkpoint to protobuf file
python flow --model cfg/tiny-yolo-voc-orchid.cfg --load -1 --savepb

在built_graph/輸出2個檔案
tiny-yolo-voc-orchid.pb
tiny-yolo-voc-orchid.meta

4. 測試模型,

#測試訓練好的模型
## Forward images in sample_img for predictions based on protobuf file

python flow --pbLoad built_graph/tiny-yolo-voc-orchid.pb --metaLoad built_graph/tiny-yolo-voc-orchid.meta --imgdir train/orchid/images






5. 利用python 測試YOLO模型









References:

https://github.com/thtrieu/darkflow
LabelImg 用來產生label 及框選Object


2019年5月6日 星期一

OpenVINO教學-OpenVINO model optimizer錯誤排解


www.ittraining.com.tw狀況一、OpenVINO model optimizer 發生內部錯誤

當使用Intel OpenVINO model optimizer 轉換tensorflow pb modelIR (Intermediate Representation) model時出現…… Exception occurred during running replacer "REPLACEMENT_ID (<……>)": list index out of range ……等訊息。


    









        出現此現象表示輸入之pb model可能未進行Freeze動作或Freeze動作未完全,故可參考
https://stackoverflow.com/questions/45466020/how-to-export-keras-h5-to-tensorflow-pb將整個tensorflow session完全freeze,再行轉換即可成功。

Reference:

    
狀況二、使用OpenVINO model optimizer 出現 __new__() got an unexpected keyword argument 'serialized_options' 錯誤

      當使用Intel OpenVINO model optimizer 轉換tensorflow pb model至IR (Intermediate Representation) model時出現以下錯誤訊息:

[ ERROR ]  Error happened while importing tensorflow module. It may happen due to unsatisfied requirements of that module. Please run requirements installation script once more.
Details on module importing failure: __new__() got an unexpected keyword argument 'serialized_options'

[ ERROR ]

Detected not satisfied dependencies:
        tensorflow: package error, required: 1.10.0

表示系統所安裝之protoc(Protocol Buffer) binary與python protobuf package版本不一致所致。可使用以下3組指令確認系統目前所安裝之版本。

1.系統Global protoc binary version
protoc --version

2.使用pip所安裝之版本
pip list|grep protobuf

3.python3 interpreter實際抓到使用的版本
python3 -c "from google import protobuf;print(protobuf.__version__);print(protobuf.__file__)"

















指令1更版方式:
#Make sure you grab the latest version
wget 
https://github.com/google/protobuf/releases/download/v3.7.1/protoc-3.7.1-linux-x86_64.zip

# Unzip
unzip protoc-3.7.1-linux-x86_64.zip -d protoc3.7.1

# Detemine Directory, if exist delete it
if [ -d " protoc3.7.1" ]; then
    # Directory protoc3.7.1 exists
    echo "Directory protoc3.7.1 exists. Remove it."
    sudo rm -r protoc3.7.1
fi

# Move protoc to /usr/local/bin/
sudo mv protoc3.7.1/bin/* /usr/local/bin/

# Detemine Directory, if exist delete it
if [ -d "/usr/local/include/google" ]; then
    # Directory /usr/local/include/google exists
    echo "Directory /usr/local/include/google exists. Remove it."
    sudo rm -r /usr/local/include/google
fi

# Move protoc3/include to /usr/local/include/
sudo mv protoc3.7.1/include/* /usr/local/include/

# Optional: change owner
sudo chown $USER /usr/local/bin/protoc
sudo chown -R $USER /usr/local/include/google

# Delete protoc3.7.1 directory
rm -r protoc3.7.1

指令2更版方式:
Pip install -U -force-reinstall protobuf==3.7.1

指令3更版方式:
若dist-package有使用easy-install (EGG)安裝之套件,則依該套件的方法移除後重新執行指令2的更版方式即可修復

~強烈建議在Linux環境下使用virtualenv、Windows環境下使用anaconda做python環境控管~


2019年4月2日 星期二

關於ROS的 6 個強大特性


  1. 支援多種程式語言
    ROS支持多種現代高級程式語言(C++、Python、Lisp),開發彈性大。
  2. 點對點設計
    ROS通過點對點設計,分散來自電腦視覺和語音識別等功能所帶來的即時計算壓力。
  3. 程式碼精簡且整合性高
    ROS建立的系統具有模組化的特點,且編譯用的CMake工具讓程式碼變得精簡,利於後續應用的套用和整合。例如,在電腦視覺方面,ROS能與OpenCV整合。在驅動、導航和模擬器方面,ROS能與Player系統整合。在規劃演算法上,ROS也已與OpenAVE整合。
  4. 便於測試
    機器人開發軟體比其他軟體開發更具挑戰性,主要是因為調試準備時間長,過程複雜。況且,因為硬體維修、經費有限等因素,不一定隨時有機器人可供使用。ROS提供兩種策略來解決上述問題。
    (1).精心設計的ROS系統框架將底層硬體控制模組和頂層數據處理與決策模組分離,從而可以使用模擬器替代底層硬體模組,獨立測試頂層部分,提高測試效率。
    (2).ROS另外提供了一種簡單的方法可以在調試過程中記錄傳感器數據及其他類型的消息數據,並在試驗後按時間戳回放。通過這種方式,每次運行機器人可以獲得更多的測試機會。例如,可以記錄傳感器的數據,並通過多次回放測試不同的數據處理算法
  5. 開源
    ROS遵從BSD協議,使開發者可以清楚的查看、自由的使用原始碼,如果有需要,可以根據不同的系統及硬體環境對原始碼進行修改,或者進行二次開發。
  6. 強大的社群資源
    ROS提供了廣泛的社群資源,實現以機動性、操作控制、感知為主的機器人功能。同時由於其開源特性,ROS的支持與發展依託著一個強大的社區。其官方網站尤其關注兼容性和支持文檔,提供了一套「一站式」的方案使得用戶得以搜索並學習來自全球開發者數以千計的ROS程式模組。

為什麼你必須要學ROS?





1.機器人產業快速成長,商機蓬勃發展
全球機器人產業快速發展,而ROS(Robot Operating System,機器人操作系統)是開發機器人的主流技術之一,目前已有許多機器人公司採用了ROS系統來開發創新產品,如ClearPath、Rethink、Unbounded、Neurala、Blue River、Big-i,最典型的就是Willow Garage的PR2機器人。Nvidia、Bosch、高通、英特爾、寶馬以及大疆等大公司也紛紛推出ROS週邊產品。


2.國際大廠相繼投入機器人開發平台,機器人市場前景看俏
國際巨頭在 2018 ~2019年間,前後推出機器人系統,包括高通(Qualcomm)機器人 RB3 平台(2019 年 2 月發表)、微軟(Microsoft )的Windows 10 ROS1(2018 年 9 月發表)、亞馬遜的 AWS RoboMaker(2018 年 11 月發表)、優必選的 ROSA(2018 年 9 月發表)、以及獵豹的 Orion OS(2018 年 3 月發表)。代表大廠也十分看好機器人市場的發展。

3.國家政策全力支持,開發者將享有更多資源
從科技部的政策來看,為了結合台灣既有產業優勢,讓AI加速台灣產業升級,政府投入大量資源來發展AI,以期能成為全球供應鏈中的重要一環。而機器人是AI落地的重要方向之一,特別是在製造、醫療照護等領域的發展。


4.高效跨領域技術整合框架,幫助你快速整合不同技術 
ROS擁有豐富的社群資源,發展迄今,已經整合感測器、視覺、人機互動、硬體、韌體等領域的技術,因此,一旦基於ROS你就可以整合全世界的研發成果,快速打造專屬的產品。舉例來說,如果你想投入工業4.0的領域,透過ROS的OpenSLAM、MoveIt等工具,你就可以快速實作出具有抓取功能的AGV(Automated Guided Vehicle,自動導引車)產品原型。


5.容易操作的可視化套件,幫助你提高專案開發效率
ROS擁有功能強大的可視化工具像是GUI工具rqt、3D可視化工具 rviz、機器人模擬器 gazebo、資料存儲/重播功能rosbag,方便你進行資料記錄、分析、模擬工具,方便調試。不用花太多的成本就可以提升你的開發效率。


2019年3月14日 星期四

C語言動態記憶體配置問題


C語言上有遇到動態記憶體配置問題


  說明直接放在下方! 


Q1:為何在下述程式內, 配置二維陣列的記憶體後, 執行出來的陣列位址每換一列都不是加4 byte.
例如:
3x3:
&arr[0][2]=00BD3200 --> &arr[1][0]=00BD3210 差10 Bytes
arr[0]=00BD31F8, arr[1]=00BD3210差18.
但若不做記憶體 配置 , 則3x3,nxn每個都是4 bytes.

Q2:為何做記憶體配置和沒有做配置, arr+n的address和arr[n]有差異?
ex:



做記憶體配置>> 取arr+n的值不會等於arr[n]的值. 且arr+0,arr+1差4 byte. arr[0],arr[1]差18.
arr+0=00BD31E0; arr[0]=00BD31F8
arr+1=00BD31E4; arr[1]=00BD3210

  
不做記憶體配置>> 取arr+n的值會等於arr[n]的值. 且arr+0,arr+1差12 byte. 剛好是3x4 byte.
arr+0=0060FE8C; arr[0]=0060FE8C; &arr[0]=0060FE8C;
arr+1=0060FE98; arr[1]=0060FE98; &arr[1]=0060FE98;
arr+2=0060FEA4; arr[2]=0060FEA4; &arr[2]=0060FEA4;

int main()
{
    int i,j,n;
    int count=0;

   printf("Input the size:");
   scanf("%d", &n);
   int **arr=(int **)malloc(n*sizeof(int *));
      for(i=0;i<n;i++)
        arr[i]=(int *)malloc(n*sizeof(int));


      for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        {
         arr[i][j]=count;
         count++;
        }

      printf("arr+0=%p; arr[0]=%p; *arr[0]=%d; *(arr+0)=%p; &arr[0][2]=%p\n",arr+0, arr[0], *arr[0], *(arr+0), &arr[0][2]);
      printf("arr+1=%p; arr[1]=%p; *arr[1]=%d; *(arr+1)=%p; &arr[1][0]=%p\n",arr+1, arr[1], *arr[1], *(arr+1), &arr[1][0]);
      printf("arr+2=%p; arr[2]=%p; *arr[2]=%d; *(arr+2)=%p; &arr[2][0]=%p\n",arr+2, arr[2], *arr[2], *(arr+2), &arr[2][0]);
      for(i=0;i<n;i++)
        free(arr[i]);
      free(arr);
    return 0;
}

結果:
arr+0=00BD31E0; arr[0]=00BD31F8; *arr[0]=0; *(arr+0)=00BD31F8; &arr[0][2]=00BD3200
arr+1=00BD31E4; arr[1]=00BD3210; *arr[1]=3; *(arr+1)=00BD3210; &arr[1][0]=00BD3210
arr+2=00BD31E8; arr[2]=00BD3228; *arr[2]=6; *(arr+2)=00BD3228; &arr[2][0]=00BD3228


===========================


From 艾鍗C程式設計講義 


 動態配置2維空間


如果想要像int arr[n][n],配置一段連續的nxn空間,可以用這樣的方式來宣告指標, n-int pointer

 printf("Input the size:");
   scanf("%d", &n);

   int (*arr)[n]=(int *)malloc(n*n*sizeof(int));
   
printf("%d\n",sizeof(arr));  // 4 byte

      for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        {
         arr[i][j]=count;
         count++;
        }
     show(n,*arr);


        free(arr);


參考:




2019年3月3日 星期日

HTTP 的訊息格式處理



HTTP  的訊息格式 (Text Format) 大致如下: 

Method     URL   Protocol \r\n          
key: value  \r\n
key: value  \r\n
key: value  \r\n
\r\n
HTML data

例如




HTTP Header 訊息每列以 \n 或 \r\n 換行, 若某一行為\\r\n 或 \n 沒有任何字 表示Header結尾。 訊息中也可能包含不定數量的空白(依程式實作者而定)

底下利用C函式的字串處理函數strpbrk(), strspn() 進行字串解析, 抓到你想要的欄位值。

protocol -->  "HTTP/1.1"
Method-->  "GET"
URL-->  "/doc/test.html"
Host--< www.test101.com
...






strpbrk()

  int len;
   const char str1[] = "ABCDEFG019874";
   const char str2[] = "BCD";

   char *str = strpbkr(str1, str2)   ==> str="BCDEFG019874"


 strspn()



   int len;
   const char str1[] = "ABCDEFG019874";
   const char str2[] = "ABCD";

   len = strspn(str1, str2)   ==> len=4


相關課程:








2019年2月28日 星期四

micro:bit 擴充板 -- Nexus:bit



適合初學者的最佳DIY機器人教育套件  --  Nexus:bit

Nexus:bit為一款針對micro:bit所做的模組化動力套件,它整合各種子元件並大幅簡化電路接線。擁有了 Nexus:bit再結合micro:bit 圖形化的積木編程,不論是新手或老手,都能快速打造出micro:bit 各種應用,包含無線遙控車、機械手臂、人型機器人....

micro:bit 具備圖形編程平台也支援python 語言撰寫。
Nexus:bit 功能描述
  1. 擴充板具有獨立電源開關
  2. 18650鋰電池座與18650充電系統
  3. 具有電源指示燈及充電指示燈
  4. 電池反接偵測(反接無法啓動電源)
  5. 可以同時控制12個伺服馬達+2個直流馬達
  6. RGB彩色 LED燈
  7. 蜂鳴器
  8. 振動器
  9. 麥克風音量偵測 (可以調整霊敏度)
  10. 超音波測距感測器連接腳座
  11. micro:bit完整擴充腳位及額外I2C、SPI引腳
  12. 5V/3V 輸出接腳
  13. 香菇頭搖桿(上下左右及A,B兩按鍵)
Note: 當接入USB外部電源時,會自動切斷18650電池電源, Nexus:bit 電源會來自USB外部電源












Nexus:bit Shield v1.0
  • USB External Power Supply with high current fuse protection
  • Li-ion 18650 Battery Holder
  • Li-ion 18650 charger system
  • Short circuit protection
  • Power On/Off switch with LED indicator (On: High-Brightness Green LED)
  • PCA9685 (PWM for Servo Motor and RGB LED)
    • Servo: PWM connectorx12
    • RGB LED: PWM (PWM 8,9,10)
  • DC Motor x2
  • GPIO
    • Buzzer  x1
    • Vibratorx1
    • LEDx1
  • Micro:bit PWM/Digital Output pin
  • Sound detection Module with a built-in potentiometer to adjust the sensitivity of the digital output pin.
  • Edge connector
  • Front interface for Joystick
    • Analog pin P1 (X),P2(Y), Button A, Button B
  • Front interface for ultrasonic distance sensor (HC-SR04)
  • I2C connector x2
  • SPI connector x1
  • 5V/3V Output connectorx2
Li-ion 18650 可以採購2000mAH~2500mAH以上


Nexus:bit 電子產品檢測認證  Safety



Nexus:bit Pinmap
Pin
Type
Function

0
Touch
Pad 0
P0 or Buzzer  (by Jumper)
1
Touch
Pad 1
Joystick AD
2
Touch
Pad 2
Joystick AD
3
Analog
Column 1
X
4
Analog
Column 2
X
5
Digital
Button A
Joystick Button A
6
Digital
Row 2
X
7
Digital
Row 1
X
8
Digital

Viberator
9
Digital
Row 3
X
10
Analog
Column 3
X
11
Digital
Button B
Joystick Button B
12
Digital
Microphone/LED1
13
Digital
SPI MOSI
SPI MOSI/M1A
14
Digital
SPI MISO
SPI MISO/ M1B
15
Digital
SPI SCK
SPI SCK/ M2A
16
Digital

SPI CE/ M2B
19
Digital
I2C SCL
I2C SCL for PCA9685
20
Digital
I2C SDA
I2C SDA for PCA9685

Nexus:bit 電路圖下載