2016年8月7日

[caffe]初心に戻ってサンプルを動かす

[ai]Caffeの画像分類を説明しているサイトをなぞる

全部入れ直したし、私も全部忘れているので、もう一度同じことをやってみようと思ったが、いやあ、説明文が悪いですな。
読み返しても、何をして良いかよくわからなかった。

 

この辺りを参考に動かそう。
OSX10.10でCaffeをインストール、リファレンスモデルで画像を分類 - Qiita
caffeのサンプルを動かす - スチールウールの活動記録


途中までやっていて気付いたのだが、これはexamples/imagenetは関係ないんだな。。
あれはトレーニングの仕方に関するexamplesなのだろう。

説明されている内容は、こうだ。

  • サンプル画像を取ってくる : www.vision.caltech.eduからダウンロード
  • モデルファイルを取ってくる : dl.caffe.berkeleyvision.orgからダウンロード
  • モデルファイルに関連するデータを取ってくる : get_ilsvrc_aux.shを実行

 

最後にpython classify.pyを実行してクラス分けをするのだが、ここにはサンプル画像しか引数に与えていない。
モデルファイルとトレーニング済みデータは必要なのだろうか?
いや、いるのだろうけど、dataにもmodelsにも他のフォルダがあるので、どうやって使い分けているのだろうか、と心配になるではないか。


pythonはよくわからないので雰囲気で見てみよう。

https://github.com/BVLC/caffe/blob/master/python/classify.py

  • --model_defがなかったら、models/bvlc_reference_caffenet/deploy.prototxt
  • --pretrained_modelがなかったら、models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel

あれ、data/が出てこないぞ?
確かに、classify.pyを実行するときにはdata/自体がなくても動作した。

data/を使うのは、show_result.pyだけだ。
これはcaffeが提供しているわけではないので、提供元を見てみよう。
変数categoriesにタブ区切りのテキストとして読込んでいるようだ。
show_result.pyで出力される内容の、この部分ですな。

#1 | n04552348 warplane, military plane | 84.1%
#2 | n04008634 projectile, missile |  5.8%
#3 | n02690373 airliner |  5.0%

classify.pyでは「n04552348に分類される確率が84.1%です」というところまでやってくれるから、それを名前解決する役割をしていると言うことだろう。


get_ilsvrc_aux.shはトレーニング済みデータを取ってくるのかと思っていたが、それはモデルファイルと一緒に提供されると思って良いのだろう。
まあ、ネットワークとトレーニングデータはセットじゃないと意味がないだろうしね。

今回使ったbvlc_reference_caffenetには、以下のファイルが入っている。

  • bvlc_reference_caffenet.caffemodel(自分でダウンロード)
  • deploy.prototxt
  • solver.prototxt
  • train_val.prototxt

classify.pyに与えるのは、最初の2つだけだ。

deploy.prototxtは、ネットワークの構成のようだ。
最初にこういうのが書かれていた。

input_param { shape: { dim: 10 dim: 3 dim: 227 dim: 227 } }


10 x 3 x 227x227。

227x227は画像のサイズで、3はRGBだろう。
10は?
http://docs.chainer.org/en/stable/reference/caffe.html
ミニバッチのサイズなのかな。


自分でトレーニングデータを作る必要がなければ、このようにどこかからもらってくればよいので、GPUがなくてもそんなに困らないように思う。

でも、症例をたくさん入れて診てもらう、みたいなことをしたかったら、自分でトレーニングデータを作らにゃならんだろう。
データはあるけどネットワークの構成を考えるのはちょっと・・・という場合は、既にあるprototxtを使ってトレーニングさせることができますよ、というのがexamples/imagenetサンプルのやりたいことだと思う。

 

うん、前よりは多少理解が早くなったように思う。
深層学習に対する理解と言うよりは、caffeなどのフレームワークを使うときの考え方への理解なのだけど、まあいいのだ。

Xubuntu16.04にアップグレードしたら起動が遅くなったが、swapだった

Xubuntuを16.04にしたのだが、久しぶりに起動したせいもあるかもしれないが、ずいぶん起動が遅くなったように感じた。
こんなもんだったっけ、と思ったが、起動時にぐるぐる回っているときにAlt+Rを押すと起動ログが見えるようになることがわかり、見てみた。
なんか、diskなんちゃらというところで1分半待った後でタイムアウトしていた。

