wide and deep

keras/tensorflowでdilated convolutionをstrides!=1で使う

keras(tensorflow backend)にはdilated convolutionが実装されている.
Convolutionalレイヤー - Keras Documentation

keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=...)

Conv2Dにdilation_rateとして引数を渡せばいいのだが,

dilation_rate: 整数か2つの整数からなるタプル/リストで,dilated convolutionで使われる膨張率を指定します. 現在,dilation_rate value != 1 とすると,strides value != 1を指定することはできません.
dilation_rate: an integer or tuple/list of 2 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.

とあるようにdilated convを使うときにはstridesを1以外にできない.

inputs = Input(shape=(7*224, 7*224, 3))
x = Conv2D(64, (3, 3), strides=(7, 7), padding='same', activation='relu', dilation_rate=(2, 2),
            kernel_initializer='he_normal')(inputs)
...

上記のようにムリヤリ使おうとしても,もちろんエラーが出る.

  File ".\train.py", line 151, in <module>
    main()
  File ".\train.py", line 77, in main
    kernel_initializer='he_normal')(inputs)
  File "C:\Python36\lib\site-packages\keras\engine\base_layer.py", line 457, in __call__
    output = self.call(inputs, **kwargs)
  File "C:\Python36\lib\site-packages\keras\layers\convolutional.py", line 168, in call
    dilation_rate=self.dilation_rate)
  File "C:\Python36\lib\site-packages\keras\backend\tensorflow_backend.py", line 3565, in conv2d
    data_format=tf_data_format)
  File "C:\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 779, in convolution
    data_format=data_format)
  File "C:\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 842, in __init__
    num_spatial_dims, strides, dilation_rate)
  File "C:\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py", line 641, in _get_strides_and_dilation_rate
    "strides > 1 not supported in conjunction with dilation_rate > 1")

エラーを見て"C:\Python36\lib\site-packages\tensorflow\python\ops\nn_ops.py"(パスは人による:仮想環境を使うべき...)の
関数_get_strides_and_dilation_rate()内,下記の箇所を書き換えValueErrorが出ないようにした.

  if np.any(strides > 1) and np.any(dilation_rate > 1):
    # raise ValueError(
    #     "strides > 1 not supported in conjunction with dilation_rate > 1")
    print("strides > 1 not supported in conjunction with dilation_rate > 1")

これで上記のdilation_rate!=1, strides!=1のconv層を作成できるようになった.
あまり使い所はないかもしれないが,どうしても等間隔でdilated convをしたいときにどうぞ.

dilated conv自体は下記記事を参考にさせて頂いた.
joisino.hatenablog.com