Darknet YOLOのハイパーパラメーター(学習率)

github.com
学習率が徐々に変化する仕様になっているらしい。

learning_rate=0.0001
policy=steps
steps=100,25000,35000
scales=10,.1,.1
  • [0 - 100] iteration learning_rate will be 0.0001 <= 指定した学習率
  • [100 - 25000] iteration learning_rate will be 0.001 <= 指定した学習率×10
  • [25000 - 35000] iteration learning_rate will be 0.0001 <= 指定した学習率×10×0.1
  • [35000 - ...] iteration learning_rate will be 0.00001 <= 指定した学習率×10×0.1×0.1

デフォルトはVOC-dataseに最適化されているらしい。
結局自分で最適な設定を見つけるしかない。
参考としてこのような記載がみられる。

If you have 10 000 images and 1 classes, 
then also you should decrease 20-fold 2 & 3 steps steps=100,1200,2000 
and you should train about 10 000 iterations.

Darknet YOLOの進化がとまらない

github.com

YOLOで『densenet201』が使えるようになった。

  • pre-trained weights 『densenet201.300』をダウンロード
  • cfg-file 『densenet201_yolo2.cfg』をダウンロード
darknet.exe detector train obj.data densenet201_yolo2.cfg densenet201.300

(おまけ)Yolo_markの使い方

github.com
To compile on Windows, open in MSVS2015 yolo_mark.sln and compile it.
1) If you have other version of OpenCV 2.4.9 then you should change version number in first 3 lines in main.cpp.
2) If you have OpenCV 2.4.13 then you should change pathes

  • 2-1) (right click on project) -> properties -> C/C++ -> General -> Additional Include Directories: C:\opencv_2.4.13\opencv\build\include

  • 2-2) (right click on project) -> properties -> Linker -> General -> Additional Library Directories: C:\opencv_2.4.13\opencv\build\x64\vc14\lib

手っ取り早くWindowsでmxnet-ssdを使う方法(GPUあり)

環境

Windows10 Pro 64bit
GeForce GTX 1080 (CUDA 8.0, cuDNN 6.0)

Anaconda4.4.0(Python2.7version)をインストール

openCVをインストール

  • こちら』からopencv-2.4.13.2をダウンロード
  • 解凍してパスを通す
D:\ProgramFiles\opencv\build\x64\vc14\bin
pip install opencv_python-2.4.13.2-cp27-cp27m-win_amd64.whl

MXNetをインストール

github.com

pip install mxnet-cu80-win

MXNetのソースをダウンロード

以上で『incubator-mxnet-0.9.5/example/ssd』フォルダ内のPythonスクリプトを実行できる

YOLO学習のためのファイル操作もろもろ (2)

画像の左右反転

import glob
import os
from PIL import Image

jpgfiles = glob.glob("./images/001/*.jpg")

for f in jpgfiles:
    (dirname, filename) = os.path.split(f)
    (name,ext) = os.path.splitext(filename)

    new_img = "LR_" + filename
    new_txt = "LR_" + name + ".txt"

    img = Image.open(f)
    imgLR = img.transpose(Image.FLIP_LEFT_RIGHT)
    imgLR.save("images/001/" + new_img)

    txt_file = open("./labels/001/" + name + ".txt", "r")
    lines = txt_file.read().replace("\r\n","\n").split('\n')

    txt_outfile = open("./labels/001/" + new_txt, "w")

    for line in lines:
        if(line != ""):
            elems = line.split(" ")
            txt_outfile.write(elems[0] + " " + str(1-float(elems[1])) + " " + elems[2] + " " + elems[3] + " " + elems[4] + '\n')

画像の上下反転

import glob
import os
from PIL import Image

jpgfiles = glob.glob("./images/001/*.jpg")

for f in jpgfiles:
    (dirname, filename) = os.path.split(f)
    (name,ext) = os.path.splitext(filename)

    new_img = "TD_" + filename
    new_txt = "TD_" + name + ".txt"

    img = Image.open(f)
    imgLR = img.transpose(Image.FLIP_LEFT_RIGHT)
    imgLR.save("images/001/" + new_img)

    txt_file = open("./labels/001/" + name + ".txt", "r")
    lines = txt_file.read().replace("\r\n","\n").split('\n')

    txt_outfile = open("./labels/001/" + new_txt, "w")

    for line in lines:
        if(line != ""):
            elems = line.split(" ")
            txt_outfile.write(elems[0] + " " + elems[1] + " " + str(1-float(elems[2])) + " " + elems[3] + " " + elems[4] + '\n')

画像の拡大、縮小

import glob
import os
import shutil
from PIL import Image

jpgfiles = glob.glob("./images/001/*.jpg")

for f in jpgfiles:
    (dirname, filename) = os.path.split(f)
    (name,ext) = os.path.splitext(filename)

    new_img_12 = "resize_12_" + filename
    new_img_08 = "resize_08_" + filename
    new_txt_12 = "resize_12_" + name + ".txt"
    new_txt_08 = "resize_08_" + name + ".txt"

    img = Image.open(f)
    img_resize_12 = img.resize((int(img.width*1.2), int(img.height*1.2)))
    img_resize_08 = img.resize((int(img.width*0.8), int(img.height*0.8)))
    img_resize_12.save("images/001/" + new_img_12)
    img_resize_08.save("images/001/" + new_img_08)


    shutil.copy("./labels/001/" + name + ".txt", "./labels/001/" + new_txt_12)
    shutil.copy("./labels/001/" + name + ".txt", "./labels/001/" + new_txt_08)

画像の明るさ変更

import glob
import os
import shutil
from PIL import Image
from PIL import ImageEnhance