その後にswapどうたらこうたらと出ていたので検索すると、/etc/fstabに書いてあるswapのUUIDと、実際のUUIDが不一致だからだろう、というのが見つかった。

見てみると、確かに違った。
これって、GPartedで「swap on」にしても書き換えてくれないんですな。。。
手動で/etc/fstabを開いてUUIDを変更すると、普通になった。
16.04にしたせいなのか、実は以前からだったのに気付かなかったのかは不明だ。

2016年8月6日

Xubuntu 16.04にcaffeを入れ直す (4) - end

もう、燃え尽きてきました。。。

まずは対象となるnVIDIAのボードがないと話にならないので、古いPCから持ってきた。
NVIDIA GeForce GT710とのこと。
Windows10のデバイスマネージャでは、こう見えている。

image

 

https://www.virtualbox.org/manual/ch09.html#pcipassthrough

よくわからんが、VBoxManageコマンドを使ってアタッチさせるらしい。
サイトでは「02:00.0@01:05.0」となっていて、@の前に書いてある方がlspciで見えている。

00:02.0 VGA compatible controller: InnoTek Systemberatung GmbH VirtualBox Graphics Adapter

これがうちのguestで見えているグラフィックスボードなので、まねしてみた。

> vboxmanage modifyvm "xubuntu" --pciattach 00:02.0@01:00.0

エラーが出た。
3行くらい出るのだが、最初がこう。

VBoxManage.exe: error: Host PCI attachment only supported with ICH9 chipset

Hostって、今だとWindows10側ということだよな。
ICH9チップセットしか対応していないというのは、この設定項目のことか?

image

後から変更して動くのかなぁ。。。やってみるけどさ。

> vboxmanage modifyvm "xubuntu" --pciattach 00:02.0@01:00.0
>

変更したら、エラーは出なかった。
では、VMを起動して・・・・しなかった。
VERR_PDM_DEVICE_NOT_FOUNDとかで、セッションが開けないんだとか。
vboxmanageを実行する前に起動させていたのだが、これは成功したので、ICH9に変更したことが理由ではなく、vboxmanageで変更した方が影響していると言うことになる。

> vboxmanage modifyvm "xubuntu" --pcidetach 00:02.0

うん、起動した。

エラーダイアログに、Extension Packがどうのこうのと出てくるが、今は5.1.2のPackが入っているので大丈夫だと思う。


ん、VirtualBoxのPCIパススルーの章の1行目になにか書いてあるぞ?

When running on Linux hosts, with a recent enough kernel (at least version 2.6.31) experimental host PCI devices passthrough is available.

ぐはぁ。。。
最初の一歩から道を踏み外していたとは。。。

Xubuntu 16.04にcaffeを入れ直す (3)

VirtualBox上にXubuntu 16.04が入っているのだが、CUDAやcuDNNとnVIDIAのグラフィックスボードがあればGPUが使えるのだろうか?

VirtualBoxでも動かせるかもしれないが非常に面倒だったりマザーボード次第だったり、という記事は見つかった。
VirtualBox上のUbuntu14.04でwaifu2xを動かしたかった - 六彩庵

lspciで見てみたけど、当然出てこない。
まあ、nVIDIAのボードが入っていないから、出るはずはないのだけどね。
「InnoTek Systemberatung GmbH VirtualBox Graphics Adapter」の立ち位置にnVIDIAのボードが出てくれば良いのかな。

https://www.virtualbox.org/manual/ch09.html#pcipassthrough

  1. うちのマザーボード(Extreme4 Z170)は、IOMMUができるようだ。
  2. i5-6500も、対応しているような感じ。
  3. BIOS設定は、なんていう名前なんだろう? VT-dでよいのかな。
  4. 次はVirtualBoxの仮想マシン設定で、システム>アクセラレーション>仮想化支援機能の項目に両方チェック。
  5. Linux Kernelですか! と心配になったが、説明があった。
    /etc/default/grubファイルのGRUB_CMDLINE_LINUXの後ろに"intel_iommu=on"を足せば良いそうだ(うちはintelなので)。DEFAULTがついた方もあったので、両方に追加して、update-grub。
    再起動後に書いてあるとおりにgrepして「DMAR: IOMMU enabled」が出てきた。

