TensorFlowで有名モデルをスクラッチから学習するときの注意点

こんにちはtatsyです。

私はDeep Learningのフレームワークは主にTensorFlowを使っているのですが、今回GoogLeNetのInception-v3というモデルをImageNet以外のデータで学習させた時に少しハマったので、解決策を共有しておきます。

ここで有名モデルと言っているのはAlexNetやVGG, GoogLeNet, ResNetといったILSVRCという画像認識コンテストで良い成績を獲得した深層学習モデルのことです。

これらのモデルは多くのフレームワークで実装が組み込まれていて、TensorFlowもインストールした段階でこの実装が用意されています。

TensorFlowの場合は有名モデルがSlimという軽量のラッパで書かれており、

import tensorflow.contrib.slim.nets as nets

outputs, layers = nets.inception.inception_v3(inputs, ...)

のように書くことで使い始めることが可能です。

ところが、このように呼び出して学習をしてみたところ、どんなに回しても識別率が向上せず、挙句の果てにPyTorchで同じコードを書いて確認してみたところ、PyTorchでは問題なく学習ができたため、TensorFlowの問題で何かがおかしいのだろうと思いました。

結論として、こちらのネットワークがSlimを使って書かれているために、使用時にはArgument scopeというデフォルト引数を定義するスコープを使う必要があることが分かりました。

Inception-v3の例であれば、正しくは以下のように呼び出す必要があります。

import tensorflow.contrib.slim as slim
import tensorflow.contrib.slim.nets as nets

arg_scope = nets.inception.inception_v3_arg_scope()
with slim.arg_scope(arg_scope):
    outputs, layers = nets.inception.inception_v3(inputs, ...)

結構長くTensorFlowを使っているのですが、あまりSlimには触ったことがなかったので、意外なところで時間を使ってしまいました。

もし、同じような症状に悩まれている方がいれば何らかの助けになれば幸いです。