Tensorflow Strides Argument


115

ฉันพยายามเข้าใจอาร์กิวเมนต์stridesใน tf.nn.avg_pool, tf.nn.max_pool, tf.nn.conv2d

เอกสารซ้ำแล้วซ้ำอีกว่า

strides: รายการ ints ที่มีความยาว> = 4 ขั้นตอนของหน้าต่างบานเลื่อนสำหรับแต่ละมิติของอินพุตเทนเซอร์

คำถามของฉันคือ:

  1. จำนวนเต็ม 4+ แต่ละตัวแสดงถึงอะไร
  2. เหตุใดพวกเขาจึงต้องมีความก้าวหน้า [0] = ก้าว [3] = 1 สำหรับ Convnets
  3. ในตัวอย่างนี้tf.reshape(_X,shape=[-1, 28, 28, 1])เราจะเห็น ทำไม -1?

น่าเศร้าที่ตัวอย่างในเอกสารสำหรับการสร้างรูปร่างใหม่โดยใช้ -1 แปลได้ไม่ดีนักกับสถานการณ์นี้

คำตอบ:


224

การรวมกันและการดำเนินการ Convolutional เลื่อน "หน้าต่าง" ข้ามเทนเซอร์อินพุต ใช้tf.nn.conv2dเป็นตัวอย่าง: หากอินพุทเทนเซอร์มี 4 มิติ: คอน [batch, height, width, channels]โวลูชั่นจะทำงานบนหน้าต่าง 2 มิติบนheight, widthมิติข้อมูล

stridesกำหนดว่าหน้าต่างจะเลื่อนไปเท่าใดในแต่ละมิติ การใช้งานโดยทั่วไปจะตั้งค่าการก้าวแรก (ชุด) และครั้งสุดท้าย (ความลึก) เป็น 1

ลองใช้ตัวอย่างที่เป็นรูปธรรม: การรันคอนโวลูชั่น 2 มิติบนอิมเมจอินพุตสีเทาขนาด 32x32 ฉันพูดว่า greyscale เพราะภาพที่ป้อนมีความลึก = 1 ซึ่งช่วยให้มันดูเรียบง่าย ให้ภาพมีลักษณะดังนี้:

00 01 02 03 04 ...
10 11 12 13 14 ...
20 21 22 23 24 ...
30 31 32 33 34 ...
...

ลองเรียกใช้หน้าต่าง Convolution 2x2 ในตัวอย่างเดียว (batch size = 1) เราจะให้คอนโวลูชั่นมีความลึกของช่องสัญญาณเอาต์พุตที่ 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)

และอื่น ๆ จากนั้นจะย้ายไปที่แถวที่สองโดยคำนวณ:

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: ทำไมต้องก้าว [1, x, y, 1] สำหรับ Convnets

ชุดแรกคือชุด: โดยปกติคุณไม่ต้องการข้ามตัวอย่างในชุดงานของคุณหรือคุณไม่ควรรวมไว้ในตอนแรก :)

1 สุดท้ายคือความลึกของการแปลง: โดยปกติคุณไม่ต้องการข้ามอินพุตด้วยเหตุผลเดียวกัน

ตัวดำเนินการ Conv2d มีความกว้างมากขึ้นดังนั้นคุณสามารถสร้าง Convolutions ที่เลื่อนหน้าต่างไปตามมิติข้อมูลอื่น ๆ ได้ แต่นั่นไม่ใช่การใช้งานทั่วไปใน Convnets การใช้งานทั่วไปคือการใช้เชิงพื้นที่

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


5
@derek เพราะ (จากข้อความ) "เราจะให้ Convolution มีความลึกของช่องสัญญาณเอาต์พุตที่ 8" เป็นสิ่งที่คุณสามารถเลือกได้เมื่อตั้งค่าคอนโวลูชั่นและผู้ตอบเลือก 8
etarion

17

อินพุตเป็น 4 มิติและอยู่ในรูปแบบ: [batch_size, image_rows, image_cols, number_of_colors]

โดยทั่วไปขั้นตอนกำหนดความเหลื่อมระหว่างการใช้การดำเนินการ ในกรณีของ conv2d จะระบุระยะห่างระหว่างการใช้งานตัวกรอง Convolutional ที่ต่อเนื่องกัน ค่า 1 ในมิติข้อมูลเฉพาะหมายความว่าเราใช้โอเปอเรเตอร์ทุกแถว / คอลัมน์ค่า 2 หมายถึงทุกวินาทีและอื่น ๆ

Re 1)ค่าที่สำคัญสำหรับ Convolutions คืออันดับ 2 และ 3 และแสดงถึงการทับซ้อนกันในการประยุกต์ใช้ตัวกรองคอนโวลูชันตามแถวและคอลัมน์ ค่าของ [1, 2, 2, 1] บอกว่าเราต้องการใช้ตัวกรองกับทุกแถวและคอลัมน์ที่สอง

Re 2)ฉันไม่ทราบข้อ จำกัด ทางเทคนิค (อาจเป็นข้อกำหนดของ CuDNN) แต่โดยทั่วไปแล้วผู้คนจะใช้การก้าวไปตามมิติของแถวหรือคอลัมน์ ไม่จำเป็นต้องทำเกินขนาดแบทช์ ไม่แน่ใจว่ามิติสุดท้าย

Re 3)การตั้งค่า -1 สำหรับหนึ่งในมิติหมายถึง "กำหนดค่าสำหรับมิติแรกเพื่อให้จำนวนองค์ประกอบทั้งหมดในเทนเซอร์ไม่เปลี่ยนแปลง" ในกรณีของเรา -1 จะเท่ากับ batch_size


11

มาเริ่มกันที่การก้าวย่างในเคส 1 สลัว

