LoginSignup
4
4

More than 5 years have passed since last update.

TimeDistributedでCNNを使った時の中間層の出力の抽出

Last updated at Posted at 2017-12-26

0. はじめに

KerasでTimeDistributedを使った時に、中の畳込み層の出力を可視化したいと思ったんですが、
結構詰まったので記事にします。

1. 通常の中間層の出力の可視化

ここは実装していないんですが、以下の方法でできるみたいです。

get_feturemap.py
from keras import backend as K

#1層目の特長マップ
get_featurmap = K.function(model.layers[0].input, model.layers[0].get_output)

参考:https://github.com/keras-team/keras/issues/588

2. TimeDistributedの中身のConvolution層にアクセスする

GithubのTimeDistributedのコードを見てもget_outputがない...
どうやって中のConvolution層にアクセスしたものか...
TensorFlowだとノードでとりだせるから楽そうなんだけどなぁ

そこで,TensorFlowのページを見てみると
https://www.tensorflow.org/versions/r1.3/api_docs/python/tf/contrib/keras/layers/TimeDistributed#get_output_at
なんか使えそうなメソッドがあります。
このメソッドを使って中間層の出力を取り出します。

2.2 とりだす学習モデルの構成

私が取り出した時の構成と少し変えていますが、動作するはずです。
下にあるような構成の学習済みモデルを作ったとしてください。

Model_Architecture.py
from keras.layers.wrappers import TimeDistributed
from keras.layers.convolutional import Conv2D, MaxPooling2D
model = Sequential()
model.add(TimeDistributed(Conv2D(32, (3, 3),
                                         kernel_initializer="he_normal",
                                         activation='relu'), input_shape=self.input_shape))
model.add(TimeDistributed(Conv2D(32, (3, 3),
                                         kernel_initializer="he_normal",
                                         activation='relu')))
model.add(TimeDistributed(MaxPooling2D()))
model.add(TimeDistributed(Conv2D(32, (3, 3),
                                         kernel_initializer="he_normal",
                                         activation='relu')))
model.add(TimeDistributed(Conv2D(32, (3, 3),
                                         kernel_initializer="he_normal",
                                         activation='relu')))
model.add(TimeDistributed(MaxPooling2D()))
model.add(TimeDistributed(Flatten()))
model.add(Dense(512))
model.add(Dropout(0.5))
model.add(Dense(self.nb_classes, activation='softmax'))

2.3 Convolution層の出力を取り出す

get_featuremap_.py

from keras.models import load_model, Model
from keras import backend as K

# 学習済みモデルを読み込み
model = load_model(#saved_model)

#これでConvolution層にアクセスできる。
#get_output(0)の0はノード番号です。今回の場合0がConvolutionを表しています。
output_layer = model.layers[0].get_output_at(0)
#特徴マップ抽出関数を作ります.
get_output = K.function([model.layers[0].input], [output_layer])
#dataは入力データです.
#get_output()の出力は[array([..., ], dtype=tf.float32)とこんな構成になっているので、特徴マップを取り出したいときは[0]を指定してください。
output = get_output([data, ])[0]

上記の手順で,畳み込み層の出力が取り出せます。
最終出力ouputは(横, 縦, 枚数)と出てきますので注意してください.
これを自分の出力したいように整形、正規化してmatplotlibなりOpenCVなりで可視化してください.
ただし、注意ですが、出力枚数はフィルタの枚数分出力されます。
なので、可視化するときは1枚ずつだとか、3枚ずつにしないと可視化できません。
(32枚のチャネルって何!?ってなりますよね、一枚目が赤で、二枚目が緑で、三枚目が青、4枚目は透明度だとしても、5枚目からの扱いに困りますね)
TensorBoardのtf.summary.image()の出力も1チャネルか3チャネルか4チャネルの画像しか受け付けてくれません。

3. さいごに

読んでいただきありがとうございます.
皆様の問題解決につながれば幸いです。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4