2017-01-18 13 views
22

私はCNNとのバイナリ分類モデルを訓練し、そしてここに私のコードケラス、各レイヤーの出力を取得する方法は?

model = Sequential() 
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1], 
         border_mode='valid', 
         input_shape=input_shape)) 
model.add(Activation('relu')) 
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1])) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size=pool_size)) 
# (16, 16, 32) 
model.add(Convolution2D(nb_filters*2, kernel_size[0], kernel_size[1])) 
model.add(Activation('relu')) 
model.add(Convolution2D(nb_filters*2, kernel_size[0], kernel_size[1])) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size=pool_size)) 
# (8, 8, 64) = (2048) 
model.add(Flatten()) 
model.add(Dense(1024)) 
model.add(Activation('relu')) 
model.add(Dropout(0.5)) 
model.add(Dense(2)) # define a binary classification problem 
model.add(Activation('softmax')) 

model.compile(loss='categorical_crossentropy', 
       optimizer='adadelta', 
       metrics=['accuracy']) 
model.fit(x_train, y_train, 
      batch_size=batch_size, 
      nb_epoch=nb_epoch, 
      verbose=1, 
      validation_data=(x_test, y_test)) 

そしてここできたが、私はどのように私はそれを行うことができ、ちょうどTensorFlowのような各層の出力を取得したいですか?

答えて

42

あなたは簡単に使用して、任意の層の出力を得ることができます。

from keras import backend as K 

inp = model.input           # input placeholder 
outputs = [layer.output for layer in model.layers]   # all layer outputs 
functors = [K.function([inp]+ [K.learning_phase()], [out]) for out in outputs] # evaluation functions 

# Testing 
test = np.random.random(input_shape)[np.newaxis,...] 
layer_outs = [func([test, 1.]) for func in functors] 
print layer_outs 

注:すべての層についてはmodel.layers[index].output

はこれを使用layer_outs1.としてドロップアウト使用learning_phaseをシミュレートするにはそれ以外の場合は使用0.

編集:(コメントに基づいて)

K.functionは、後で入力を与えられた記号グラフからの出力を得るために使用されるtheano/tensorflowテンソル関数を作成する。ドロップアウト/ Batchnomalizationのような多くのKeras層は、訓練と試験時間中に動作を変更するためにそれに依存するよう今

K.learning_phase()を入力として必要とされます。あなたのコードでドロップアウト層を削除する場合

は、だから、単純に使用することができます。

from keras import backend as K 

inp = model.input           # input placeholder 
outputs = [layer.output for layer in model.layers]   # all layer outputs 
functors = [K.function([inp], [out]) for out in outputs] # evaluation functions 

# Testing 
test = np.random.random(input_shape)[np.newaxis,...] 
layer_outs = [func([test]) for func in functors] 
print layer_outs 

編集2:より最適化された

は、私はちょうど前の回答が用として最適化されたものではないことに気づきました各関数の評価は、データがCPU-> GPUメモリに転送され、テンソルの計算も下位層のover-n-overに対して実行される必要があります。

代わりに、これはあなたが複数の機能が、あなたのすべての出力のリストを与え、単一の機能を必要としないよう、もっと良い方法です:

from keras import backend as K 

inp = model.input           # input placeholder 
outputs = [layer.output for layer in model.layers]   # all layer outputs 
functor = K.function([inp]+ [K.learning_phase()], outputs) # evaluation function 

# Testing 
test = np.random.random(input_shape)[np.newaxis,...] 
layer_outs = functor([test, 1.]) 
print layer_outs 
+1

siあなたの答えは良いです、あなたのコードでは 'K.function([inp] + [K.learning_phase()]、[out])'は何を意味していますか? –

+0

優秀な回答、 'np.random.random(input_shape)[np.newaxis、...]'は 'np.random.random(input_shape)[np.newaxis、:]'と書くことができます。 – Tom

+0

Kとは何ですか?関数 ?それはGPU(MPI?)にどのように渡されましたか?シーンの裏には何がありますか?どのようにCUDAと話し合っていますか?ソースコードはどこですか? –

1

私は(Jupyterに)自分のためにこの関数を書き、それindraforyouの答えに触発されました。すべてのレイヤー出力を自動的にプロットします。画像は(1、1、1)の形をしていなければなりません。 plot_layer_outputs(...)を呼び出してプロットするだけです。

