Conv1D และ Conv2D แตกต่างกันอย่างไร?


19

ฉันกำลังดำเนินการเอกสารการแปลงแบบ keras และพบ Convivuion Conv1 สองประเภทและ Conv2D สองประเภท ฉันค้นหาเว็บและนี่คือสิ่งที่ฉันเข้าใจเกี่ยวกับ Conv1D และ Conv2D; Conv1D ใช้สำหรับซีเควนซ์และ Conv2D ใช้สำหรับอิมเมจ

ฉันมักจะคิดว่าเครือข่ายที่ใช้ร่วมกันของ convolution นั้นใช้สำหรับรูปภาพและซีเอ็นเอ็นด้วยวิธีนี้เท่านั้น

ป้อนคำอธิบายรูปภาพที่นี่

ภาพนั้นถือเป็นเมทริกซ์ขนาดใหญ่จากนั้นฟิลเตอร์จะเลื่อนผ่านเมทริกซ์นี้และคำนวณผลคูณของจุด ฉันเชื่อว่าสิ่งที่ keras กล่าวถึงในฐานะ Conv2D ถ้า Conv2D ทำงานในลักษณะนี้แล้วกลไกของ Conv1D คืออะไรและเราจะจินตนาการกลไกของมันได้อย่างไร


2
ดูคำตอบนี้ หวังว่านี่จะช่วยได้
learner101

คำตอบ:


4

Convolution คือการดำเนินการทางคณิตศาสตร์ที่คุณ "สรุป" เมตริกซ์หรือเมทริกซ์หรือเวกเตอร์เป็นขนาดเล็ก หากอินพุตเมทริกซ์ของคุณเป็นหนึ่งมิติคุณจะต้องสรุปตามขนาดนั้นและถ้าเทนเซอร์มีขนาด n คุณก็สามารถสรุปตามมิติทั้งหมดได้ Conv1D และ Conv2D สรุป (convolve) ตามหนึ่งหรือสองมิติ

ตัวอย่างเช่นคุณสามารถโน้มน้าวใจเวกเตอร์เป็นเวกเตอร์ที่สั้นกว่าดังต่อไปนี้ รับเวกเตอร์ "ยาว" ที่มีองค์ประกอบ n และโน้มน้าวใจโดยใช้เวกเตอร์น้ำหนัก W ที่มีองค์ประกอบ m เป็นเวกเตอร์ "สั้น" (สรุป) B ที่มีองค์ประกอบ n-m + 1: โดยที่

bi=j=m10ai+jwj
i=[1,nm+1]

ดังนั้นถ้าคุณมีเวกเตอร์ของความยาว n และเมทริกซ์น้ำหนักของคุณคือความยาว nดังนั้นการบิดจะสร้างสเกลาร์หรือเวกเตอร์ความยาว 1 เท่ากับค่าเฉลี่ยของค่าทั้งหมดในเมทริกซ์อินพุท มันเป็นการโน้มน้าวใจที่แย่ลงถ้าคุณต้องการ ถ้าเมทริกซ์น้ำหนักตัวเดียวกันสั้นกว่าเมทริกซ์อินพุทคุณก็จะได้ค่าเฉลี่ยเคลื่อนที่ในเอาต์พุตของความยาว 2 เป็นต้นwi=1/n

[a:a1a2a3w:1/21/2w:1/21/2]=[b:a1+a22a2+a32]

คุณสามารถทำเช่นเดียวกันกับเมตริกซ์สามมิติ (เมทริกซ์) ในลักษณะเดียวกัน: โดยที่

bikl=j1=m11j2=m21j3=m410ai+j1,k+j2,l+j3wj1j2j3
i=[1,n1m1+1],k=[1,n2m2+1],l=[1,n3m3+1]


3

การบิดแบบ 1d นี้เป็นตัวประหยัดค่าใช้จ่ายมันทำงานในลักษณะเดียวกัน แต่สมมติอาร์เรย์ 1 มิติที่ทำให้การคูณกับองค์ประกอบ หากคุณต้องการเห็นภาพความคิดของเมทริกซ์ของทั้งแถวหรือคอลัมน์นั่นคือมิติเดียวเมื่อเราคูณเราจะได้อาร์เรย์ที่มีรูปร่างเดียวกัน แต่มีค่าต่ำกว่าหรือสูงกว่าดังนั้นมันจะช่วยในการเพิ่มหรือลดความเข้มของค่า

