LoginSignup
5
7

More than 5 years have passed since last update.

MacOS+docker+Caffeで画像分類

Last updated at Posted at 2018-01-09

やること

ゴリラの画像とチンパンジーの画像を分類してくれる分類器を作ろうと思います。
ゴリラの画像16枚、チンパンジーの画像16枚で試してみます。

環境

OS X El Capitan 10.11.6
今回はMacOSにDockerでCaffeを導入しようと思います。Ubuntuで導入した方が色々とよさそうな感じだったんですが、今回はDockerの使い方と軽くCaffeを触りたかっただけなのでMacOSにしました。

docker

DockerをMacにインストールする (更新:2017/5/26)
dockerが無事インストールできたら上のメニューバーに鯨のマークが出ます。可愛いですね。

docker version
Client:
Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:22:25 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:28:28 2017
 OS/Arch:      linux/amd64
 Experimental: true

無事にdockerがインストールできました

Caffeの導入

gitでローカルに落としてから、docker buildしていきます。
-tはターミナル起動、-iはインタラクティブだそうです。

mac OS Xに、caffe+jupyter notebook環境構築メモ

git clone https://github.com/BVLC/caffe.git
cd Caffe/docker
docker build -t caffe:cpu cpu #dockerfileにしたがってimageを作ります。
docker run -p 8889:8888 -ti caffe:cpu /bin/bash
root@fl23o7yashof:/# cd /opt/caffe
root@fl23o7yashof:/opt/caffe# jupyter notebook --allow-root --ip 0.0.0.0 --no-browser

Jupyterが起動します。ない場合は適宜pip installしましょう
表示に接続するURLが出ているので8888を8889に変更すればipythonが開けます

前準備

早速訓練とかできるのかと思ったら、事前に前準備が色々と必要ですね。
今回はYahoo Blogの中盤に書いてあるCaffeを特徴抽出器として使った分類をやるために準備します。

①get_caffe_reference_imagenet_model.shを実行

cd examples/imagenet
wget https://raw.githubusercontent.com/sguada/caffe-public/master/models/get_caffe_reference_imagenet_model.sh
chmod u+x get_caffe_reference_imagenet_model.sh
./get_caffe_reference_imagenet_model.sh

②data/ilsvrc12/get_ilsvrc_aux.shを実行

cd ~/caffe/data/ilsvrc12/
./get_ilsvrc_aux.sh

③画像データを取得

cd ~/caffe/
wget http://www.vision.caltech.edu/Image_Datasets/Caltech101/101_ObjectCategories.tar.gz
tar xzvf 101_ObjectCategories.tar.gz

④imagenetのモデル定義ファイルをダウンロードしてきて、自分で編集できるようにコピーして編集

cd examples/imagenet
wget https://raw.githubusercontent.com/aybassiouny/wincaffe-cmake/master/examples/imagenet/imagenet_deploy.prototxt
cp imagenet_deploy.prototxt imagenet_feature.prototxt

imagenet_feature.prototxtの編集