これで、6番目までやったことになるはず。
で、どうしたらよいのだ?
lspciで見たけど、何も変わらんぞ。

00:02.0 VGA compatible controller: InnoTek Systemberatung GmbH VirtualBox Graphics Adapter

最初の数字がPCIバスのアドレスらしいから、それがそれぞれの数字になったりするのかと思ったのだが。


その合間に、CUDAのRC8とcuDNNをダウンロードしていた。
あきらめて、nVIDIAにユーザ登録することにしたのだ。
承認までに数日かかると書いてあるサイトもあったのだけど、特にそういうこともなくログインしてダウンロードできた。

cuDNNはv5.1があったのだけど「available soon」だったので、v5のfor Linuxをダウンロード。
cudaはapt-getでインストールしたものが残っていたけど、せっかくなのでRC8をダウンロード。

準備だけはできたんだけどねぇ。

Xubuntu 16.04にcaffeを入れ直す (2)

前回、エラーで終わったので、今日も緑茶の人のを参考にしながら進めよう。

http://yusuke-ujitoko.hatenablog.com/entry/2016/06/19/203443

VirtualBoxで動かすので、CUDAなんかはいらないと思うが、apt-get以外はやらずにcaffeのmakeを行ったので、「python pipによるインストール」を抜かしていた。
これを実行すると何かしらインストールされているようなので、caffeを入れ直すときにはやった方が良いのかもしれん。

が、make cleanしてやり直しても、同じエラーが。

https://github.com/BVLC/caffe/issues/3700
opencv 3を使うなら、Makefile.configの編集が必要だと?
確かに、そういう行がコメントアウトされていた。
opencvのサイトも、2.4の方が上にあったから、そっちの方がまだメジャーなのかな?

ともかく、opencv 3対応したら、makeが通った。
やれやれ。


しかし、cntkのサンプルを動かしたときにわかったのだけど、GPUを使うのと使わないのとでは時間が全然違うのよね。。。
なんかバグってるんじゃないの?と思うくらい時間が違う。
nVIDIAの5千円もしないグラフィックスボードを使っていたのだけどねぇ。

今は、オンボードのIntelなのだが、CUDAはnVIDIA専用よね、さすがに。
古いマシンからnVIDIAのボードだけ引っ張ってきて、caffe用に使えるのかしら?

2016年8月5日

Xubuntu 16.04にcaffeを入れ直す (1)

久々にXubuntuを起動したら、16.04にアップデートできるということで更新した。
ついでなので、caffeも長いこと触っていないから、全部捨てて新しくしておこう。


前にやった手順をなぞったのだが、どうにもうまくいかないので、以下を参考にすることにした。
いやあ、ありがたい。

【Caffe】はじめてCaffeをmakeするまでOn Ubuntu16.04 - 緑茶思考ブログ

最後まで進んだのだが、opencvっぽいところがリンクエラーらしきものを出していた。
「最後まで」といいつつ、前にビルドしたパッケージは更新していなかったので、そのせいじゃなかろうか。


で、今opencv 3.1を取ってきてcmakeしているのだが、うまくいかない。
「file DOWNLOAD HASH mismatch」などといっているので、ダウンロードしたファイルとハッシュが合わないとか?

https://github.com/opencv/opencv/issues/5973
-DWITH_IPP=OFFと書いておくとチェックされないようなので、それで回避したらいいんじゃなかろうか、という案を試すことにした。
うん、エラーは出なくなった。

次にmakeすると、今度はmemcpyでエラーが。
これは、緑茶の人のところにも書いてあった。。。あ、これはcaffeの方だ。

https://github.com/BVLC/caffe/issues/4046
CUDA 8だといいよ、と書いてある。
しかし、メンバーじゃないとダウンロードできない。。そこまでする気はないのだ。

というわけで、その次にあったCMakefile.txtの先頭に「set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORCE_INLINES")」を追加する方法にした。
gccのバージョンが新しくなったことに関連しているのかな。

makeが終わり、make installした。
-jしていなかったせいかもしれないが、かなり時間がかかった。