ภาพนี้อาจช่วยคุณได้ ป้อนคำอธิบายรูปภาพที่นี่

สำหรับรายละเอียดอ้างอิง https://www.youtube.com/watch?v=qVP574skyuM


1

ฉันจะใช้มุมมอง Pytorch อย่างไรก็ตามตรรกะยังคงเหมือนเดิม

เมื่อใช้ Conv1d () เราต้องจำไว้ว่าเรามักจะทำงานกับอินพุต 2 มิติเช่นลำดับดีเอ็นเอที่เข้ารหัสหนึ่งครั้งหรือรูปภาพขาวดำ

ความแตกต่างเพียงอย่างเดียวระหว่าง Conv2d () ทั่วไปและ Conv1d () ยิ่งกว่านั้นคือหลังใช้เคอร์เนล 1 มิติดังที่แสดงในภาพด้านล่าง

พบตัวอย่าง Conv1d () บน /programming/48859378/how-to-give-the-1d-input-to-convolutional-neural-networkcnn-using-keras/52508449

ในที่นี่ความสูงของข้อมูลอินพุตของคุณจะกลายเป็น“ ความลึก” (หรือ in_channels) และแถวของเรากลายเป็นขนาดเคอร์เนล ตัวอย่างเช่น,

import torch
import torch.nn as nn

tensor = torch.randn(1,100,4)
output = nn.Conv1d(in_channels =100,out_channels=1,kernel_size=1,stride=1)(tensor)
#output.shape == [1,1,4]

เราสามารถเห็นได้ว่าเคอร์เนลขยายโดยอัตโนมัติจนถึงความสูงของรูปภาพ (เช่นเดียวกับใน Conv2d () ความลึกของเคอร์เนลจะขยายแชนเนลของรูปภาพโดยอัตโนมัติ) และดังนั้นสิ่งที่เราเหลือไว้ให้คือขนาดเคอร์เนลที่เกี่ยวข้องกับช่วง แถว

เราต้องจำไว้ว่าถ้าเราสมมติว่าอินพุต 2 มิติตัวกรองของเรากลายเป็นคอลัมน์ของเราและแถวของเราจะกลายเป็นขนาดเคอร์เนล


รูปภาพถูกนำมาจากคำถามก่อนหน้านี้: stackoverflow.com/questions/48859378/…
Erick Platero

1

ฉันต้องการอธิบายความแตกต่างทางสายตาและรายละเอียด (ความคิดเห็นในโค้ด) และในวิธีที่ง่ายมาก

ขอตรวจสอบครั้งแรกConv2D ใน TensorFlow

ป้อนคำอธิบายรูปภาพที่นี่

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 เป็นกรณีพิเศษของ Conv2D ตามที่ระบุไว้ในวรรคนี้จากเอกสาร TensorFlow ของ Conv1D

ภายในตัวเลือกนี้จะปรับเปลี่ยนเทนเซอร์อินพุตและเรียกใช้ tf.nn.conv2d ตัวอย่างเช่นถ้า data_format ไม่ได้เริ่มต้นด้วย "NC" รูปร่างของเมตริกซ์ [batch, in_width, in_channels] จะถูกเปลี่ยนรูปร่างเป็น [batch, 1, in_width, in_channels] และตัวกรองถูกเปลี่ยนเป็น [1, filter_width, in_channels, out_channels] ผลลัพธ์จะถูกเปลี่ยนรูปร่างกลับเป็น [batch, out_width, out_channels] (โดยที่ out_width เป็นฟังก์ชั่นของ stride และ padding เช่นเดียวกับใน Conv2d) และส่งกลับไปยังผู้เรียก

มาดูกันว่าเราสามารถถ่ายโอน Conv1D ยังเป็นปัญหา Conv2D ได้อย่างไร เนื่องจากมักจะใช้ Conv1D ในสถานการณ์ NLP เราจึงสามารถแสดงให้เห็นได้ว่าในปัญหา NLP ด้านล่าง
ป้อนคำอธิบายรูปภาพที่นี่

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

เราจะเห็นได้ว่า 2D ใน Conv2D หมายถึงแต่ละช่องในอินพุตและตัวกรองเป็น 2 มิติ (ดังที่เราเห็นในตัวอย่าง gif) และ 1D ใน Conv1D หมายถึงแต่ละช่องในอินพุตและตัวกรองเป็น 1 มิติ (ดังที่เห็นในแมว และตัวอย่างสุนัข NLP)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.