tensorflow cnnチュートリアル

50091 ワード

tensorflow cnnチュートリアル
nlpでもcvでもcnnは非常に使いやすいツールであり,局所的特徴を抽出するのが得意である.
最も簡単な例
import tensorflow as tf
tf.enable_eager_execution()
picture = tf.reshape([0.0, 0, 0, 0, 0, 1, 3, 0, 0, 2, 2, 0, 0, 0, 0, 0], [1, 4, 4, 1])
w = tf.reshape([1, 2, 0.5, 1], [2, 2, 1, 1])
out = tf.nn.conv2d(picture, w, [1, 1, 1, 1], padding="VALID")
print(tf.squeeze(picture))
print(tf.squeeze(w))
print(tf.squeeze(out))
#         ============================
tf.Tensor(
[[0. 0. 0. 0.]
 [0. 1. 3. 0.]
 [0. 2. 2. 0.]
 [0. 0. 0. 0.]], shape=(4, 4), dtype=float32)
tf.Tensor(
[[1.  2. ]
 [0.5 1. ]], shape=(2, 2), dtype=float32)
tf.Tensor(
[[ 1.   3.5  1.5]
 [ 4.  10.   4. ]
 [ 4.   6.   2. ]], shape=(3, 3), dtype=float32)

この例では、shapeが4*4の単一チャネルピクチャpictureを入力します.私は2*2のボリュームコアwでボリュームを作って、ボリュームの結果がどのようなものかを見たいです.出力結果には、元の画像、ボリュームコア、およびボリューム結果が表示されます.この結果は、私たちが計算した結果と一致しています.
チャンネルを出力して少し追加したらどうですか?
picture = tf.reshape([0.0, 0, 0, 0, 0, 1, 3, 0, 0, 2, 2, 0, 0, 0, 0, 0], [1, 4, 4, 1])
w1 = tf.reshape([1, 2, 0.5, 1], [2, 2, 1, 1])
w2 = tf.reshape([1.0, 1, 1, 1], [2, 2, 1, 1])
w = tf.concat([w1, w2], axis=-1)
out = tf.nn.conv2d(picture, w, [1, 1, 1, 1], padding="VALID")
print(tf.squeeze(picture))
print(tf.squeeze(tf.transpose(w, [3, 0, 1, 2])))
out = tf.transpose(out, [0, 3, 1, 2])
print(tf.squeeze(out))
#         ============================
tf.Tensor(
[[0. 0. 0. 0.]
 [0. 1. 3. 0.]
 [0. 2. 2. 0.]
 [0. 0. 0. 0.]], shape=(4, 4), dtype=float32)
tf.Tensor(
[[[1.  2. ]
  [0.5 1. ]]
 [[1.  1. ]
  [1.  1. ]]], shape=(2, 2, 2), dtype=float32)
tf.Tensor(
[[[ 1.   3.5  1.5]
  [ 4.  10.   4. ]
  [ 4.   6.   2. ]]
 [[ 1.   4.   3. ]
  [ 3.   8.   5. ]
  [ 2.   4.   2. ]]], shape=(2, 3, 3), dtype=float32)

