【YOLOv5】で指文字判定を試す！！【物体検出アルゴリズム】

# 1.はじめに

https://qiita.com/kindamu24005/private/417369ef11ade359c306

・上の記事で、**YOLOの学習済みモデル**を使用しました。

https://qiita.com/PoodleMaster/items/5f2cc3248c03b03821b8

:::note info
さらに**こちらの方の記事**に影響されて、**自分でYOLOの指文字を判定する学習モデルを作ってみます！！！！！**
:::

# 2.指文字判定AIを作る
![yolo実装.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/eb8451eb-005e-cab1-8c3f-210c29950e5d.jpeg)
・こんなイメージで、<B>　「あ」の手の形はこれ！！　「い」の形はこれ！！　「う」の形はこれ！！・・・　</B>みたいな感じで<B>モデルに手の形を教え込みます。</B>

### ◎やることの流れ
<B>・データセットの準備
　　　　　↓
・ラベリングを行う
　　　　　↓
・学習させて物体検出モデルを作る
　　　　　↓
・作ったモデルでyoloを実行</B>

## 2.1.データセットの準備
・Windowsカメラアプリの連写機能を使って指文字の<B>写真を撮りまくります。</B>
・撮影する<B>画像のサイズは640×480</B>に設定しました。
![WIN_20220626_02_31_53_Pro (2) - コピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/73d239d7-6559-abaf-b94e-340255612ce0.jpeg)
・こんな感じで、今回は<B>「あ、い、う、え、お」の手の形それぞれ100枚ずつ</B>写真を撮りました。

## 2.2.「ラベリング」を行う
### 2.2.1.ラベリングって何？
#### <font size="7" color="red">この画像は、「ここを検出して、それは○○と認識するのが正解だ！」←この「正解」を作ること</font>

