やってみた!

やってみた!

試したことを中心に、書評や興味のあること、思ったこととか

YOLOv3-tinyで学習してみた2(パソコン作業、アノテーション続きから学習まで)

 3回記事の2回目です。前回準備した学習用データを使ってgoogle Colaboratoryで学習させました。前の記事はこちら。

akifukka.hatenablog.com

 

 9.googleドライブに学習用ファイルをアップロード

 googleドライブにパソコン上のファイルをアップロードします。

1)フォルダ作成
 googleドライブのdarknetの直下にdata1フォルダを作成します。darknetフォルダを表示させた状態で、画面右にあるスクロールバーの左側の空白で右クリックするとメニューが表示されるので、新しいフォルダを選んで作成します。

2)ファイルアップロード
 次のファイルをgoogleドライブのdata1フォルダにアップロードします。フォルダの中身のみ(フォルダはいらない)をアップロードします。

  • Annotationsフォルダの中身のファイル(*.xml)全て
  • ImageSets-Mainの中にある*_train.txt、*_val.txt
  • JPEGImagesの中身のファイル(*.jpg)全て

3)obj.data、obj.names作成

 次の中身のobj.dataをエディタもしくはメモ帳で作成、googleドライブのdata1フォルダにアップロードします。

obj.data -------------------

classes= 1
train = data1/train.txt
valid = data1/test.txt
names = data1/obj.names
backup = backup/

obj.names -----------------

no parking

10.VOC形式からYOLO形式に変換

 google Colaboratoryで作業します。

0)googleドライブのマウント
 前回の1.項と同じやり方でgoogleドライブをマウントします。

from google.colab import drive
drive.mount('/content/drive')

1)train.txt,test.txt
 Colaboratoryに次のコードを追加して実行させます。

%cd /content/drive/My\ Drive/YOLO/darknet
path_train_in = 'data1/no parking_train.txt'
path_test_in = 'data1/no parking_val.txt'

#train.txt
in_file = open(path_train_in)
out_file = open('data1/train.txt','w')
for s_line in in_file:
s = s_line.split()
out_file.write('data1/'+s[0].replace('JPG','jpg')+'\n')
in_file.close()
out_file.close()

#test.txt
in_file = open(path_test_in)
out_file = open('data1/test.txt','w')
for s_line in in_file:
s = s_line.split()
out_file.write('data1/'+s[0].replace('JPG','jpg')+'\n')
in_file.close()
out_file.close()

実行結果
 後ろについているクラス番号を削除してtrain.txt、test.txtを生成します。

data1/no parking_train.txt -----------------
191017_063233.mp4#t=21.8.jpg 1
191017_063233.mp4#t=20.6.jpg 1
191017_063233.mp4#t=16.jpg 1

data1/train.txt ---------------------------------
191017_063233.mp4#t=21.8.jpg
191017_063233.mp4#t=20.6.jpg
191017_063233.mp4#t=16.jpg

2)*.xml→*.txt
 bounding box(対象物を囲む四角の枠)、クラスのデータをVOC形式からYOLO形式に変換するためColaboratoryに次のコードを追加して実行させます。YOLOのgitサイトにあるスクリプトvoc_label.pyを改造して作成しました。

 1)で作ったファイルの中身を使って*.xmlファイルを読み込み、加工して*.txtファイルを作成します。

%cd /content/drive/My\ Drive/YOLO/darknet
import xml.etree.ElementTree as ET
classes = ['no parking']
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h)
def convert_annotation(path_in_file,path_out_file):
in_file = open(path_in_file)
out_file = open(path_out_file, 'w')
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
for obj in root.iter('object'):
difficult = obj.find('difficult').text
cls = obj.find('name').text
if cls not in classes or int(difficult)==1:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
in_file.close()
out_file.close()
train_file = open('data1/train.txt')
print('train_file')
for file_line in train_file:
path_in_file = file_line.replace('jpg','xml').rstrip()
path_out_file = file_line.replace('jpg','txt').rstrip()
print(path_in_file,path_out_file)
convert_annotation(path_in_file,path_out_file)
train_file.close()
test_file = open('data1/test.txt')
print('test_file')
for file_line in test_file:
path_in_file = file_line.replace('jpg','xml').rstrip()
path_out_file = file_line.replace('jpg','txt').rstrip()
print(path_in_file,path_out_file)
convert_annotation(path_in_file,path_out_file)
test_file.close()

