2016/09/05

[caffe]cifar10サンプルでclassify.pyは使えんのか

久々に、Ubuntuを仮想環境ではなくインストールした。
14.04のDVDしかなかったので、インストールして、アップグレードしてもらった。
ときどきなぜか固まることがあるのだが、まあよかろう。

 

GeForce GT710という古いグラフィックスボードだが、これでもCPUで計算するよりも速い(はず)。
CaffeとCUDA8.0RCなどをインストールした。


もう使い方を覚えていないから、ネットで見ながら動作確認を行った。

CaffeでDeep Learning (2) - 桜朔
[deep learning] caffeとCIFAR-10を使って画像判別テスト(詳細) - 脳汁portal

 

動いたのだが、どちらの人もclassify.pyを使っていない。
io.pyを修正しても、なんかちゃんとした結果を出していないような気がするのだが、そもそも何なのかがよくわかっていないので、推測ができん。

 

まず思ったのは、classify.pyで省略した引数が影響しているのではないか、ということだ。
"--mean_file"があやしい。
デフォルトでは、'caffe/imagenet/ilsvrc_2012_mean.npy'を使っているのだが、これはILSVRC2012用だろう。
cifar10は、CIFAR-10のmean_fileを指定すべきではなかろうか。

ただ、python/caffeの下にはCIFAR-10用と思われるファイルがない。
このnpyファイルは、numpy array形式のファイルらしく、"data set image mean of [Channels x Height x Width]"と説明があるから、平均画像なのだろう。

CIFAR-10サンプルの平均画像は、mean.binaryprotoというファイルになるようだ。
これを指定すればよいかと思ったが、エラーになった。
形式が違うようだ。

Convert binaryproto to npy | Rachel's Memo
Pythonのコードが載っているが、open/readはしているが、writeはしていないから、arrという変数がnpy形式ということになるのか。
最後に「np.save(ファイル名, arr)」とすると、arrの内容をファイル保存するようだ。

これをclassify.pyの--mean_fileに指定すると、ずいぶん進むようになったが、今度は次元数が違っているというような感じがする。
いや、ndimじゃなくてlen()だから、次元ではないか。
io.pyでは、2か3(2だったら1足している)を通すようなのだが、変換したデータは4になっている。
変換データのshapeは(1, 3, 32, 32)だから、これが4つあるからlen()が4なのか。

最初にmean.binaryprotoを作る場合は、コマンドbuild/tools/convert_imagesetを使っている。
lmdbとあるから、lmdbフォーマットがbinaryproto形式ということか。
(1, 3, 32, 32)のうち、最後の2つはデータのWidth x Heightだろうし、その手前はRGBの3 layerだろう。
classify.pyがほしいのは"[Channels x Height x Width]"ということだから、最初の"1"がいらないだけなのかな。

「arr = np.reshape(arr, (3, 32, 32))」とすると、(3, 32, 32)になった。

import caffe
import numpy as np
import sys

param = sys.argv

blob = caffe.proto.caffe_pb2.BlobProto()
data = open( param[1] , 'rb' ).read()
blob.ParseFromString(data)
arr = np.array( caffe.io.blobproto_to_array(blob) )
arr = np.reshape(arr, (3, 32, 32))
np.save(param[2], arr)

わざわざparamに移したり、arrに2回代入したりと格好は悪いが、ネットで調べながらだから許しておくれ。

 

これで(3, 32, 32)になったし、classify.pyの--mean_fileに指定してもエラーにならなかったが、show_result.pyで見てもパーセントが0だ。
何か違うのか。。。


ああ、--model_defと--pretrained_modelも指定しないといかんのか。
2番目のサイトのスクリプトをまねしよう。

$ python python/classify.py ./car.jpg ./result.npy --mean_file=cifar10.npy \
--model_def=examples/cifar10/cifar10_quick.prototxt \
--pretrained_model=examples/cifar10/cifar10_quick_iter_4000.caffemodel.h5

$ python python/show_npy.py result.npy
#1 | dog | 42.7%
#2 | cat | 31.8%
#3 | airplane | 11.0%

数字は出たのだが、結果がおかしいな。。。
2番目のサイトにある、猫がアップになった画像だと、こうなった。

#1 | bird | 29.0%
#2 | airplane | 20.9%
#3 | cat | 13.8%

全然違うなぁ。
同じスクリプトをうちでも動かしたが、数値は異なるもののネコが一番高くなるところは同じだ。

====================================
possibility of each categoly
0(airplane):   0.184532
1(automobile): 0.000219549
2(bird):       0.0134824
3(cat):        0.539376
4(deer):       0.0715057
5(dog):        0.021061
6(frog):       0.0255798
7(horse):      6.09221e-07
8(ship):       0.136054
9(truck):      0.00818893
====================================
I guess this image is [cat]

数字が違うというのも気にはなるのだが、半年違いがあるからネットワークが少し変わったのかもしれない、と勝手に思うことにしよう。

載っているスクリプトもmean.binaryprotoをreshape()しているから、意味として同じようなことをやってるんだと思う。
なにが、何が違う。。。。

あー、images_dimだ。
classify.pyはデフォルトだと256,256なのだが、載っているスクリプトでは省略していて、caffe/classifier.pyのデフォルトは画像サイズ、つまり32,32になっていたのだ。

 

なんだー、じゃあ、そこも指定して動かしておしまい。。。と思ったら、Ubuntuが死んでしまった。。。
メモリテストも正常だったし、インストールも新規だったし、あとはnVIDIAのドライバか、AMDのドライバか?


リセットして動かしたが、まだ合わない。。。
ここまで指定して、ようやく結果が一致した。

$ python python/classify.py ./cat.jpg ./result.npy --mean_file=cifar10.npy \
--model_def=examples/cifar10/cifar10_quick.prototxt \
--pretrained_model=examples/cifar10/cifar10_quick_iter_4000.caffemodel.h5 \
--images_dim=32,32 --center_only --channel_swap=0,1,2

$ python python/show_result.py data/cifar10/batches.meta.txt ./result.npy
#1 | cat | 53.9%
#2 | airplane | 18.5%
#3 | ship | 13.6%

 

こういう目にあうと、DeepLearningはともかく、Pythonには少し近づけたかもしれない。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。