### 2.2.2.ラベリングツールのダウンロードと使い方
・[<B>「labelImg」</B>](https://github.com/tzutalin/labelImg)というソフトを使います。
・[<B>「ここ」</B>](https://github.com/tzutalin/labelImg/files/2638199/windows_v1.8.1.zip)をクリックして<B>windows_v1.8.1.zip</B>をダウンロードします。
___
・解凍したwindows_v1.8.1内のdataフォルダに入ってる<B>テキストファイル(predefind_class)に分類したいクラスを書きます。</B>
・今回は<B>「あ、い、う、え、お」</B>を検出したいので、ラベルの種類を<B>[a,i,u,e,o」</B>をテキストファイル(predefind_class)に書きます。
![change class.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/eedeee27-6d8e-dcf0-e7b8-a19440b52eed.png)
___
・<B>labelImg</B>のアプリを開きます。
・開いたら左下の<B>PascalVC</B>の所をクリックして<B>「YOLO」</B>にします。
![labelling change format.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/5800d7d2-e3fa-9796-4cbf-76dad8dc0946.png)
・左上の**Open Dir**で画像が入っているフォルダを開きます。
![labelling00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/93f64f82-8db4-ad3a-de0d-56e2f80ee150.png)
___
・左下の**Crreate¥nRectBox**をクリックします。
・認識したい部分を四角で囲います。
・**labellmgのボックス**から**何として認識したいのか**を選びOKを選びます。
・左の**Save**を押します。
![labelling1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/c6c0b0d7-d52e-27f6-9eb4-12e4317a79af.png)
・保存されたラベル**は画像と同じフォルダ**に入ってます。
___
#### ◎保存されたラベルの中身
```text
0 0.569418 0.640351 0.530957 0.619048
```
・こんな感じの**テキストファイル**で保存されています。
・それぞれの数字の意味は「<font size="7" color="Blue"><B>クラスの値</B></font>」と「<font size="7" color="red"><B>各頂点の座標</B></font>」とを表しています。
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/b4971516-3b3d-3e90-5d69-54c5efd95148.jpeg)

:::note warn
今回の例での**クラスの種類**と**クラスの値**の対応関係

| クラスの**種類**| クラスの**値**                                      |
| :---------: | :-------------------------------------------------: |
| <B>a</B> | <B>0</B> |
| <B>i</B> | <B>1</B> |
| <B>u</B> | <B>2</B> |
| <B>e</B> | <B>3</B> |
| <B>o</B> | <B>4</B> |
:::



## 2.3.学習させて物体検出モデルを作る
### 2.3.1.トレーニング(train)フォルダ、検証(Valid)フォルダを作る
・yolov5フォルダ内のdataフォルダの中に<B>"training"</B>、<B>"valid"</B>の名前でフォルダを作ります。
![create train valid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/0b21e4d6-ee95-0fb3-ae84-96443b6a204a.png)

### 2.3.2.trainフォルダとvalidフォルダの中にそれぞれimagesフォルダとlabelsフォルダを作る
・trainフォルダの中に<B>"images"</B>、<B>"labels"</B>の名前でフォルダを作ります。
![create images labels in the training.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/a74dc59f-1dcc-cc63-5967-4261bc1a51a7.png)
・validフォルダの中にも<B>"images"</B>、<B>"labels"</B>の名前でフォルダを作ります。
![create images labels in the valid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/ca4dbea3-6793-cb2f-6db4-4e24fc66810d.png)

### 2.3.3.撮った写真と保存したラベルをトレーニング用と検証用に分ける

・<B>「あ、い、う、え、お」</B>それぞれ１００枚の写真とラベルファイルを<B>90枚</B>と<B>10枚</B>に分けて<B>train</B>と<B>valid</B>それぞれの<B>imagesフォルダ</B>と<B>labelsフォルダ</B>に入れます。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/9730c578-940e-2fc9-ee7a-0b8e4b8af7e3.jpeg)
・


<B>・imagesの中身</B>
![imagesfolda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/cf14e557-595e-b30e-6c68-ad9387c43b0c.png)

<B>・labelsの中身</B>
![labelfolda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/08f4292c-4d8c-3c65-d40b-0361beecaaee.png)

### 2.3.4.yamlファイルを作る
```
train: data/train/images
val: data/valid/images

#クラスの数
nc: 5

#クラスの名前
names: ['a','i','u','e','o']
```
・上記のコードを**メモ帳等**で書き、<B>「data.yaml」</B>という名前で保存してください。
・data.yamlを<B>yolov5フォルダ</B>に入れてください。
![yamlfile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/3879b396-2932-0d9d-a9d8-7dda62c09bd1.png)

### 2.3.5.Wand.aiで学習の過程を可視化する

https://wandb.ai

:::note info
**Wand.ai**とはモデルの学習過程を**可視化してくれるwebサイト**です。
:::

#### ◎使い方
##### 学習実行前に
```:(yolov5)C:¥Users¥ユーザー名¥yolov5
pip install wandb
```
・学習実行前にターミナルで上のコマンドを打ち、インストールします。
##### 学習実行後に
```:(yolov5)C:¥Users¥ユーザー名¥yolov5
Downloading https://ultralytics.com/assets/Arial.ttf to /root/.config/Ultralytics/Arial.ttf...
wandb: (1) Create a W&B account
wandb: (2) Use an existing W&B account
wandb: (3) Don't visualize my results
wandb: Enter your choice: (30 second timeout) 
```
・学習実行後に上の状態で停止するので、キーボードの「2」を打ちます。
・その後、[<B>「Wand.ai」</B>のwebサイト](https://wandb.ai/home)でログインし、<B>「Create New Project」</B>を押して、プロジェクトを作ります。
![wandailogin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/5c4bb979-4e41-3ed9-c5c0-44dc611b6020.png)
・上のページの**赤四角の部分をコピー**します。
```terminal
Downloading https://ultralytics.com/assets/Arial.ttf to /root/.config/Ultralytics/Arial.ttf...
wandb: (1) Create a W&B account
wandb: (2) Use an existing W&B account
wandb: (3) Don't visualize my results
wandb: Enter your choice: (30 second timeout) 2
wandb: You chose 'Use an existing W&B account'
wandb: Logging into wandb.ai. (Learn how to deploy a W&B server locally: https://wandb.me/wandb-server)
wandb: You can find your API key in your browser here: https://wandb.ai/authorize
wandb: Paste an API key from your profile and hit enter, or press ctrl+c to quit: 
```
・コピーしたものを上の```to quit:```の後に**貼り付けます。**
・貼り付けたら学習がスタートします。

### 2.3.6.学習の実行
```:(yolov5)C:¥Users¥ユーザー名¥yolov5
python train.py　--data data.yaml --batch-size 20 --epochs 300　--name　handsign
```
・上記のコマンドを実行します。
#### 〇コマンドの意味
| コマンド | 意味                                        |
| :---------: | :------------------------------------------------- |
| <B>python train.py</B> | train.pyを実行します。 |
| <B>--data data.yaml</B> | 学習データの情報を記載した**yamlファイル**の位置を書きます。(今回はyolov5フォルダの中なので、**ファイル名だけでOK**) |
| <B>--batch-size 20</B> | **バッチサイズ**を**20**に設定します。 |
| <B>--epochs 300</B> | <B>エポック(学習回数)</B>を**300**に設定します。 |




## 2.4.作ったモデルでyoloを実行

### 2.4.1.学習されたモデルを確認

![check model.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/015ddb97-ada0-93c8-9d2f-e1d514f9f453.png)
・学習が終わると<B>runs/train/exp/weightsフォルダの中</B>に<B>last.pt</B>と<B>best.pt</B>という物が出来上がっています。

![move bestpt to olov5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/44ef708d-e041-3369-7dc4-01533a2bc898.png)
・そのうち<B>best.pt</B>を<B>yolov5フォルダ</B>の中に入れます。

### 2.4.2.分析したい画像を用意
![prep images.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/a17578fd-fa30-779f-94a4-0add56549852.png)
・適当に指文字の写真を撮って**imageフォルダの中**に入れます。(busとzidaneは元から入っている画像です。)

### 2.4.3.実行！！！！！！
```:(yolov5)C:¥Users¥ユーザー名¥yolov5
python detect.py --source data/images/ --weights best.pt
```
・上記のコマンドを打ちます！

### 2.4.4.結果
・結果は**detectフォルダ内**に**expフォルダ**が自動で作られて**その中に入っています。**

![result images.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/9d14210a-b47c-00d5-3098-fb285579e5b7.png)


![WIN_20220704_15_51_42_Pro.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/b8dfc381-4c66-bf0a-74f4-b4cb704c937e.jpeg)
・間違い、、、

![WIN_20220704_15_51_49_Pro.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/05f9afb9-cadd-1b00-55ee-e0f432317349.jpeg)
・正解！

![WIN_20220704_15_52_02_Pro.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/97fee187-62df-8e6d-2367-c6ce0d50f353.jpeg)
・正解！

![WIN_20220704_15_52_03_Pro.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/d00597da-fca1-ae5e-0b05-3c64b88a140f.jpeg)
・正解！

### あってるのもあるけど、なんか普通に間違ってるのがある・・・
:::note warn
・単純に**データ不足**が原因だと思われます。
・**角度**とか**背景**とか**大きさ**とかもっと**バラエティ豊富なデータを大量に集める**ことができれば改善できるかもしれないです。
:::

### 2.4.5.学習過程の可視化
![acc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/8238fff9-4b16-bb7e-3f49-3fdbccfaa811.png)
・学習回数を重ねるごとに精度が<B>「1(誤分類がない)」</B>に近づいています。
![loss visualization.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658998/09cdcfcb-75f5-6fa5-7372-7a9be5f14cf5.png)
・学習回数を重ねるごとに損失が<B>「0(損失がない)」</B>に近づいています。

# 3.まとめ
**・とにかくデータの収集とラベリングが大変すぎました！！！！！！！！！！**
・収集したデータは**自分の手だけ**だから、<B>作られたモデルはかなり偏ってる</B>と思います。
・つまり**私の手なら間違いなく検出はできる**と思いますが、**他の人の手だとうまく検出されない可能性があ理想です!**
・どんな手でも判別できるようになるのは、**全世界の人の手をデータとして集める？？？**



# 【連合学習】データの収集不足、データの偏りがなくせそうな技術
https://qiita.com/magisystem0408/items/804b420bdc2842370089