สมมติว่าคุณinput = [1, 0, 2, 3, 0, 1, 1]และkernel = [2, 1, 3]ผลลัพธ์ของการ Convolution คือ[8, 11, 7, 9, 4]ซึ่งคำนวณโดยการเลื่อนเคอร์เนลของคุณไปที่อินพุตทำการคูณอย่างชาญฉลาดและสรุปทุกอย่าง เช่นนี้ :

  • 8 = 1 * 2 + 0 * 1 + 2 * 3
  • 11 = 0 * 2 + 2 * 1 + 3 * 3
  • 7 = 2 * 2 + 3 * 1 + 0 * 3
  • 9 = 3 * 2 + 0 * 1 + 1 * 3
  • 4 = 0 * 2 + 1 * 1 + 1 * 3

ที่นี่เราเลื่อนไปทีละองค์ประกอบ แต่ไม่มีอะไรหยุดคุณได้โดยใช้หมายเลขอื่น หมายเลขนี้คือก้าวย่างของคุณ คุณสามารถคิดว่ามันเป็นการลดการสุ่มตัวอย่างผลลัพธ์ของคอนโวลูชั่น 1 ขั้นโดยรับผลลัพธ์ s-th ทุกครั้ง

เมื่อทราบขนาดอินพุตi , ขนาดเคอร์เนลk , stride sและ padding pคุณสามารถคำนวณขนาดเอาต์พุตของคอนโวลูชั่นได้อย่างง่ายดายดังนี้:

ใส่คำอธิบายภาพที่นี่

ที่นี่ || ตัวดำเนินการหมายถึงการทำงานของเพดาน สำหรับการรวมเลเยอร์ s = 1


กรณี N-dim

การรู้คณิตศาสตร์สำหรับเคส 1 สลัวนั้นง่ายมากเมื่อคุณเห็นว่าแต่ละสลัวเป็นอิสระ ดังนั้นคุณเพียงแค่เลื่อนแต่ละมิติแยกกัน นี่คือตัวอย่างสำหรับ 2-D สังเกตว่าคุณไม่จำเป็นต้องก้าวย่างเหมือนกันในทุกมิติ ดังนั้นสำหรับอินพุต / เคอร์เนล N-dim คุณควรจัดเตรียม N strides


ดังนั้นตอนนี้จึงเป็นเรื่องง่ายที่จะตอบคำถามของคุณ:

  1. จำนวนเต็ม 4+ แต่ละตัวแสดงถึงอะไร . conv2d , สระว่ายน้ำจะบอกคุณว่ารายการนี้แสดงให้เห็นถึงความก้าวหน้าในหมู่แต่ละมิติ โปรดสังเกตว่าความยาวของรายการก้าวจะเหมือนกับอันดับของเคอร์เนลเทนเซอร์
  2. เหตุใดพวกเขาจึงต้องมีความก้าว [0] = ก้าว3 = 1 สำหรับ Convnets . มิติข้อมูลแรกคือขนาดแบทช์สุดท้ายคือแชแนล ไม่มีจุดที่จะข้ามทั้งแบทช์หรือแชนเนล คุณจึงทำให้เป็น 1 สำหรับความกว้าง / ความสูงคุณสามารถข้ามบางสิ่งได้และนั่นคือสาเหตุที่อาจไม่ใช่ 1
  3. tf.reshape (_X, รูปร่าง = [- 1, 28, 28, 1]) ทำไม -1? tf.reshapeครอบคลุมสำหรับคุณ:

    หากส่วนประกอบหนึ่งของรูปร่างเป็นค่าพิเศษ -1 ขนาดของมิตินั้นจะถูกคำนวณเพื่อให้ขนาดรวมคงที่ โดยเฉพาะรูปร่าง [-1] แผ่เป็น 1-D องค์ประกอบของรูปร่างส่วนใหญ่สามารถเป็น -1 ได้


2

@dga ทำงานได้อย่างยอดเยี่ยมในการอธิบายและฉันไม่สามารถขอบคุณมากพอที่จะเป็นประโยชน์ได้ ในทำนองเดียวกันฉันต้องการแบ่งปันสิ่งที่ค้นพบเกี่ยวกับวิธีการstrideทำงานในการแปลงภาพ 3 มิติ

ตามเอกสาร TensorFlowบน Conv3d รูปร่างของอินพุตต้องอยู่ในลำดับนี้:

[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.

ด้านล่างนี้เป็นเอกสารสรุปเกี่ยวกับวิธีการใช้ก้าวย่าง

ก้าว: รายการของ int ที่มีความยาว> = 5. 1-D เทนเซอร์ของความยาว 5. ก้าวของหน้าต่างบานเลื่อนสำหรับแต่ละมิติของอินพุต จำเป็นต้องมีstrides[0] = strides[4] = 1

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

จากเอกสารด้านบนการก้าวย่างใน 3 มิติจะมีลักษณะดังนี้ก้าว = (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 หมายถึงใช้ทุกเฟรมที่สองและดำเนินไปเรื่อย ๆ

ก้าว [y] และก้าว [z] ทำตามคำอธิบายของ@dgaดังนั้นฉันจะไม่ทำซ้ำส่วนนั้น

อย่างไรก็ตามใน keras คุณจะต้องระบุทูเพิล / รายการของจำนวนเต็ม 3 จำนวนเท่านั้นโดยระบุความคืบหน้าของการแปลงตามมิติเชิงพื้นที่แต่ละมิติโดยที่มิติเชิงพื้นที่คือการก้าว [x] ก้าว [y] และสไตรด์ [z] strides [0] และ strides [4] มีค่าเริ่มต้นเป็น 1 อยู่แล้ว

ฉันหวังว่าใครบางคนจะพบว่าสิ่งนี้เป็นประโยชน์!

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