しかし、これでもまだエラーが出ている。。

.build_release/lib/libcaffe.so: undefined reference to `cv::imread(cv::String const&, int)'

済まぬ、疲れたので次回じゃ。

2016年8月4日

[java?]ライブラリを作るときはRuntimeExceptionに気を配ろう

考えたらわかるだろう?と言うようなことが、ときどき、しばしば、あると思う。
自分から言ったり、相手から言われたり。

 

Androidのライブラリを作るお仕事をしているのだが、今日、バグが見つかった。
ライブラリに作ったAPIをアプリが呼んで、そのAPI内で例外が発生すると、状態が残ったままになる、というものだ。

APIでは、呼ばれたときにフラグを変化させて、終わると戻すようにしていたのだ。
だから、APIが「終わる」ということにならないと、フラグが戻らない。

そのことはわかっていたから、メソッドを抜けるルートにフラグを戻す処理を書いていたし、IDEが「このexceptionどうする?」と尋ねれば、捕捉するようにしていた。

 

しかし・・・RuntimeExcetpionが考慮から漏れていた・・・。
Android Studioが賢いのか言語仕様が賢いのかわからんけど、Exceptionをcatchしなかったら警告が出てくれるじゃないか。
あれは、全部チェックしていたのだ。

でも、RuntimeExceptionはそういう対象ではないから、そういう例外が発生することを想定すらしていなかったのですわ。
これがアプリであれば、catchしてなかったら死ぬし、catchしたら処理すれば良いだけだ。
しかしライブラリの場合、自分でスルーしてアプリでcatchされて継続された場合、自分が中断されて状態がおかしくなっていることに気付かないことになってしまうのだ。

 

なので、RuntimeExceptionはIDEなどが検出できないからcatchしなくても気付かないのもわかるし、APIのreturnルートに終了処理を組み込んでいるからreturnしないとダメというのもわかっているのだけど、両方が重なると「あれ??」となります。

言われてみればわかるのだけど、ライブラリってどう使われるかよくわからないから、そういう作りにしているところは「Exception」でcatchせざるを得ない。
「RuntimeException」で済むのかもしれないけど、なんかもう面倒だし。

 

あんまり例外のある言語を使ってないから。。。という言い訳をしたいのだけど、あまり意味がないから止めよう。

2016年8月3日

[esp8266]NonOS V2.0のlibsslには時間設定がいるよ

http://bbs.espressif.com/viewtopic.php?t=2502&p=8235#p8235

上は中国語のようですが、下の方に英語の説明もあるからご安心を。

あまり読んでないですが、configTime APIを使えと書いてあるので、たぶん時間の設定がいるということじゃないだろうか。

昔、opensslで、時間を設定してない状態でずっとつながらず、ひどく困ったことがあった。
どのくらいの時間差ならよいのかはわからないけど、だいたい合ってないと期限切れ扱いになったりするので、ご注意を。

2016年8月2日

[java]@Overrideは、正しければ書かなくても怒られない

「Androidとも、しばらくこれでお別れか、ふっ」となることを期待していたのだが、ちゃんと動かない。。。

悪魔の証明じゃないけど、この問題は私が作った部分には絶対に関係していません!というのを証明するのは、なかなか難しいことですな。
お仕事の発注元の人に期待大なのだが、こちらもやれることはやっておきたいし、どちらかといえば、こういうのが「ノウハウ」になってしまうのだな。


さて、それはともかく。

自分で書いたコードを見直していて、見覚えのないメソッドが出てきた。
そのファイル内では使っていない。
見覚えがないだけで、自分しか触っていないし、自分が作ったファイルだから、覚えがないだけで自分が作ったことに間違いは無い。
呼ばれないのに、なぜ。。。。

と深刻になるまでもなく、基底classをextendsしているメソッドだった。
@Override、と書いておけば気付いたのだろうが、書いていなかったのだな。
書いておくと、違っていれば、Android Studioは警告してくれるようだ。

しかし、書いていなければ、比較のしようがない。
それにそのメソッドは、abstractじゃなくて、デフォルト実装を書いていたから、判断のしようがない。

うまく言えないが、一方通行の道路をその方向に進んでいるから、一方通行かどうか知らなかったとしても問題がない、みたいなものか。
いや、うちの前は一方通行なのだけど、道が太いから逆走するのが多くてね。。

2016年8月1日

[bbg]BeagleBone GreenのUbuntuでUART1を有効にしたい

8月なので心機一転、というか、案件が(不具合がなければ)変わるので、少し違う方面の調べごとをしている。

BeagleBone Green来たる
[bbg]BegleBone Green用のLinuxを作ろう

UARTで制御したいデバイスがあるので、UART1を使うことにした。

image

P9の24ピンと26ピンがUART1だ。


さて、UART0は/dev/ttyS0として見ていて、それをコンソールで使っているようだ。

$ tty
/dev/ttyS0

じゃあ、ttyS1がUART1だろう。

$ ls -l /dev/ttyS*
crw------- 1 ubuntu tty     4, 64 Aug  1 02:42 /dev/ttyS0
crw-rw---- 1 root   dialout 4, 65 Aug  1 02:22 /dev/ttyS1
crw-rw---- 1 root   dialout 4, 66 Aug  1 02:22 /dev/ttyS2
crw-rw---- 1 root   dialout 4, 67 Aug  1 02:22 /dev/ttyS3
crw-rw---- 1 root   dialout 4, 68 Aug  1 02:22 /dev/ttyS4
crw-rw---- 1 root   dialout 4, 69 Aug  1 02:22 /dev/ttyS5

ノードはあるから、使えるんじゃなかろうか。

$ cat hello.txt > /dev/ttyS1
cat: write error: Input/output error

エラーだ。。。
rootになっているからかも、とsudoでやってみたが同じだった。


ネットで検索すると、BeagleBone Blackのことがよく出てくる。
/dev/ttyO系らしいが、uEnv.txtに

cape_enable=capemgr.enable_partno=BB-UART1

などと追加すると良いらしい。

BBGには、/uEnv.txtと/boot/uEnv.txtがあるので、/boot/uEnv.txtに追加した。
dmesgには、カーネルのコマンドラインに追加されるようだ。

Kernel command line: console=tty0 console=ttyO0,115200n8 capemgr.enable_partno=BB-UART1 root=/dev/mmcblk0p1 rootfstype=ext4 rootwait fixrtc

が、変わらず。。。
dmesgを見ると、ttyO0はttyS0に置き換えました、と出てるので、/dev/ttyO1があるのを期待してみたが、無い。

$ sudo cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:8250 mmio:0x44E09000 irq:155 tx:21075 rx:461 RTS|CTS|DTR|DSR
1: uart:unknown port:00000000 irq:0
....

あら、unknown扱いになっているので、ドライバが見えていない?

https://eewiki.net/display/linuxonarm/BeagleBone+Black#BeagleBoneBlack-LinuxKernel
ここに「see: BeagleBone Black#capemgr.v4.1.x+」というリンクがあるな。
capemgrというのが何だか知らないけど、当時のブログに何も書いていないから、やっていないのだと思う。


capemgr: v4.1.x+のところを順番にやっているのだが、installのところで64bit OSはサポートしていないというエラーが出てしまう。

はっ、もしかして、これはBeagleBone上で行う作業なのか??
PC上でスクリプトを動かして、/usr/local/binにdtcとかいうコマンドがコピーされてしまったよ。。。

 

/boot/uEnv.txtに追加するやつで

dtb=am335x-boneblack-overlay.dtb

があるけど、am335x-bonegreen-overlay.dtbもあったので、そちらにしておこう。
最終的にはこうなった(uname_rは最初から入っていた)。

uname_r=4.4.10-bone10
dtb=am335x-bonegreen-overlay.dtb
cape_enable=bone_capemgr.enable_partno=BB-UART1

では、再起動して確認。

$ sudo cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:8250 mmio:0x44E09000 irq:155 tx:8210 rx:74 RTS|CTS|DTR|DSR
1: uart:8250 mmio:0x48022000 irq:187 tx:0 rx:0 CTS|DSR|CD|RI
2: uart:unknown port:00000000 irq:0
....

出てきた出てきた。

$ cat hello.txt > /dev/ttyS1
$

エラー出なくなった。
やれやれですわ。