Google Colabを使って学習

#はじめに
[レーザポインタを物体検出するためのYOLO学習データの作成](https://qiita.com/sowd0726/items/631745cb514a1d64ebbc)でレーザーポインタを学習させてみましたが、学習中XavierNXが使えないのが不便です。
GOOGLE Colabでやればいろいろパラレルでできる上にXabvierNXより3倍ほど高速でした。
以下は備忘録としてステップバイステップで。。

#やったこと
レーザーポインタの学習データをGoogle Colabで作成しました。

#手順
- ./cfg/task/datasets を作成します。
- ./cfg/task/backup　を作成します。
- [レーザポインタを物体検出するためのYOLO学習データの作成](https://qiita.com/sowd0726/items/631745cb514a1d64ebbc)で、スクリプトで作成されるjpgとtxtを全てdatasets内に入れます。
- taskディレクトリ内でmklist.shを実行します。

```sh:mklist.sh
sed -i -e 's/.*img/img/g' list.txt
sed -i -e 's/^/\/content\/train\/cfg\/task\/datasets\//g' list.txt
grep -v 1.jpg list.txt > train.txt
grep 1.jpg list.txt > test.txt
```
- taskディレクトリ内にdatasets.dataを作成します。

```data:datasets.data
classes= 1
train  = /content/train/cfg/task/train.txt
valid  = /content/train/cfg/task/test.txt
names = /content/train/cfg/task/class.txt
backup = /content/train/cfg/task/backup
```
- taskディレクトリ内にclass.txtを作成します。

```text:class.txt
laser

```
- taskディレクトリ内にyolov3-voc.cfg をコピー、変更します。
 - yolov3-voc.cfg はdarknetをgit cloneしたディレクトリの中のcfg内にオリジナルがあります。
 - ~~このファイルの全てのfiltersを18に変更~~スミマセン嘘つきました。 [yolo]ってかいてあるブロックを探し、その直前の[convolutional]ブロック内のfiltersのみを18に変更してください。計3カ所です。同様に[yolo]ブロック内のclassesを1に変更して（同様に3カ所です）taskディレクトリに置きます。
 - 18は、filters=mask_num * (classes + 5)　から計算された値です。  
また、先頭部分にあるbachとsubdivisionをそれぞれ私の場合は32と8に変更しました。元々は1，1になっているので、そのままだとデータが発散して学習が停止する場合があります。
また、大きくするとメモリが足りなくなって終了する可能性があります。 （6／7追記）

ここまででtask内は以下になります。

```
train.txt , test.txt : mklist.shで作成される。
yolov3-voc.cfg : 上の手順で作成
datasets.data : 上のコンテンツそのまま
class.txt : 上のコンテンツそのまま
datasets : 学習用JPEGデータとTEXTデータが全部はいっている
backup: 空のディレクトリでweightsが作られる
cfg内はtask だけがある状態です。
```
ここまでできたらcfgの親ディレクトリに行き

```
tar zcvf train.tgz cfg/*
```
としてアーカイブを作成します。

- 出来たアーカイブをブラウザ経由でgoogle driveにアップロード
- google colab を開きます。
 - googleアカウントにログインしたブラウザからgoogle colabを検索、開きます。
 - Colaboratoryへようこその画面が開くので<img width="1044" alt="スクリーンショット 2020-06-07 10.40.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/410d6035-7489-cd98-024e-c1e310d1f27b.png">
 - 右下の青字の　ノートブックを新規作成を開きます。
<img width="1217" alt="スクリーンショット 2020-06-07 10.42.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/75c0010f-6c30-372a-a6eb-d4a8d42f47d3.png">
 - 上のWindowになるので、上のメニューからランタイム->ランタイムのタイプの変更を選択、GPUを選び、保存を押します。
<img width="1139" alt="スクリーンショット 2020-06-07 13.09.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/c85d147e-3071-2573-6e20-9a8017e0504e.png">
左のフォルダマークのアイコンを押します。
<img width="929" alt="スクリーンショット 2020-06-07 13.12.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/0f7a57e3-f0ac-7d66-1f92-84db5ec26638.png">
"ファイルのブラウジングを有効にするには、ランタイムに接続してください。"といわれる場合には、右側の再生ボタン脇のテキストボックスにカーソルをあわせて少し待つと表示されます。
ディレクトリが表示されたら、GOOGLEドライブの脇のドライブをマウントをクリック
<img width="929" alt="スクリーンショット 2020-06-07 13.16.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/e3f1c046-5188-013f-bebd-4f6bc79e8160.png">
GOOGLEドライブに接続をクリックします。
アカウントの選択画面で、マウントしたいドライブのアカウントを選択します。
<img width="980" alt="スクリーンショット 2020-06-07 13.18.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/eecd005c-d9b0-8a72-4f72-a80b16e9c074.png">
Googleドライブをマウントするにはこのセルを実行してください、といわれるので、該当セルの再生ボタンを押します。
左側ドライブを開き直すと、GoogleDriveのコンテンツが見えます。  
<img width="326" alt="スクリーンショット 2020-06-07 13.20.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/25c4bdf8-069a-8567-d371-b34b88a36d9e.png">

先ほどアップロードしたtrain.tgzが見えます。  

<img width="400" alt="スクリーンショット 2020-06-07 13.24.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/7c79dfa2-112b-9ddf-d9f4-39e143a91f58.png">  

少し上の＋コードをクリックし、新しいセルを開きます。
セルに以下を入力、再生ボタンを押します。

```sh:セルの中身
%%bash
mkdir train
cd train
tar zxvf /content/drive/My\ Drive/train.tgz
rm cfg/task/backup/*
```
しばらく再生ボタンがグルグルしたあと、アーカイブの展開ログが表示されます。
左側ディレクトリツリーを開き直すと、trainディレクトリが作成されています。
<img width="315" alt="スクリーンショット 2020-06-07 13.29.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/2f88eb26-2054-cb84-2329-7a046ad59359.png">
開き治すには ... を押した後、
contentをクリックします。
<img width="539" alt="スクリーンショット 2020-06-07 13.31.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/e0e1b3c0-e938-ceff-ee19-7404f4fc170c.png">
ここまでで作成したtrainディレクトリがcolab上に展開されます。

次にdarknetをビルドします。
また＋コードをクリック、新しくできたセルに

```sh:セルの中身
%%bash
git clone https://github.com/AlexeyAB/darknet.git
cd darknet
sed -i 's/GPU=0/GPU=1/g' Makefile
sed -i 's/CUDNN=0/CUDNN=1/g' Makefile
sed -i 's/CUDNN_HALF=0/CUDNN_HALF=1/g' Makefile
sed -i 's/OPENCV=0/OPENCV=1/g' Makefile
sed -i 's/LIBSO=0/LIBSO=1/g' Makefile
make
```
を入力、実行します。
darknetをgit clone してビルドして実行するので少し時間がかかります。
しばらくすると、ビルド結果がでてきます。warningはいっぱいでますが、エラーは無いはずです。

次にいよいよ学習を開始します。
また＋コードをクリック　新しくできたセルに

```sh:セルの中身
%%bash
cd train
cp ../darknet/darknet .
cp ../darknet/libdark* .
./darknet detector train ./cfg/task/datasets.data  cfg/task/yolov3-voc.cfg -dont_show > darknet_out.txt
```
を入力して、再生ボタンを押すと学習が始まります。
yolov3-voc.cfg
の設定にもよりますが、上記の手順通りだとほっとくとおわりませんが、
実行を開始すると、trainディレクトリに、darknet_out.txt というファイルが出来ており、そこに途中結果が出力されます。
また、1000イテレーション毎に、train/cfg/task/backupディレクトリ内にweightsファイルが作成されます。

放置すると勝手にブラウザが切断され、データが全て削除されるので30分に一度いじって、途中のファイルをダウンロードする必要があります。