読者です 読者をやめる 読者になる 読者になる

MATHGRAM

主に数学とプログラミング、時々趣味について。

chainerに復帰したくてFCN実装した

Deep Learning OpenCV chainer python 機械学習 画像処理

もともと, chainerユーザーだった僕ですが, 5月くらいにKerasを使い出してからchainerにはあまり触れてきませんでした. しかし先日の分散処理の発表なども含め, バージョンアップが早く, 常に速度の向上を図っているchainerにはもう1度触れておきたいと思い, 今回ハンドリングとしてFCNを実装した次第です. (ちょうどFCNを使ってやりたいこともあったしね.)

レポジトリはここに置いときます.

GitHub - k3nt0w/chainer_fcn: Implementation FCN via chainer

あと学習済みパラメータもここに置いときます. chainerってついてる方です. お間違いのないように.

ぱらめーたー - Google ドライブ

FCNは以前Kerasでも実装していて, FCNそのものの説明もこちらに詳しくしているので, もし"FCNってなんじゃい“って方がおりましたら, こちらを参照してください.

www.mathgram.xyz

いやーしかし・・・, chainer使いやすすぎだろ!! 誰だよ,
あれ...?chainerよりkerasの方が書きやすくね? - MATHGRAM
なんて言ったの!死んで詫びろ!
昔使っていた貯金はありますが, 今回の実装には3時間もかかってないと思います. しかもほとんどは画像の出力方法の部分. ただ僕が使っていた時には無かったtrainerの部分は全く触れずに実装しちゃいました. 必要性を感じたら勉強しよう.

keras2も気になりますが, chainerもいっぱい使っていこうと思います.

目次

環境

実験方法

実験にはPASCAL VOC2012のSegmentationClassを使いました. クラス数は背景を含めて21. trainデータは, VOCのtrain&valを全部使っちゃってて約2500枚, epochは100, batchsizeは5です.

境界線には-1を当てて計算から除外しました. 任意のサイズの画像をinputできますが, 速度向上のため256に統一しています. 予測は任意のサイズいけます.

また今回もこの論文からそのまま実装しました. 厳密にはFCN-8sの実装となっています.

実験結果

lossはまだまだ下がりきってないけど, AWSの請求が半端なくなりそうなので, とりあえずここで区切る.

あとtrainデータにのみ予測を行なっています. お叱りを受けそうですが, 今回の目的はFCNの精度を上げることではないので許してください. むしろいいGPUマシン持っている方, fine-tuningしてくれたらくそ喜びます.

人間

f:id:ket-30:20170218120353p:plain

f:id:ket-30:20170218115535p:plain

バス

f:id:ket-30:20170218115050p:plain

クルマ

f:id:ket-30:20170218120620p:plain

Kerasの時もそうだったけど, 犬って難しいのかな? f:id:ket-30:20170218120815p:plain

おまけ

VGG16のpretrain modelを使う

今回はなぜか1から学習させてしまいましたが, FCN−8sはほとんどVGGと同じ構成なので学習済みのパラメータを使うことができます. モデルの定義をVGGとその出力を受け取る部分に分ければいいだけですね.

インデックスカラーについて

前回の実装では, PASCALVOCの画像をRGBに変換し, 色ごとに自分でクラスを分けるというクッソだるいことしていましたが, なんとインデックスカラーなるものがこの世には存在するようです.

インデックスカラー - Wikipedia

VOCのSegmentationClassに存在する画像はこのインデックスカラーによって着色されたもので, pngで画像を読み込めばそのままクラスを表すarrayになってくれるんです.

画像で説明するとこんな感じ. f:id:ket-30:20170218124136p:plain

当たり前な人にとっては当たり前なのかもしれませんが, 多分1人で勉強してるとなかなか分からなかったりすると思います. この情報だけで実装にかかる時間は何倍も短縮できますからね. この情報が誰かの役に立つことを望みます.

アルファブレンドについて

今回の出力は元画像にsegmentationした画像を重ねているのですが, こういうのをアルファブレンドって言ったりするそうです.

アルファブレンド - Wikipedia

こういう画像そのものの学習を自分は怠っていると感じました, pngとかjpgとかちゃんとわかってないしなぁ. もっと基本的なところから勉強して, いずれ記事にまとめたいところ.

PILでアルファブレンドする方法がわからなかったので, そこだけopencv使っています.

o = cv2.imread("out/original.jpg", 1)
p = cv2.imread("out/pred.png", 1)

# 0.6, 0.4 は比です.
pred = cv2.addWeighted(o, 0.6, p, 0.4, 0.0)

参考

今回もたくさんのブログ, レポジトリを参考にさせていただきました.
ありがとうございました.

chainerそのものとFCNの参考
https://github.com/yusuketomoto/chainer-fast-neuralstyle https://github.com/pfnet/PaintsChainer
memo: Fully Convolutional Networks 〜 Chainerによる実装 〜

PILでは透化の合成ができなかったけど, このへん試しました.
Python + Pillow(PIL)で、透過したpng画像を作成する - Symfoware 画像処理についてあれこれ: Python Imaging Libraryを使用して画像を重ね合わせる

結果的にはこちらの方法です. ありがとうございました.
Python3 OpenCV3で平均値画像(Alpha Blending)を作成 | from umentu import stupid