imagenet_feature.prototxt
174   top: "fc6wi" # fc6->fc6wi
175   blobs_lr: 1
176   blobs_lr: 2
177   weight_decay: 1
178   weight_decay: 0
179   inner_product_param {
180     num_output: 4096
181   }
182 }
183 layers {
184   name: "relu6"
185   type: RELU
186   bottom: "fc6wi" # fc6->fc6wi

⑤特徴量を取り出せるようにfeature.pyを作成

feature.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os, os.path, numpy, caffe

MEAN_FILE = 'python/caffe/imagenet/ilsvrc_2012_mean.npy'
MODEL_FILE = 'examples/imagenet/imagenet_feature.prototxt'
PRETRAINED = 'examples/imagenet/caffe_reference_imagenet_model'
LAYER = 'fc6wi'
INDEX = 4

IMAGE_DIR = 'path/to/imagedir'
image_number = 1

net = caffe.Classifier(MODEL_FILE, PRETRAINED)
#caffe.set_phase_test()
caffe.set_mode_cpu()
net.transformer.set_mean('data', numpy.load(MEAN_FILE))
net.transformer.set_raw_scale('data', 255)
net.transformer.set_channel_swap('data', (2,1,0))

for im in os.listdir(IMAGE_DIR):
    image = caffe.io.load_image(IMAGE_DIR + '/' + im)
    net.predict([ image ])
    feat = net.blobs[LAYER].data[INDEX].flatten().tolist()

    print(image_number),
    for i,f in enumerate(feat):
        print(str(i+1) + ":" + str(f)),
    print()
    image_number += 1

ディレクトリをいちいち指定するのが面倒だったので,feature.py内でディレクトリごと指定できるようにしました。最終的にSVMに入れる時のデータ形式を以下のようなlibsvm形式にしないといけないのでtxtデータも一つにまとめました。

python feature.py  > tmp.txt
tmp.txt
0 1:-44.596577 2:-30.565985 3:-26.004364 4:-1.526159 ...
1 1:-10.0806865692 2:-27.590259552 3:-25.8647613525 4:-2.82715797424 ...

最初の行に(1,1,277,277)みたいなものがプリントされましたが、今回は不要なので削除しました。

⑥SVMにかける
Ubuntuを触ったのは初めてなのですが、どうやらinstall libsvmではなくinstall libsvm-toolsじゃないとダメみたいです。

apt-get install libsvm-tools
svm-scale -s scale.txt tmp.txt > train_scaled.txt
#scale.txtとtrain_scaled.txtは新しく作られるファイルです。
svm-scale -r scale.txt test.txt > test_scaled.txt
svm-train -c 0.03 train_scaled.txt gorilla_chimp.model
#gorilla_chimp.model は新しく作られるファイル名です
svm-predict test_scaled.txt gorilla_chimp.model result.txt

これでうまくいくやろ!と思ったのですが、どうやらモデルを作成する時にクラスが教師の数だけ(今回はゴリラとチンパンジーを8枚ずつ入れたので、16クラス)出来てしまったので、正答率がめちゃめちゃ低くなってしまいました。そもそも正解値を入れるところなんてどっかにあったか?
調べてもよくわからなかったので、今回はsklearnを使ってcross validationを使うことにしました。
cross validationならばデータは一緒にまとめちゃっていいので、32枚のデータ全てでtmp.txtを作りスケーリングしたtxtデータをdata.txtとしました。0~15がゴリラ、16~31がチンパンジーの画像です。

learning.py
import sklearn
from sklearn import datasets
from sklearn.model_selection import train_test_split

#txtデータを加工
f = open("data.txt",'r')
string = f.readlines()
this_data = []
for i in range(len(string)):
    x = string[i][string[i].find(" ") +1:].split(" ")
    x.pop(len(x)-1)
    sublist = []
    for j in x:
        j = float(j[j.find(":")+1:])
        sublist.append(j)
    this_data.append(sublist)

#正解値付与
this_target = []
for i in range(16):
    this_target.append(0)
for i in range(16):
    this_target.append(1)

#分類
X_train, X_test, Y_train, Y_test = train_test_split(this_data, this_target, random_state=1)
#random_stateはシード値

#学習
from sklearn.svm import SVC
model = SVC()
model.fit(X_train,Y_train)
from sklearn import metrics
predicted = model.predict(X_test)

#実行
metrics.accuracy_score(Y_test,predicted)

sklearn.model_sectionはcross_validationと書いてあるサイトが多かったですが、アップデートで場所が変わったみたいです。accuracy87.5でまあいい精度が出ました。
結局docker(Caffe)で使ったのは画像を4096次元のデータにするだけであとは全部sklearn頼りでした。もう少しdockerについて学ぼうと思います。

参考資料

CaffeのImageNetで特徴量抽出器を動かすまで
”Caffeで手軽に画像分類”の”Caffeを特徴抽出器として使った分類”をやってみた1
『Caffeで手軽に画像分類』が手軽にできない。
【Caffe】特徴量抽出を行いSVMで物体識別する

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7