SqueezeNetの読み込み

450 views
Skip to first unread message

wataru yasuda

unread,
Sep 8, 2016, 9:57:56 AM9/8/16
to Chainer Japanese User Group
SqueezeNet学習済caffeモデルをchainerに読み込もうと、以下の記事を参考にしました。

Chainerでcaffemodelを読み込んで画像を分類する

こちらのソースコードで、新たに以下のクラスを作成しました。

class SqueezeNet(NNModel):
    def __init__(self):
        NNModel.__init__(self)

    def _image_shape(self):
        return (227, 227)

    def _mean_image(self):
        mean_image = np.ndarray((3, 227, 227), dtype=np.float32)
        mean_image[0] = 103.939
        mean_image[1] = 116.779
        mean_image[2] = 123.68
        return mean_image

    def _predict_class(self, x):
        y, = self.func(inputs={'data': x}, outputs=['pool10'], train=False)
        return F.softmax(y)

添付の画像で実行してみたところ、GoogleNetでは「36.70% tabby, tabby cat」という結果が出たのですが、SqueezeNetでは以下のワーニングが出て、「nan% tench, Tinca tinca」という結果になりました。

Warning (from warnings module):
  File "C:\Python27\lib\site-packages\numpy\core\_methods.py", line 59
    warnings.warn("Mean of empty slice.", RuntimeWarning)
RuntimeWarning: Mean of empty slice.

Warning (from warnings module):
  File "C:\Python27\lib\site-packages\numpy\core\_methods.py", line 68
    ret, rcount, out=ret, casting='unsafe', subok=False)
RuntimeWarning: invalid value encountered in true_divide

正しく動作していないようですが、SqueezeNetのcaffeモデルはchainerに読み込むことが出来ないのでしょうか。

アドバイス頂けましたら幸いです。

以上、よろしくお願い致します。
2.jpg

Daiki Sanno

unread,
Sep 11, 2016, 9:13:37 AM9/11/16
to Chainer Japanese User Group
Chainerでcaffemodelを読み込んで画像を分類する」を投稿した者です

以下のSqueezeNetのprototxtを確認したところ
https://github.com/DeepScale/SqueezeNet/blob/master/SqueezeNet_v1.0/deploy.prototxt

layer "pool10"の定義が以下のようになっているのですが、Chainerが"global_pooling"属性に対応していないようです。

layer {
  name: "pool10"
   type: "Pooling"
   bottom: "conv10"
   top: "pool10"
   pooling_param {
     pool: AVE
     global_pooling: true
   }
}

元のコードの_predict_classでaverage poolingのkernel sizeを明示的に指定したところうまく動作しました。

    def _predict_class(self, x):
        y, = self.func(inputs={'data': x}, outputs=['conv10'], train=False)
        return F.softmax(F.average_pooling_2d(y, 15))

ただこの修正を行ってもWarningは発生します。
Warningの原因が何で認識結果に影響が出るかどうかまではわかっていません。


2016年9月8日木曜日 22時57分56秒 UTC+9 wataru yasuda:

wataru yasuda

unread,
Sep 14, 2016, 3:37:57 AM9/14/16
to Chainer Japanese User Group
Sanno様

アドバイスありがとうございます。
教えて頂いたとおり_predict_classを変更してみましたが、結果は変わりませんでした。
私の方はChainerの1.15.0を使用しているのですが、それが原因でしょうか。


2016年9月11日日曜日 22時13分37秒 UTC+9 Daiki Sanno:

Daiki Sanno

unread,
Sep 14, 2016, 10:48:03 AM9/14/16
to Chainer Japanese User Group

確認したところSqueezeNetのv1.0とv1.1で構造が違うようで、conv10の幅高さが異なっていました。(v1.0は(15, 15)、v1.1は(14, 14))
以下のようにconv10のレイヤーに合わせてkernel sizeを指定するのはどうでしょうか?


    def _predict_class(self, x):
        y, = self.func(inputs={'data': x}, outputs=['conv10'], train=False)
        return F.softmax(F.average_pooling_2d(y, y.data.shape[2:]))

これでも動かない場合はSqueezeNetのレイヤーの出力を1つずつ確認してどこでNaNになるのかを確認するのがよいと思います。


2016年9月14日水曜日 16時37分57秒 UTC+9 wataru yasuda:

wataru yasuda

unread,
Sep 15, 2016, 4:10:50 AM9/15/16
to Chainer Japanese User Group
Sanno様

アドバイスありがとうございます。
ソースコード変更してみましたが、同じ結果でした。
レイヤーを一個一個たどってみようかと思います。
ありがとうございました。

2016年9月14日水曜日 23時48分03秒 UTC+9 Daiki Sanno:
Reply all
Reply to author
Forward
0 new messages