บทบาทของ“ Flatten” ใน Keras คืออะไร?


109

ฉันพยายามที่จะเข้าใจบทบาทของFlattenฟังก์ชั่นใน Keras ด้านล่างนี้คือรหัสของฉันซึ่งเป็นเครือข่ายสองชั้นที่เรียบง่าย ใช้ข้อมูล 2 มิติของรูปร่าง (3, 2) และส่งออกข้อมูลรูปร่าง 1 มิติ (1, 4):

model = Sequential()
model.add(Dense(16, input_shape=(3, 2)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(4))
model.compile(loss='mean_squared_error', optimizer='SGD')

x = np.array([[[1, 2], [3, 4], [5, 6]]])

y = model.predict(x)

print y.shape

สิ่งนี้จะพิมพ์ออกมาที่yมีรูปร่าง (1, 4) อย่างไรก็ตามถ้าฉันลบFlattenเส้นมันก็จะพิมพ์ออกมาที่yมีรูปร่าง (1, 3, 4)

ฉันไม่เข้าใจเรื่องนี้ จากความเข้าใจของฉันเกี่ยวกับโครงข่ายประสาทเทียมmodel.add(Dense(16, input_shape=(3, 2)))ฟังก์ชันนี้กำลังสร้างเลเยอร์ที่เชื่อมต่อเต็มรูปแบบที่ซ่อนอยู่โดยมี 16 โหนด แต่ละโหนดเหล่านี้เชื่อมต่อกับแต่ละองค์ประกอบอินพุต 3x2 ดังนั้นโหนด 16 โหนดที่เอาต์พุตของเลเยอร์แรกนี้จึง "แบน" อยู่แล้ว ดังนั้นรูปร่างผลลัพธ์ของเลเยอร์แรกควรเป็น (1, 16) จากนั้นเลเยอร์ที่สองจะใช้สิ่งนี้เป็นอินพุตและเอาต์พุตข้อมูลของรูปร่าง (1, 4)

ดังนั้นหากผลลัพธ์ของเลเยอร์แรกเป็น "แบน" และมีรูปร่างอยู่แล้ว (1, 16) ทำไมฉันจึงต้องทำให้แบนลงอีก?

คำตอบ:


123

หากคุณอ่านรายการเอกสาร Keras สำหรับDenseคุณจะเห็นว่าสายนี้:

Dense(16, input_shape=(5,3))

จะส่งผลให้Denseเครือข่ายมี 3 อินพุตและ 16 เอาต์พุตซึ่งจะถูกนำไปใช้อย่างอิสระสำหรับแต่ละขั้นตอน 5 ขั้นตอน ดังนั้นถ้าD(x)แปลงเวกเตอร์ 3 มิติ 16-D เวกเตอร์สิ่งที่คุณจะได้รับเป็นผลผลิตจากชั้นของคุณจะเป็นลำดับของเวกเตอร์: ที่มีรูปร่าง[D(x[0,:]), D(x[1,:]),..., D(x[4,:])] (5, 16)เพื่อให้มีลักษณะการทำงานที่คุณระบุก่อนอื่นคุณอาจFlattenป้อนข้อมูลให้กับเวกเตอร์ 15 มิติจากนั้นจึงใช้Dense:

model = Sequential()
model.add(Flatten(input_shape=(3, 2)))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(4))
model.compile(loss='mean_squared_error', optimizer='SGD')

แก้ไข: เนื่องจากบางคนพยายามที่จะเข้าใจ - ที่นี่คุณมีภาพอธิบาย:

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


