みなさんにコメント何件か頂いたので、再評価してみました。
環境については、前回の記事を参照してください。
.keras.jsonのimage_dim_orderingの設定
image_dim_ordering: 文字列, "tf" か "th" によって、channel_firstかchannel_lastのいずれかになるのではないかとのご指摘です。
data_formatの初期値
また、Hirofumi Yashimaさんからは、初期化メソッドにて、data_formatはNoneになるのではないかとのご指摘です。
こちらの記事の冒頭 で、以下、
class Conv1D(_Conv) 中、親クラスの初期化メソッド を 呼び出しているところ
に 注目されています が 、
convolutional.py#L233
class Conv1D(_Conv):
.
.
super(Conv1D, self).init(
rank=1,
filters=filters,
kernel_size=kernel_size,
strides=strides,
padding=padding,
data_format='channels_last',
>conv1dメソッド を data_format引数に何も渡さず に 呼び出すと、
data_format は デフォルト設定 の data_format=None に 切り替わり、
tf_data_format = 'NCW' に なるのではないでしょうか?
>>```python:convolutional.py#L233
conv1d(x, kernel, strides=1, padding='valid',
data_format=None, dilation_rate=1):
if data_format == 'channels_last':
tf_data_format = 'NWC'
else:
tf_data_format = 'NCW'
評価方法
ソースコードを読んでるより、実際書いてみてdata_formatがどうなっているのかを確認してみました。
確認方法
from keras.models import Model, Sequential
from keras import backend as K
from keras.layers import Input, Conv1D, Flatten, Dense
Using TensorFlow backend.
- image_dim_orderがthかtfどちらになっているのか確認します。
K.image_dim_ordering()
'tf'
tfですね。
- 次は、image_data_formatがchannels_firstかchannels_lastどちらになっているのかを確認します。
K.image_data_format()
'channels_last'
channels_lastですね。
- image_dim_orderをthに変えて、image_dim_orderingとimage_data_formatを確認します。
K.set_image_dim_ordering('th')
K.image_dim_ordering()
'th'
K.image_data_format()
'channels_first'
channels_firstになっています。
DATA_SAMPLES = 20
CHANNELS = 1
DATA_LENGTH = 10
KERNEL_SIZE = 3
FILTERS = 50
- Modelクラスのget_configでdata_formatが拾えないか見てみたのですが、以下の通り、data_formatを削除しているようでした。
def get_config(self):
config = super(Conv1D, self).get_config()
config.pop('rank')
config.pop('data_format')
return config
- そこで、Conv1Dを基底クラスとして、ラッパークラス作って、そのラッパークラスを呼び出すとき、data_formatを表示してやり、さらに、get_configを返す際、data_formatを削除しないようにしてみました。
class Conv1D_test(Conv1D):
def get_config(self):
config = super(Conv1D, self).get_config()
#config.pop('rank')
#config.pop('data_format')
return config
def call(self, inputs):
print(self.data_format)
outputs = Conv1D.call(self, inputs)
print(self.data_format)
return outputs
shape=(None, DATA_LENGTH, CHANNELS)
input_layer = Input(batch_shape=shape)
conv_1d_output_layer = Conv1D_test(FILTERS, KERNEL_SIZE, padding='same')(input_layer)
flatten_output_layer = Flatten()(conv_1d_output_layer)
prediction_result = Dense(1)(flatten_output_layer)
model = Model(inputs=input_layer, outputs=prediction_result)
channels_last
channels_last
となり、data_formatはK.set_image_dim_orderingに関わらず、channels_lastとなっています。
また、get_configの結果についても、「'data_format': 'channels_last'」となっています。
model.get_config()
{'input_layers': [['input_1', 0, 0]],
'layers': [{'class_name': 'InputLayer',
'config': {'batch_input_shape': (None, 10, 1),
'dtype': 'float32',
'name': 'input_1',
'sparse': False},
'inbound_nodes': [],
'name': 'input_1'},
{'class_name': 'Conv1D_test',
'config': {'activation': 'linear',
'activity_regularizer': None,
'bias_constraint': None,
'bias_initializer': {'class_name': 'Zeros', 'config': {}},
'bias_regularizer': None,
'data_format': 'channels_last',
'dilation_rate': (1,),
'filters': 50,
'kernel_constraint': None,
'kernel_initializer': {'class_name': 'VarianceScaling',
'config': {'distribution': 'uniform',
'mode': 'fan_avg',
'scale': 1.0,
'seed': None}},
'kernel_regularizer': None,
'kernel_size': (3,),
'name': 'conv1d_test_1',
'padding': 'same',
'rank': 1,
'strides': (1,),
'trainable': True,
'use_bias': True},
'inbound_nodes': [[['input_1', 0, 0, {}]]],
'name': 'conv1d_test_1'},
{'class_name': 'Flatten',
'config': {'name': 'flatten_1', 'trainable': True},
'inbound_nodes': [[['conv1d_test_1', 0, 0, {}]]],
'name': 'flatten_1'},
{'class_name': 'Dense',
'config': {'activation': 'linear',
'activity_regularizer': None,
'bias_constraint': None,
'bias_initializer': {'class_name': 'Zeros', 'config': {}},
'bias_regularizer': None,
'kernel_constraint': None,
'kernel_initializer': {'class_name': 'VarianceScaling',
'config': {'distribution': 'uniform',
'mode': 'fan_avg',
'scale': 1.0,
'seed': None}},
'kernel_regularizer': None,
'name': 'dense_1',
'trainable': True,
'units': 1,
'use_bias': True},
'inbound_nodes': [[['flatten_1', 0, 0, {}]]],
'name': 'dense_1'}],
'name': 'model_1',
'output_layers': [['dense_1', 0, 0]]}
結論
ということで、Conv1Dの場合、image_dim_orderに関わらず、input shapeはchannel lastで設定するということになるのではないかと思います。
ただし、これはKeras 2.0の場合でKeras 1系については確認しておりません。