%matplotlib inline 
import matplotlib.pyplot as plt 
from keras import backend as K 

def get_layer_outputs(): 
    test_image = YOUR IMAGE GOES HERE!!! 
    outputs = [layer.output for layer in model.layers]   # all layer outputs 
    comp_graph = [K.function([model.input]+ [K.learning_phase()], [output]) for output in outputs] # evaluation functions 

    # Testing 
    layer_outputs_list = [op([test_image, 1.]) for op in comp_graph] 
    layer_outputs = [] 

    for layer_output in layer_outputs_list: 
     print(layer_output[0][0].shape, end='\n-------------------\n') 
     layer_outputs.append(layer_output[0][0]) 

    return layer_outputs 

def plot_layer_outputs(layer_number):  
    layer_outputs = get_layer_outputs() 

    x_max = layer_outputs[layer_number].shape[0] 
    y_max = layer_outputs[layer_number].shape[1] 
    n  = layer_outputs[layer_number].shape[2] 

    L = [] 
    for i in range(n): 
     L.append(np.zeros((x_max, y_max))) 

    for i in range(n): 
     for x in range(x_max): 
      for y in range(y_max): 
       L[i][x][y] = layer_outputs[layer_number][x][y][i] 


    for img in L: 
     plt.figure() 
     plt.imshow(img, interpolation='nearest') 
+0

モデルに複数の入力がある場合はどうなりますか?どのように入力を指定するのですか? –

+0

この行には:layer_outputs_list = [op([test_image、1.])。 1.は0にする必要がありますか? 1はトレーニングを意味し、0はテストを意味しますか?そうじゃない? – Kongsea

3

他の回答は非常に完全ですが、形状を「取得」するのではなく、「見る」という非常に基本的な方法があります。

model.summary()を実行してください。すべてのレイヤーとその出力シェイプを印刷します。続き

1

は私には非常にシンプルになります。あなたはテンソルオブジェクトに適用できる操作を使用して、それを修正することができるように

上記
model.layers[idx].output 

は、テンソルオブジェクトです。

例えば、形状model.layers[idx].output.get_shape()

idxを取得することは層の屈折率であり、あなたがhttps://keras.io/getting-started/faq/#how-can-i-obtain-the-output-of-an-intermediate-layerからmodel.summary()

1

からそれを見つけることができます。

One simple way is to create a new Model that will output the layers that you are interested in: 

from keras.models import Model 

model = ... # create the original model 

layer_name = 'my_layer' 
intermediate_layer_model = Model(inputs=model.input, 
           outputs=model.get_layer(layer_name).output) 
intermediate_output = intermediate_layer_model.predict(data) 
Alternatively, you can build a Keras function that will return the output of a certain layer given a certain input, for example: 

from keras import backend as K 

# with a Sequential model 
get_3rd_layer_output = K.function([model.layers[0].input], 
            [model.layers[3].output]) 
layer_output = get_3rd_layer_output([x])[0] 
1

から:https://github.com/philipperemy/keras-visualize-activations/blob/master/read_activations.py

import keras.backend as K 

def get_activations(model, model_inputs, print_shape_only=False, layer_name=None): 
    print('----- activations -----') 
    activations = [] 
    inp = model.input 

    model_multi_inputs_cond = True 
    if not isinstance(inp, list): 
     # only one input! let's wrap it in a list. 
     inp = [inp] 
     model_multi_inputs_cond = False 

    outputs = [layer.output for layer in model.layers if 
       layer.name == layer_name or layer_name is None] # all layer outputs 

    funcs = [K.function(inp + [K.learning_phase()], [out]) for out in outputs] # evaluation functions 

    if model_multi_inputs_cond: 
     list_inputs = [] 
     list_inputs.extend(model_inputs) 
     list_inputs.append(0.) 
    else: 
     list_inputs = [model_inputs, 0.] 

    # Learning phase. 0 = Test mode (no dropout or batch normalization) 
    # layer_outputs = [func([model_inputs, 0.])[0] for func in funcs] 
    layer_outputs = [func(list_inputs)[0] for func in funcs] 
    for layer_activations in layer_outputs: 
     activations.append(layer_activations) 
     if print_shape_only: 
      print(layer_activations.shape) 
     else: 
      print(layer_activations) 
    return activations 
関連する問題