提案されたトリックは実際には正しくないと思います。 tf.conv3d()
レイヤーで起こることは、入力が深度(=実際のバッチ)ディメンションで畳み込まれ、結果のフィーチャーマップに沿って合計されることです。 padding='SAME'
を使用すると、結果の出力数はバッチサイズと同じになるので、だまされます。
EDIT:さまざまなミニバッチ要素に対して異なるフィルタを使用して畳み込みを行う方法として、深さ方向の畳み込みを「ハッキングする」ことが考えられます。次のようにあなたがtf.map_fn
を使用することができます(と思う)場合MB
に
inp = tf.placeholder(tf.float32, [MB, H, W, channels_img])
# F has shape (MB, fh, fw, channels, out_channels)
# REM: with the notation in the question, we need: channels_img==channels
F = tf.transpose(F, [1, 2, 0, 3, 4])
F = tf.reshape(F, [fh, fw, channels*MB, out_channels)
inp_r = tf.transpose(inp, [1, 2, 0, 3]) # shape (H, W, MB, channels_img)
inp_r = tf.reshape(inp, [1, H, W, MB*channels_img])
out = tf.nn.depthwise_conv2d(
inp_r,
filter=F,
strides=[1, 1, 1, 1],
padding='VALID') # here no requirement about padding being 'VALID', use whatever you want.
# Now out shape is (1, H, W, MB*channels*out_channels)
out = tf.reshape(out, [H, W, MB, channels, out_channels) # careful about the order of depthwise conv out_channels!
out = tf.transpose(out, [2, 0, 1, 3, 4])
out = tf.reduce_sum(out, axis=3)
# out shape is now (MB, H, W, out_channels)
が不明で、tf.shape()
を使用して動的に決定することが可能でなければなりません
おそらく 'tf.expand_dims'を使って '偽ミニバッチディメンション'を追加した後、' tf.nn.conv3d'を使うことができます。ここで、フィルタ深度はバッチサイズと一致します。可変バッチサイズでどれくらいうまくいくかはわかりません。 –
@RobertLacok素晴らしいアイデアのように聞こえます。唯一の問題は、私がそれを行うと、私は新しい空間次元(ミニバッチ次元)のサイズを知らないということです。しかし、私は試してみて...多分それはとにかく動作します... –
私はあなたがそれの上限を知って、その次元で重み(フィルタ)を初期化する必要があると思います。次に、実行時に、 'batch_size = tf.shape(input)[0]'のようなことを行い、ディメンションを推測し、フィルタのスライスだけを使用することができます。純粋に示唆していますが、私はそのようなことを試みたことはないので、問題を引き起こす可能性があります。 –