ขอบคุณสำหรับคำอธิบาย เพียงเพื่อชี้แจงว่า: ด้วยDense(16, input_shape=(5,3)เซลล์ประสาทเอาต์พุตแต่ละชุดจากชุด 16 (และสำหรับเซลล์ประสาททั้ง 5 ชุด) จะเชื่อมต่อกับเซลล์ประสาทอินพุตทั้งหมด (3 x 5 = 15) หรือไม่? หรือเซลล์ประสาทแต่ละชุดใน 16 ชุดแรกจะเชื่อมต่อกับเซลล์ประสาท 3 ชุดในชุดแรกของเซลล์ประสาทอินพุต 5 ชุดจากนั้นเซลล์ประสาทแต่ละเซลล์ในชุดที่สองของ 16 จะเชื่อมต่อกับเซลล์ประสาท 3 เซลล์ในชุดที่สองของ 5 อินพุตเท่านั้น เซลล์ประสาท ฯลฯ .... งงว่ามันคืออะไร!
Karnivaurus

1
คุณมีเลเยอร์หนาแน่นหนึ่งชั้นซึ่งได้รับ 3 เซลล์ประสาทและเอาต์พุต 16 ซึ่งใช้กับเซลล์ประสาท 3 ชุด 5 ชุด
Marcin Możejko

1
อาโอเค. สิ่งที่ฉันพยายามทำคือใช้รายการพิกเซล 5 สีเป็นอินพุตและฉันต้องการให้พวกมันผ่านเลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์ ดังนั้นinput_shape=(5,3)หมายความว่ามี 5 พิกเซลและแต่ละพิกเซลมีสามช่อง (R, G, B) แต่ตามที่คุณพูดแต่ละช่องจะถูกประมวลผลทีละช่องในขณะที่ฉันต้องการให้ทั้งสามช่องประมวลผลโดยเซลล์ประสาททั้งหมดในชั้นแรก ดังนั้นการใช้Flattenเลเยอร์ทันทีในตอนเริ่มต้นจะให้สิ่งที่ฉันต้องการหรือไม่?
Karnivaurus

8
การวาดภาพเล็ก ๆ น้อย ๆ ที่มีและไม่มีFlattenอาจช่วยให้เข้าใจได้
Xvolks

2
ตกลง Guys - ฉันให้ภาพคุณ ตอนนี้คุณสามารถลบ downvotes ของคุณได้
Marcin Możejko

52

ใส่คำอธิบายภาพที่นี่ นี่คือวิธีการทำงานของ Flatten ในการแปลงเมทริกซ์เป็นอาร์เรย์เดี่ยว


4
ผู้ชายคนนี้ต้องสร้างภาพมากขึ้น ฉันชอบสิ่งนี้. มันสมเหตุสมผล
alofgran

10
ใช่ แต่ทำไมถึงต้องการนี่คือคำถามที่แท้จริงที่ฉันคิด
เฮเลน

35

อ่านสั้น ๆ :

การแบนเทนเซอร์หมายถึงการลบมิติทั้งหมดยกเว้นมิติเดียว นี่คือสิ่งที่เลเยอร์ Flatten ทำ

อ่านยาว:

หากเราใช้โมเดลดั้งเดิม (ที่มีเลเยอร์ Flatten) ที่สร้างขึ้นในการพิจารณาเราจะได้รับสรุปโมเดลต่อไปนี้:

Layer (type)                 Output Shape              Param #   
=================================================================
D16 (Dense)                  (None, 3, 16)             48        
_________________________________________________________________
A (Activation)               (None, 3, 16)             0         
_________________________________________________________________
F (Flatten)                  (None, 48)                0         
_________________________________________________________________
D4 (Dense)                   (None, 4)                 196       
=================================================================
Total params: 244
Trainable params: 244
Non-trainable params: 0

สำหรับบทสรุปนี้ภาพถัดไปหวังว่าจะช่วยให้เข้าใจขนาดอินพุตและเอาต์พุตสำหรับแต่ละเลเยอร์ได้มากขึ้น

(None, 48)รูปร่างการส่งออกสำหรับชั้นแบนในขณะที่คุณสามารถอ่านได้ นี่คือเคล็ดลับ คุณควรอ่าน(1, 48)หรือ(2, 48)หรือ ... หรือ(16, 48)... หรือ(32, 48)...

ในความเป็นจริงNoneในตำแหน่งนั้นหมายถึงขนาดแบทช์ใด ๆ สำหรับอินพุตที่จะเรียกคืนมิติแรกหมายถึงขนาดแบทช์และที่สองหมายถึงจำนวนคุณสมบัติอินพุต

บทบาทของเลเยอร์ Flatten ใน Keras นั้นง่ายมาก:

การดำเนินการเรียบในเมตริกซ์ reshapes เมตริกซ์ที่จะมีรูปร่างที่เท่ากับจำนวนขององค์ประกอบที่มีอยู่ในเมตริกซ์ที่ไม่รวมถึงมิติชุด

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


หมายเหตุ: ฉันใช้model.summary()วิธีนี้เพื่อระบุรูปร่างผลลัพธ์และรายละเอียดพารามิเตอร์


1
แผนภาพที่ลึกซึ้งมาก
Shrey Joshi

1
ขอบคุณสำหรับแผนภาพ มันทำให้ฉันเห็นภาพที่ชัดเจน
Sultan Ahmed Sagor

0

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


0

ฉันเพิ่งเจอสิ่งนี้เมื่อไม่นานมานี้มันช่วยให้ฉันเข้าใจได้อย่างแน่นอน: https://www.cs.ryerson.ca/~aharley/vis/conv/

ดังนั้นจึงมีอินพุต Conv2D, MaxPooling2D และอื่น ๆ เลเยอร์ Flatten อยู่ที่ส่วนท้ายและแสดงให้เห็นอย่างชัดเจนว่าพวกมันถูกสร้างขึ้นอย่างไรและพวกเขาจะกำหนดประเภทสุดท้ายอย่างไร (0-9)

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