मैं अंतर को विस्तार से और विस्तार से बताना चाहता हूं (कोड में टिप्पणी) और बहुत आसान तरीके से।
पहले TensorFlow में Conv2D की जांच करते हैं ।
c1 = [[0, 0, 1, 0, 2], [1, 0, 2, 0, 1], [1, 0, 2, 2, 0], [2, 0, 0, 2, 0], [2, 1, 2, 2, 0]]
c2 = [[2, 1, 2, 1, 1], [2, 1, 2, 0, 1], [0, 2, 1, 0, 1], [1, 2, 2, 2, 2], [0, 1, 2, 0, 1]]
c3 = [[2, 1, 1, 2, 0], [1, 0, 0, 1, 0], [0, 1, 0, 0, 0], [1, 0, 2, 1, 0], [2, 2, 1, 1, 1]]
data = tf.transpose(tf.constant([[c1, c2, c3]], dtype=tf.float32), (0, 2, 3, 1))
# we transfer [batch, in_channels, in_height, in_width] to [batch, in_height, in_width, in_channels]
# where batch = 1, in_channels = 3 (c1, c2, c3 or the x[:, :, 0], x[:, :, 1], x[:, :, 2] in the gif), in_height and in_width are all 5(the sizes of the blue matrices without padding)
f2c1 = [[0, 1, -1], [0, -1, 0], [0, -1, 1]]
f2c2 = [[-1, 0, 0], [1, -1, 0], [1, -1, 0]]
f2c3 = [[-1, 1, -1], [0, -1, -1], [1, 0, 0]]
filters = tf.transpose(tf.constant([[f2c1, f2c2, f2c3]], dtype=tf.float32), (2, 3, 1, 0))
# we transfer the [out_channels, in_channels, filter_height, filter_width] to [filter_height, filter_width, in_channels, out_channels]
# out_channels is 1(in the gif it is 2 since here we only use one filter W1), in_channels is 3 because data has three channels(c1, c2, c3), filter_height and filter_width are all 3(the sizes of the filter W1)
# f2c1, f2c2, f2c3 are the w1[:, :, 0], w1[:, :, 1] and w1[:, :, 2] in the gif
output = tf.squeeze(tf.nn.conv2d(data, filters, strides=2, padding=[[0, 0], [1, 1], [1, 1], [0, 0]]))
# this is just the o[:,:,1] in the gif
# <tf.Tensor: id=93, shape=(3, 3), dtype=float32, numpy=
# array([[-8., -8., -3.],
# [-3., 1., 0.],
# [-3., -8., -5.]], dtype=float32)>
और Conv1D Conv1D का एक विशेष मामला है जैसा कि इस पैरा में Conv1D के TensorFlow doc से बताया गया है ।
आंतरिक रूप से, यह सेशन इनपुट टेनर्स को फिर से व्यवस्थित करता है और tf.nn.conv2d को आमंत्रित करता है। उदाहरण के लिए, यदि data_format "NC", आकार के दसवें भाग [बैच, in_width, in_channels] के साथ [बैच, 1, in_width, in_channels] पर फिर से शुरू नहीं होता है, और फ़िल्टर को [1, फ़िल्टर_ एक्सपोज़र, in_channels, के लिए पुन: आकार दिया जाता है out_channels]। फिर परिणाम को [बैच, आउट_ एक्सपोज़र, आउट_चैनल्स] (जहाँ आउट_एक्सएक्सएक्स के रूप में स्ट्राइड और पेडिंग का एक कार्य है) में वापस लाया जाता है और कॉलर को वापस कर दिया जाता है।
आइए देखें कि हम Conv1D को कन्वर्ज़न 2 की समस्या में भी कैसे स्थानांतरित कर सकते हैं। चूंकि Conv1D का उपयोग आमतौर पर एनएलपी परिदृश्यों में किया जाता है, इसलिए हम इसे एनएलपी समस्या में चित्रित कर सकते हैं।
cat = [0.7, 0.4, 0.5]
sitting = [0.2, -0.1, 0.1]
there = [-0.5, 0.4, 0.1]
dog = [0.6, 0.3, 0.5]
resting = [0.3, -0.1, 0.2]
here = [-0.5, 0.4, 0.1]
sentence = tf.constant([[cat, sitting, there, dog, resting, here]]
# sentence[:,:,0] is equivalent to x[:,:,0] or c1 in the first example and the same for sentence[:,:,1] and sentence[:,:,2]
data = tf.reshape(sentence), (1, 1, 6, 3))
# we reshape [batch, in_width, in_channels] to [batch, 1, in_width, in_channels] according to the quote above
# each dimension in the embedding is a channel(three in_channels)
f3c1 = [0.6, 0.2]
# equivalent to f2c1 in the first code snippet or w1[:,:,0] in the gif
f3c2 = [0.4, -0.1]
# equivalent to f2c2 in the first code snippet or w1[:,:,1] in the gif
f3c3 = [0.5, 0.2]
# equivalent to f2c3 in the first code snippet or w1[:,:,2] in the gif
# filters = tf.constant([[f3c1, f3c2, f3c3]])
# [out_channels, in_channels, filter_width]: [1, 3, 2]
# here we have also only one filter and also three channels in it. please compare these three with the three channels in W1 for the Conv2D in the gif
filter1D = tf.transpose(tf.constant([[f3c1, f3c2, f3c3]]), (2, 1, 0))
# shape: [2, 3, 1] for the conv1d example
filters = tf.reshape(filter1D, (1, 2, 3, 1)) # this should be expand_dim actually
# transpose [out_channels, in_channels, filter_width] to [filter_width, in_channels, out_channels]] and then reshape the result to [1, filter_width, in_channels, out_channels] as we described in the text snippet from Tensorflow doc of conv1doutput
output = tf.squeeze(tf.nn.conv2d(data, filters, strides=(1, 1, 2, 1), padding="VALID"))
# the numbers for strides are for [batch, 1, in_width, in_channels] of the data input
# <tf.Tensor: id=119, shape=(3,), dtype=float32, numpy=array([0.9 , 0.09999999, 0.12 ], dtype=float32)>
मान लें कि Conv1D (TensorFlow में भी) का उपयोग कर:
output = tf.squeeze(tf.nn.conv1d(sentence, filter1D, stride=2, padding="VALID"))
# <tf.Tensor: id=135, shape=(3,), dtype=float32, numpy=array([0.9 , 0.09999999, 0.12 ], dtype=float32)>
# here stride defaults to be for the in_width
हम देख सकते हैं कि Conv2D में 2 डी का अर्थ है कि इनपुट और फ़िल्टर में प्रत्येक चैनल 2 आयामी है (जैसा कि हम gif उदाहरण में देखते हैं) और Conv1D में 1D का अर्थ है इनपुट और फ़िल्टर में प्रत्येक चैनल 1 आयामी है (जैसा कि हम बिल्ली में देखते हैं। और कुत्ता एनएलपी उदाहरण)।