実行結果
*.xml -----------------------------------------------------
<annotation verified="yes">
<folder>Annotation</folder>
<filename>191017_063233.mp4#t=22.533333.jpg</filename>
<path>no-parking-PascalVOC-export/Annotations/191017_063233.mp4#t=22.533333.jpg</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>1080</width>
<height>1920</height>
<depth>3</depth>
</size>


*.txt -------------------------------------------------------
0 0.4003254270515315 0.3194559467240355 0.10319930038215946 0.09872239807341572

11.CFGファイルの変更

1)CFGファイルのダウンロード
 googleドライブのdarknet-cfgフォルダの中にある次のファイルをパソコンにダウンロードします。

yolov3-tiny_obj.cfg

2)yolov3-tiny_obj.cfgの編集
 次の通り変更します。ファイル名をyolo3-tiny_obj2.cfgとしました。

①[yolo]の項2箇所
 今回はクラス数を1としたので、clssesを変更する他、クラス数nとして層数は3x(n+5)になるので、直前のconvolutionalの出力層filtersを3x(1+5)=18に変更する。なお3はmaskの数です。

[convolutional]
size=1
stride=1
pad=1
#filters=255
filters=18
activation=linear

  [yolo]
mask = 3,4,5
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
#classes=80
classes=1
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1


[convolutional]
size=1
stride=1
pad=1
#filters=255
filters=18
activation=linear
[yolo]
mask = 0,1,2
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
#classes=80
classes=1
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1

②batch、subdivisions
 batchは1回の重み更新に使う学習データの数。batch数をまとめて学習した後に重みを更新します。

 subdivisionsはbatchをさらにいくつに分割するかを示します。メモリエラーが出たのでbatchを小さくして、subdivisionsを大きくしました。

 [net]
# Testing
#batch=1
#subdivisions=1
# Training
#batch=64
batch=32
#subdivisions=2
subdivisions=8

googleドライブにアップロード
 yolo3-tiny_obj2.cfgをgoogleドライブのdarknet-data1にアップロードします。

 12.学習を実行する

 Colaboratoryは90分セッションが切れているとリセットされてしまうということで、次の記事の通りChromeのアドオンAuto Refreshを使いました。

qiita.com

 なお、ほんとは途中経過が画面とlog.txtに出力されるはずだったのですが、共に出力されませんでした・・・。Colaboratoryに次のコードを追加して実行させます。

%%bash
cd /content/drive/My\ Drive/YOLO/darknet
./darknet detector train data1/obj.data data1/yolov3-tiny_obj2.cfg yolov3-tiny.conv.15 > data1/log.txt | tee data1/log.txt

 4時間ぐらい経過したところで終了していました。darknet-backupフォルダに、
yolov3-tiny_obj2_1000.weights ~ yolov3-tiny_obj2_7000.weights、
yolov3-tiny_obj2_last.weightsが作られてました。

 試しに1枚判定させてみます。次のコードを追加して実行させます。
191017_195709.mp4#t=3.533333.jpgは学習に使ったうちの1枚です。

%%bash
cd /content/drive/My\ Drive/YOLO/darknet
./darknet detector test data1/obj.data data1/yolov3-tiny_obj2.cfg backup/yolov3-tiny_obj2_last.weights -ext_output data1/191017_195709.mp4#t=3.533333.jpg

 学習は無事できているようです。darknetフォルダにpredictions.jpgとして結果が出力されました。

f:id:akifukka:20191022091817j:plain

補足
①permission denied
 なぜかわかりませんが、./darknetを実行するとエラーが出るようになったことがあります。ファイルの実行権限がなくなっていたので、次のコマンドで追加しました。

%%bash
cd /content/drive/My\ Drive/YOLO/darknet
chmod u+x darknet
ls -l

②max_batches、steps
 AlexeyAB/darknetのサイトではmax_batches、stepsも変更するように書かれていますが、今回は忘れていて変更していないまま学習しました。

GitHub - AlexeyAB/darknet: Windows and Linux version of Darknet Yolo v3 & v2 Neural Networks for object detection (Tensor Cores are used)

 ③今回作ったColaboratoryのpdfを参考に張り付けます。

https://drive.google.com/file/d/1oc_Non9d7dTSiS4NUVuPBRyQ0y8eXbiN/view?usp=sharing

つづく

akifukka.hatenablog.com

 

Jetson Nano カテゴリーの記事一覧へ