少し変更すると、出力チャネル数(channel)が1から2に変更されるため、2つのボリュームコアw 1とw 2が必要となる.2つのボリュームコアw 1とw 2を結合してwを得、そのshapeは[2*2*1*2]であり、それぞれボリュームコア長2、幅2、入力チャネル数1、出力チャネル数2を表す.ここでは、ボリューム計算のプレゼンテーションを容易にするために注意してください.実際に適用する場合,w 1とw 2をそれぞれ定義するプロセスをスキップし,wを直接初期化する.出力結果から,2つのボリュームコアは,元の画像処理後,それぞれ2枚の新しい画像を生成することが分かった.ここで、出力channel 1は、前の例の結果と完全に一致する.まとめると、出力チャネルchannelが何個あるかで、新しいピクチャが何個生成されますか.
チャンネルを入力して少し追加したらどうですか?
channel1 = tf.reshape([0.0, 0, 0, 0, 0, 1, 3, 0, 0, 2, 2, 0, 0, 0, 0, 0], [1, 4, 4, 1])
channel2 = tf.reshape([0.0, 0, 0, 0, 0, 1, 3, 0, 0, 2, 2, 0, 0, 0, 0, 0], [1, 4, 4, 1])
picture = tf.concat([channel1, channel2], axis=-1)
w1 = tf.reshape([1, 2, 0.5, 1], [2, 2, 1, 1])
w2 = tf.reshape([1.0, 1, 1, 1], [2, 2, 1, 1])
w = tf.concat([w1, w2], axis=-2)
out = tf.nn.conv2d(picture, w, [1, 1, 1, 1], padding="VALID")
print(tf.squeeze(tf.transpose(picture, [3,0,1,2])))
print(tf.squeeze(tf.transpose(w, [3, 0, 1, 2])))
out = tf.transpose(out, [0, 3, 1, 2])
print(tf.squeeze(out))
#         ============================
tf.Tensor(
[[[0. 0. 0. 0.]
  [0. 1. 3. 0.]
  [0. 2. 2. 0.]
  [0. 0. 0. 0.]]
 [[0. 0. 0. 0.]
  [0. 1. 3. 0.]
  [0. 2. 2. 0.]
  [0. 0. 0. 0.]]], shape=(2, 4, 4), dtype=float32)
tf.Tensor(
[[[1.  1. ]
  [2.  1. ]]
 [[0.5 1. ]
  [1.  1. ]]], shape=(2, 2, 2), dtype=float32)
tf.Tensor(
[[ 2.   7.5  4.5]
 [ 7.  18.   9. ]
 [ 6.  10.   4. ]], shape=(3, 3), dtype=float32)

入力channelには、入力されたピクチャが2チャネル(channel)を有し、channel 1とchannel 2からなる.実際、RGB図は3チャネルです.ボリュームコアは、w 1およびw 2がそれぞれchannel 1およびchannel 2上でボリュームを完了するため、w 1およびw 2から構成される必要がある.w 1 channel 1ボリュームとw 2 channel 2ボリュームにより,彼らの結果をさらに加算し,最終結果を得た.本例の出力は,出力結果から見て,前例で出力した2チャネル出力の結果の和である.まとめると、入力ピクチャにはn個の入力channelがあり、1個のボリュームコアにはn個のsize*sizeのマトリクスの組み合わせが必要であり、n個のchannelがそれぞれボリューム化された後、結果を加算して出力channelを得る.
以上より,ボリュームコア次元[height,width,in_channels,output_channels]の意味が分かる.
Depthwise Separable Convolutionのメリット
picture = tf.reshape([0.0, 0, 0, 0, 0, 1, 3, 0, 0, 2, 2, 0, 0, 0, 0, 0], [1, 4, 4, 1])
w = tf.reshape([1, 2, 0.5, 1], [2, 2, 1, 1])
point = tf.reshape([1.0], [1, 1, 1, 1])
out = tf.nn.separable_conv2d(picture, w, point, strides=[1, 1, 1, 1], padding="VALID")
print(tf.squeeze(picture))
print(tf.squeeze(w))
print(tf.squeeze(out))
#         ============================
tf.Tensor(
[[0. 0. 0. 0.]
 [0. 1. 3. 0.]
 [0. 2. 2. 0.]
 [0. 0. 0. 0.]], shape=(4, 4), dtype=float32)
tf.Tensor(
[[1.  2. ]
 [0.5 1. ]], shape=(2, 2), dtype=float32)
tf.Tensor(
[[ 1.   3.5  1.5]
 [ 4.  10.   4. ]
 [ 4.   6.   2. ]], shape=(3, 3), dtype=float32)

リファレンスhttps://blog.csdn.net/tintinetmilou/article/details/816077211枚の[4*4*3]の画像は、10個のボリュームコアで処理され、パラメータ量は2*2*3*10=120に達し、depthwise separable convolutionに変更され、パラメータ量は2*2*3+3*10=42で表示され、depthwise separable convolutionはパラメータ数を大幅に減少させることができる.