web-dev-qa-db-ja.com

Kerasでレイヤーの出力形状を取得する方法は?

Kerasに次のコードがあり(基本的に使用するためにこのコードを変更しています)、このエラーが発生します。

「ValueError:ターゲットのチェック時のエラー:conv3d_3は5次元であると予想されますが、形状(10、4096)の配列を取得しました」

コード:

from keras.models import Sequential
from keras.layers.convolutional import Conv3D
from keras.layers.convolutional_recurrent import ConvLSTM2D
from keras.layers.normalization import BatchNormalization
import numpy as np
import pylab as plt
from keras import layers

# We create a layer which take as input movies of shape
# (n_frames, width, height, channels) and returns a movie
# of identical shape.

model = Sequential()
model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
                   input_shape=(None, 64, 64, 1),
                   padding='same', return_sequences=True))
model.add(BatchNormalization())

model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
                   padding='same', return_sequences=True))
model.add(BatchNormalization())

model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
                   padding='same', return_sequences=True))
model.add(BatchNormalization())

model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
                   padding='same', return_sequences=True))
model.add(BatchNormalization())

model.add(Conv3D(filters=1, kernel_size=(3, 3, 3),
               activation='sigmoid',
               padding='same', data_format='channels_last'))
model.compile(loss='binary_crossentropy', optimizer='adadelta')

フィードするデータの形式は[1、10、64、64、1]です。だから私はどこが間違っているのか、また各レイヤーのoutput_shapeを見る方法を知りたいです。

_layer.output_shape_ でレイヤーの出力形状を取得できます。

_for layer in model.layers:
    print(layer.output_shape)
_

あなたにあげる:

_(None, None, 64, 64, 40)
(None, None, 64, 64, 40)
(None, None, 64, 64, 40)
(None, None, 64, 64, 40)
(None, None, 64, 64, 40)
(None, None, 64, 64, 40)
(None, None, 64, 64, 40)
(None, None, 64, 64, 40)
(None, None, 64, 64, 1)
_

あるいは、 _model.summary_ を使用してモデルをきれいに印刷できます:

_model.summary()
_

パラメーターの数と各レイヤーの出力形状および全体的なモデル構造に関する詳細をきれいな形式で提供します。

__________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv_lst_m2d_1 (ConvLSTM2D)  (None, None, 64, 64, 40)  59200     
_________________________________________________________________
batch_normalization_1 (Batch (None, None, 64, 64, 40)  160       
_________________________________________________________________
conv_lst_m2d_2 (ConvLSTM2D)  (None, None, 64, 64, 40)  115360    
_________________________________________________________________
batch_normalization_2 (Batch (None, None, 64, 64, 40)  160       
_________________________________________________________________
conv_lst_m2d_3 (ConvLSTM2D)  (None, None, 64, 64, 40)  115360    
_________________________________________________________________
batch_normalization_3 (Batch (None, None, 64, 64, 40)  160       
_________________________________________________________________
conv_lst_m2d_4 (ConvLSTM2D)  (None, None, 64, 64, 40)  115360    
_________________________________________________________________
batch_normalization_4 (Batch (None, None, 64, 64, 40)  160       
_________________________________________________________________
conv3d_1 (Conv3D)            (None, None, 64, 64, 1)   1081      
=================================================================
Total params: 407,001
Trainable params: 406,681
Non-trainable params: 320
_________________________________________________________________
_

特定のレイヤーに関する情報のみにアクセスしたい場合、そのレイヤーを構築するときにname引数を使用して、次のように呼び出すことができます。

_...
model.add(ConvLSTM2D(..., name='conv3d_0'))
...

model.get_layer('conv3d_0')
_

EDIT:参考のため、これは常に_layer.output_shape_と同じであり、実際にはLambdaまたはカスタムレイヤーを使用しないでください。ただし、 Lambda layerを使用して、通過するテンソルの形状をエコーできます。

_...
def print_tensor_shape(x):
    print(x.shape)
    return x
model.add(Lambda(print_tensor_shape))
...
_

または、カスタムレイヤーを記述して、call()にテンソルの形状を印刷します。

_class echo_layer(Layer):
...
    def call(self, x):
        print(x.shape)
        return x
...

model.add(echo_layer())
_
16
umutto