Tf.nn.avg_pool、tf.nn.max_pool、tf.nn.conv2dのstrides引数を理解しようとしています。
ドキュメント 繰り返し言う
strides:長さが4以上の整数のリスト。入力テンソルの各次元のスライディングウィンドウのストライド。
私の質問は:
tf.reshape(_X,shape=[-1, 28, 28, 1])
が表示されます。なぜ-1ですか?残念なことに、-1を使用したreshapeのドキュメントの例は、このシナリオにうまく変換できません。
プーリングと畳み込み演算は、入力テンソルを横切る「ウィンドウ」をスライドさせます。例として tf.nn.conv2d
を使用する場合:入力テンソルが4次元の場合、[batch, height, width, channels]
の場合、畳み込みはheight, width
次元の2Dウィンドウで動作します。
strides
は、各次元でウィンドウがどれだけシフトするかを決定します。典型的な使用法では、最初(バッチ)と最後(深さ)のストライドを1に設定します。
非常に具体的な例を使用してみましょう。32x32グレースケール入力画像上で2次元畳み込みを実行します。グレースケールと言うのは、入力画像がdepth = 1であるため、シンプルに保つためです。そのイメージを次のようにします。
00 01 02 03 04 ...
10 11 12 13 14 ...
20 21 22 23 24 ...
30 31 32 33 34 ...
...
1つの例(バッチサイズ= 1)で2x2の畳み込みウィンドウを実行してみましょう。畳み込みに8の出力チャネル深度を与えます。
畳み込みへの入力にはshape=[1, 32, 32, 1]
があります。
strides=[1,1,1,1]
にpadding=SAME
を指定すると、フィルターの出力は[1、32、32、8]になります。
フィルタは、最初に次の出力を作成します。
F(00 01
10 11)
それから:
F(01 02
11 12)
等々。次に、2番目の行に移動して、以下を計算します。
F(10, 11
20, 21)
それから
F(11, 12
21, 22)
[1、2、2、1]のストライドを指定すると、ウィンドウのオーバーラップは行われません。以下を計算します:
F(00, 01
10, 11)
その後
F(02, 03
12, 13)
ストライドは、プーリングオペレーターに対しても同様に動作します。
質問2:なぜconvnetsのために[1、x、y、1]を踏む
最初の1つはバッチです。通常、バッチ内の例をスキップしたくない、または最初の場所に含めるべきではありません。 :)
最後の1は畳み込みの深さです。同じ理由で、通常は入力をスキップする必要はありません。
Conv2d演算子はより一般的であるため、couldウィンドウを他の次元に沿ってスライドさせる畳み込みを作成できますが、convnetsでの一般的な使用法ではありません。典型的な使用法は、それらを空間的に使用することです。
-1に再整形する理由-1は、「フルテンソルに必要なサイズに合わせて必要に応じて調整する」というプレースホルダーです。これは、コードを入力バッチサイズに依存しないようにする方法であるため、パイプラインを変更でき、コード内のどこでもバッチサイズを調整する必要はありません。
入力は4次元で、形式は[batch_size, image_rows, image_cols, number_of_colors]
です。
一般に、ストライドは、適用操作間のオーバーラップを定義します。 conv2dの場合、畳み込みフィルターの連続したアプリケーション間の距離を指定します。特定のディメンションの値1は、すべての行/列に演算子を適用することを意味し、値2は毎秒を意味します。
Re 1)畳み込みに重要な値は2番目と3番目で、行と列に沿った畳み込みフィルターの適用におけるオーバーラップを表します。 [1、2、2、1]の値は、2行ごとにフィルターを適用することを示しています。
Re 2)技術的な制限はわかりませんが(CuDNNの要件かもしれません)、通常、人々は行または列の次元に沿ってストライドを使用します。バッチサイズを超えることは必ずしも意味がありません。最後の次元がわからない。
Re 3)次元の1つに-1を設定すると、「テンソルの要素の総数が変わらないように最初の次元の値を設定する」という意味になります。この場合、-1はbatch_sizeと等しくなります。
input = [1, 0, 2, 3, 0, 1, 1]
とkernel = [2, 1, 3]
を畳み込みの結果が[8, 11, 7, 9, 4]
であると仮定しましょう。これは、入力上でカーネルをスライドさせ、要素ごとの乗算を実行し、すべてを合計することによって計算されます。 これに似ています :
ここでは、1つの要素ごとにスライドしますが、他の番号を使用しても何も妨げられません。この数字はあなたの歩みです。すべてのs番目の結果を取得するだけで、1のたたみ込みの結果をダウンサンプリングすると考えることができます。
入力サイズi、カーネルサイズk、ストライドsおよびパディングp畳み込みの出力サイズは次のように簡単に計算できます。
ここ||演算子は天井操作を意味します。プーリング層の場合s = 1。
1次元の場合の数学を知っていれば、各次元が独立していることがわかると、n次元の場合は簡単です。したがって、各次元を個別にスライドするだけです。 2-dの例 です。すべての次元で同じストライドを使用する必要はありません。したがって、N次元の入力/カーネルの場合、Nストライドを提供する必要があります。
Shapeの1つのコンポーネントが特別な値-1の場合、合計サイズが一定になるように、その次元のサイズが計算されます。特に、[-1]の形状は1次元に平坦化されます。シェイプの最大1つのコンポーネントは-1です。
@dgaはすばらしい説明をしてくれました。それがどれほど役に立ったかに感謝できません。同様に、stride
が3D畳み込みでどのように機能するかについての調査結果を共有したいと思います。
Conv3dの TensorFlow documentation によると、入力の形状は次の順序である必要があります。
[batch, in_depth, in_height, in_width, in_channels]
例を使用して、右端から左に向かって変数を説明しましょう。入力形状がinput_shape = [1000,16,112,112,3]
であると仮定します
input_shape[4] is the number of colour channels (RGB or whichever format it is extracted in)
input_shape[3] is the width of the image
input_shape[2] is the height of the image
input_shape[1] is the number of frames that have been lumped into 1 complete data
input_shape[0] is the number of lumped frames of images we have.
以下は、ストライドの使用方法に関する概要ドキュメントです。
strides:長さが5以上のintのリスト。長さ5の1次元テンソル。入力の各次元のスライディングウィンドウのストライド。
strides[0] = strides[4] = 1
が必要です
多くの作品で示されているように、ストライドとは、データフレームまたはピクセルにかかわらず、ウィンドウまたはカーネルが最も近い要素からジャンプしていくステップ数を意味します(これはちなみに言い換えられています)。
上記のドキュメントから、3Dのストライドは次のようになります=(1、X、Y、Z、1)。
ドキュメントでは、strides[0] = strides[4] = 1
を強調しています。
strides[0]=1 means that we do not want to skip any data in the batch
strides[4]=1 means that we do not want to skip in the channel
strides [X]は、ひとまとめのフレームで何回スキップするかを意味します。たとえば、16フレームがある場合、X = 1はすべてのフレームを使用することを意味します。 X = 2は、1秒おきにフレームを使用することを意味します
strides [y]とstrides [z]は @ dga の説明に従っているので、その部分はやり直しません。
ただし、kerasでは、各空間次元に沿った畳み込みのストライドを指定する3つの整数のタプル/リストを指定するだけでよく、空間次元はstride [x]、strides [y]およびstrides [z]です。 strides [0]とstrides [4]はすでにデフォルトで1に設定されています。
誰かがこれが役立つことを願っています!