jpgfiles = glob.glob("./images/001/*.jpg")

for f in jpgfiles:
    (dirname, filename) = os.path.split(f)
    (name,ext) = os.path.splitext(filename)

    new_img_bright = "bright_" + filename
    new_img_dark = "dark_" + filename

    new_txt_bright = "bright_" + name + ".txt"
    new_txt_dark = "dark_" + name + ".txt"

    img = Image.open(f)
    eim = ImageEnhance.Brightness(img)
    
    eim.enhance(1.1).save("images/001/" + new_img_bright)
    eim.enhance(0.9).save("images/001/" + new_img_dark)

    shutil.copy("./labels/001/" + name + ".txt", "./labels/001/" + new_txt_bright)
    shutil.copy("./labels/001/" + name + ".txt", "./labels/001/" + new_txt_dark)

YOLO学習のためのファイル操作もろもろ

複数のファイルに連番をつける

Windowsの場合にはコマンドプロンプト(あるいはPower Shell)を使えばできる。
新たに勉強するのが面倒くさいのでRで行う。
(例としてPASという名前がついたtifファイルに連番をつける)

mypath <- getwd()

setwd(choose.dir())

files <- list.files(pattern="PAS")

file.rename(files, paste("PAS",sprintf("%05d",1:length(files)),".tif",sep=""))

setwd(mypath)

連番をつけたのちに何番かのファイルが欠損している場合、そのファイル名を知る

(例としてPAS00162.txtまで存在する場合)

for(i in 1:162)
{
	file <- paste("PAS",sprintf("%05d",i),".txt",sep="")
	if(!is.element(file,files)) print(i)
}

フォルダ内のjpgファイルのフルパスをテキストに書き出す

setwd(choose.dir())

files <- list.files()
JPG <- grep("jpg",files)
files <- files[JPG]

sink("data.txt")
for(i in 1:length(files))
{
	cat(paste(getwd(),"/",files[i],sep=""))
	cat("\n")
}
sink()

Bash on Ubuntu on Windowsでのファイル操作(ImageMagick使用)

  • tif → jpg
  • 画像縮小
mogrify -format jpg *.tif
mogrify -resize 600x *.jpg

pythonでの画像回転

import glob
import os
from PIL import Image

files = glob.glob('*.jpg')

for f in files:
    (dirname,filename)=os.path.split(f)

    file_plus = "./new/5+" + filename
    file_minus = "./new/5-" + filename
    img = Image.open(filename)
    img_plus = img.rotate(5)
    img_minus = img.rotate(-5)
    img_plus.save(file_plus)
    img_minus.save(file_minus)

Python素人がWindowsでmxnet-ssdを使うまでの長い長い道のり

DarknetのYOLOを試してみたらどうしてもSSDも試したくなった
そこで真剣にPythonに取り組もうと決めた
今後はRとPythonの両方を使っていく

環境

Pythonのインストール

pip install numpy-1.13.1+mkl-cp35-cp35m-win_amd64.whl
pip install scipy‑0.19.1‑cp35‑cp35m‑win_amd64.whl
  • matplotlibもインストール
pip install matplotlib

mxnetのインストール

下記を参考にさせて頂いた
yohira3.hatenablog.com
qiita.com

openCVをインストール

  • openCV3.3を選択してダウンロード
  • 解凍してパスを通す(C直下の場合には以下のパス)
C:\opencv\build\x64\vc14\bin
pip install opencv_python-3.3.0+contrib-cp35-cp35m-win_amd64.whl

mxnet-ssdをダウンロード

  • こちらから「Download ZIP」でごっそりダウンロードして解凍

github.com

  • 同じサイトの下の方から「ssd_resnet50_0712.zip」をダウンロード
  • 解凍してmodelフォルダに中身のみコピー(jsonファイルとparamsファイル)

いよいよ実行

python demo.py --cpu --images ./data/demo/000022.jpg

結果

このような図ができる
f:id:touch-sp:20170816171825p:plain

Rから実行

Rからバッチファイルを吐き出して、実行する。

setwd("C:/mxnet-ssd")
bat <- "python demo.py --cpu --images"
myfile <- file.choose()
bat_code <- paste(bat, myfile, sep = " ")
cat(bat_code, file = "ssd_exec.bat")
shell.exec("ssd_exec.bat")

2017年9月15日更新
こちらも参照touch-sp.hatenablog.com

WindowsでDarknetのYOLO-v2を試してみる

Deep learningの世界ではLinux+Pythonが主流。
自分のようにWindows+Rでやっているのはおそらくかなりの少数派。
物体検出をmxnet-ssdでやろうと思ったが今のところPythonを使わないといけない。
そこでDarknetのYOLOに興味をもった。

参考にさせて頂いたサイト

tadaoyamaoka.hatenablog.com

環境

手順

github.com
まずはサイト内のDownload Zipボタンからファイルをダウンロード。
こちらのサイトからVisual Studio 2015 Community(英語)のインストーラーもダウンロードできる。
Microsoft公式サイトからVisual Studio 2015をインストールしようとすると登録が必要)
OpenCV2.4.13をダウンロードして展開。
その後は上記の参考にさせて頂いたサイト通りにやれば問題なし。

Rから実行

まずはyolo.weightsをダウンロードしてくる。
Rからバッチファイルを吐き出して、実行する。

setwd("D:/Download/darknet-master/darknet-master/build/darknet/x64")
bat <- "darknet detector test ./data/coco.data yolo.cfg yolo.weights"
myfile <- file.choose()
bat_code <- paste(bat, myfile, sep = " ")
cat(bat_code, file = "yolo_exec.bat")
shell.exec("yolo_exec.bat")