บทช่วยสอนการเรียนรู้เชิงลึก: จาก Perceptrons ไปจนถึง Deep Networks
เผยแพร่แล้ว: 2022-03-11ในช่วงไม่กี่ปีที่ผ่านมา มีการฟื้นคืนชีพในด้านปัญญาประดิษฐ์ มันแพร่กระจายไปไกลกว่าโลกวิชาการด้วยผู้เล่นหลักเช่น Google, Microsoft และ Facebook ที่สร้างทีมวิจัยของตนเองและเข้าซื้อกิจการที่น่าประทับใจ
บางส่วนอาจเป็นผลมาจากข้อมูลดิบจำนวนมากที่สร้างขึ้นโดยผู้ใช้เครือข่ายสังคมออนไลน์ ซึ่งส่วนใหญ่จำเป็นต้องได้รับการวิเคราะห์ การเพิ่มขึ้นของโซลูชันวิทยาศาสตร์ข้อมูลขั้นสูง ตลอดจนความสามารถในการคำนวณราคาถูกที่มีผ่าน GPGPU
แต่นอกเหนือจากปรากฏการณ์เหล่านี้ การฟื้นคืนชีพนี้ได้รับแรงผลักดันจากกระแสใหม่ใน AI โดยเฉพาะในการเรียนรู้ของเครื่องที่เรียกว่า "การเรียนรู้เชิงลึก" ในบทช่วยสอนนี้ ฉันจะแนะนำคุณเกี่ยวกับแนวคิดหลักและอัลกอริทึมที่อยู่เบื้องหลังการเรียนรู้เชิงลึก โดยเริ่มจากหน่วยองค์ประกอบที่ง่ายที่สุดและการสร้างไปจนถึงแนวคิดของการเรียนรู้ด้วยเครื่องใน Java
(สำหรับการเปิดเผยแบบเต็ม: ฉันยังเป็นผู้เขียน Java deep learning library ซึ่งมีให้ที่นี่ และตัวอย่างในบทความนี้ถูกนำไปใช้โดยใช้ไลบรารีด้านบน ถ้าคุณชอบ คุณสามารถสนับสนุนมันได้โดยให้ดาวมันบน GitHub ซึ่งฉันจะขอบคุณมาก คำแนะนำในการใช้งาน มีอยู่ในหน้าแรก)
บทช่วยสอนสามสิบวินาทีเกี่ยวกับการเรียนรู้ของเครื่อง
ในกรณีที่คุณไม่คุ้นเคย โปรดดูข้อมูลเบื้องต้นเกี่ยวกับการเรียนรู้ของเครื่อง:
ขั้นตอนทั่วไปมีดังนี้:
- เรามีอัลกอริธึมที่ให้ตัวอย่างป้ายกำกับจำนวนหนึ่ง เช่น ภาพสุนัข 10 ภาพที่มีป้ายกำกับ 1 (“สุนัข”) และรูปภาพอื่นๆ ที่มีป้ายกำกับ 0 (“ไม่ใช่สุนัข”) 10 ภาพ—โปรดทราบว่า เรายึดติดกันเป็นหลัก การจำแนกประเภทไบนารีภายใต้การดูแลสำหรับโพสต์นี้
- อัลกอริธึม "เรียนรู้" เพื่อระบุรูปภาพของสุนัข และเมื่อป้อนรูปภาพใหม่ หวังว่าจะสร้างป้ายกำกับที่ถูกต้อง (1 หากเป็นรูปภาพของสุนัข และ 0 หากไม่ใช่)
การตั้งค่านี้เป็นเรื่องทั่วไปอย่างไม่น่าเชื่อ: ข้อมูลของคุณอาจเป็นอาการและการเจ็บป่วยที่ติดฉลาก หรือข้อมูลของคุณอาจเป็นภาพของอักขระที่เขียนด้วยลายมือและป้ายกำกับของคุณตามอักขระจริงที่แสดง
Perceptrons: อัลกอริธึมการเรียนรู้เชิงลึกในช่วงต้น
หนึ่งในอัลกอริธึมการฝึกอบรมที่มีการควบคุมดูแลที่เก่าแก่ที่สุดคือของ perceptron ซึ่งเป็นชุดสร้างโครงข่ายประสาทเทียมขั้นพื้นฐาน
สมมติว่าเรามี n คะแนนบนเครื่องบิน ที่มีป้ายกำกับ '0' และ '1' เราได้รับจุดใหม่และเราต้องการคาดเดาป้ายกำกับ (ซึ่งคล้ายกับสถานการณ์ "สุนัข" และ "ไม่ใช่สุนัข" ด้านบน) เราจะทำอย่างไร?
วิธีหนึ่งอาจเป็นการดูเพื่อนบ้านที่ใกล้ที่สุดและส่งคืนป้ายของจุดนั้น แต่วิธีที่ชาญฉลาดกว่าเล็กน้อยในการดำเนินการคือการเลือกบรรทัดที่แยกข้อมูลที่ติดป้ายกำกับออกได้ดีที่สุดและใช้สิ่งนั้นเป็นตัวแยกประเภทของคุณ
ในกรณีนี้ ข้อมูลอินพุตแต่ละส่วนจะแสดงเป็นเวกเตอร์ x = ( x_1, x_2 ) และฟังก์ชันของเราจะเป็น "'0' หากอยู่ใต้เส้น '1' หากอยู่เหนือ"
ในการแสดงทางคณิตศาสตร์นี้ ให้กำหนดตัวคั่นด้วยเวกเตอร์ของน้ำหนัก w และออฟเซ็ตแนวตั้ง (หรืออคติ) b จากนั้น ฟังก์ชันของเราจะรวมอินพุตและน้ำหนักเข้ากับฟังก์ชันการถ่ายโอนผลรวมแบบถ่วงน้ำหนัก:
ผลลัพธ์ของฟังก์ชันการถ่ายโอนนี้จะถูกป้อนเข้าสู่ฟังก์ชันการเปิดใช้งานเพื่อสร้างการติดฉลาก ในตัวอย่างข้างต้น ฟังก์ชันการเปิดใช้งานของเราคือจุดตัดของเกณฑ์ (เช่น 1 ถ้ามากกว่าค่าบางค่า):
การฝึกอบรม Perceptron
การฝึกอบรมของ perceptron ประกอบด้วยการป้อนตัวอย่างการฝึกอบรมหลายตัวอย่างและการคำนวณผลลัพธ์สำหรับแต่ละตัวอย่าง หลังจากแต่ละตัวอย่าง น้ำหนัก w จะถูกปรับในลักษณะเพื่อลด ข้อผิดพลาด ในการส่งออก ซึ่งกำหนดเป็นความแตกต่างระหว่าง ผลลัพธ์ที่ต้องการ (เป้าหมาย) และผลลัพธ์ จริง มีฟังก์ชันข้อผิดพลาดอื่นๆ เช่น ความคลาดเคลื่อนกำลังสองเฉลี่ย แต่หลักการพื้นฐานของการฝึกยังคงเหมือนเดิม
ข้อเสียของ Perceptron เดียว
แนวทางเดียวในการเรียนรู้เชิงลึกของ Perceptron มีข้อเสียอย่างหนึ่งคือ สามารถเรียนรู้ได้เฉพาะฟังก์ชันที่แยกเชิงเส้นออกได้เท่านั้น ข้อเสียเปรียบนี้สำคัญแค่ไหน? ใช้ XOR ซึ่งเป็นฟังก์ชันที่ค่อนข้างง่าย และสังเกตว่าตัวคั่นเชิงเส้นไม่สามารถจำแนกได้ (สังเกตความพยายามที่ล้มเหลวด้านล่าง):
เพื่อแก้ไขปัญหานี้ เราจำเป็นต้องใช้ perceptron แบบหลายชั้น หรือที่เรียกว่า feedforward neural network โดยที่จริงแล้ว เราจะรวบรวมกลุ่มของ perceptron เหล่านี้เข้าด้วยกันเพื่อสร้างกลไกการเรียนรู้ที่ทรงพลังยิ่งขึ้น
โครงข่ายประสาทฟีดฟอร์เวิร์ดสำหรับการเรียนรู้เชิงลึก
โครงข่ายประสาทเทียมเป็นเพียงองค์ประกอบหนึ่งของเพอร์เซปตรอน เชื่อมต่อด้วยวิธีต่างๆ และทำงานบนฟังก์ชันการเปิดใช้งานต่างๆ
สำหรับการเริ่มต้น เราจะดูที่โครงข่ายประสาทฟีดฟอร์เวิร์ด ซึ่งมีคุณสมบัติดังต่อไปนี้:
- อินพุต เอาต์พุต และเลเยอร์ ที่ซ่อนอยู่ อย่างน้อยหนึ่งเลเยอร์ รูปด้านบนแสดงเครือข่ายที่มีเลเยอร์อินพุต 3 ยูนิต เลเยอร์ที่ซ่อนอยู่ 4 ยูนิต และเลเยอร์เอาต์พุตที่มี 2 ยูนิต (เงื่อนไขยูนิตและเซลล์ประสาทใช้แทนกันได้)
- แต่ละหน่วยเป็น perceptron เดียวเหมือนที่อธิบายไว้ข้างต้น
- หน่วยของเลเยอร์อินพุตทำหน้าที่เป็นอินพุตสำหรับหน่วยของเลเยอร์ที่ซ่อนอยู่ ในขณะที่หน่วยของเลเยอร์ที่ซ่อนอยู่นั้นเป็นอินพุตของเลเยอร์เอาต์พุต
- แต่ละการเชื่อมต่อระหว่างสองเซลล์ประสาทมีน้ำหนัก w (คล้ายกับน้ำหนักของเพอร์เซปตรอน)
- โดยทั่วไปแล้วแต่ละหน่วยของเลเยอร์ t จะเชื่อมต่อกับ ทุก ยูนิตของเลเยอร์ t - 1 ก่อนหน้า (แม้ว่าคุณจะยกเลิกการเชื่อมต่อโดยกำหนดน้ำหนักเป็น 0) ก็ตาม
- ในการประมวลผลข้อมูลที่ป้อนเข้า คุณ "ยึด" เวกเตอร์อินพุตกับเลเยอร์อินพุต ตั้งค่าของเวกเตอร์เป็น "เอาต์พุต" สำหรับแต่ละหน่วยอินพุต ในกรณีนี้ เครือข่ายสามารถประมวลผลเวกเตอร์อินพุต 3 มิติได้ (เพราะ 3 หน่วยอินพุต) ตัวอย่างเช่น หากเวกเตอร์อินพุตของคุณคือ [7, 1, 2] คุณจะต้องตั้งค่าเอาต์พุตของยูนิตอินพุตบนสุดเป็น 7, หน่วยกลางเป็น 1, เป็นต้น ค่าเหล่านี้จะถูกส่งต่อไปยังหน่วยที่ซ่อนอยู่โดยใช้ฟังก์ชันการถ่ายโอนผลรวมถ่วงน้ำหนักสำหรับแต่ละหน่วยที่ซ่อนอยู่ (ด้วยเหตุนี้ คำว่าการส่งต่อ) ซึ่งจะคำนวณผลลัพธ์ (ฟังก์ชันการเปิดใช้งาน)
- เลเยอร์เอาต์พุตจะคำนวณผลลัพธ์ในลักษณะเดียวกับเลเยอร์ที่ซ่อนอยู่ ผลลัพธ์ของเลเยอร์เอาต์พุตคือเอาต์พุตของเครือข่าย
นอกเหนือจากความเป็นลิเนียร์
จะเกิดอะไรขึ้นถ้า perceptrons ของเราแต่ละคนได้รับอนุญาตให้ใช้ฟังก์ชันการเปิดใช้งานเชิงเส้นเท่านั้น? จากนั้น เอาต์พุตสุดท้ายของเครือข่ายของเราจะ ยังคง เป็นฟังก์ชันเชิงเส้นของอินพุต เพียงปรับด้วยน้ำหนักต่างๆ มากมายที่รวบรวมไว้ทั่วทั้งเครือข่าย กล่าวอีกนัยหนึ่ง องค์ประกอบเชิงเส้นของฟังก์ชันเชิงเส้นจำนวนมากยังเป็นเพียงฟังก์ชันเชิงเส้น หากเราจำกัดฟังก์ชันการเปิดใช้งานแบบเชิงเส้น โครงข่ายประสาทเทียมแบบ feedforward ก็ไม่ได้มีประสิทธิภาพมากไปกว่า Perceptron ไม่ว่าจะมีเลเยอร์กี่ชั้นก็ตาม
ด้วยเหตุนี้ โครงข่ายประสาทเทียมส่วนใหญ่จึงใช้ฟังก์ชันการเปิดใช้งานที่ไม่ใช่เชิงเส้น เช่น ลอจิสติก แทนห์ ไบนารี หรือวงจรเรียงกระแส หากไม่มีพวกเขา เครือข่ายสามารถเรียนรู้ฟังก์ชันที่เป็นการรวมเชิงเส้นของอินพุตเท่านั้น
การฝึกอบรม Perceptrons
อัลกอริธึมการเรียนรู้เชิงลึกที่ใช้บ่อยที่สุดสำหรับการฝึก Perceptron แบบหลายชั้นภายใต้การดูแลนั้นเรียกว่า backpropagation ขั้นตอนพื้นฐาน:
- ตัวอย่างการฝึกอบรมจะถูกนำเสนอและเผยแพร่ไปข้างหน้าผ่านเครือข่าย
มีการคำนวณข้อผิดพลาดเอาต์พุต โดยทั่วไปแล้วจะเป็นข้อผิดพลาดกำลังสองเฉลี่ย:
โดยที่ t คือค่าเป้าหมายและ y คือเอาต์พุตเครือข่ายจริง การคำนวณข้อผิดพลาดอื่นๆ ก็ยอมรับได้เช่นกัน แต่ MSE เป็นตัวเลือกที่ดี
ข้อผิดพลาดของเครือข่ายถูกย่อให้เล็กสุดโดยใช้วิธีการที่เรียกว่า stochastic gradient descent
การไล่ระดับสีแบบลาดนั้นเป็นสากล แต่ในกรณีของโครงข่ายประสาทเทียม นี่จะเป็นกราฟของข้อผิดพลาดในการฝึกเป็นฟังก์ชันของพารามิเตอร์อินพุต ค่าที่เหมาะสมที่สุดสำหรับแต่ละน้ำหนักคือค่าที่ข้อผิดพลาดบรรลุ ค่าต่ำสุดทั่วโลก ในระหว่างขั้นตอนการฝึก น้ำหนักจะได้รับการอัปเดตเป็นขั้นตอนเล็กๆ (หลังจากตัวอย่างการฝึกแต่ละครั้งหรือชุดย่อยของตัวอย่างหลายชุด) ในลักษณะที่พวกเขามักจะพยายามไปให้ถึงระดับต่ำสุดทั่วโลก—แต่นี่ไม่ใช่งานง่ายอย่างคุณ มักจะลงเอยด้วย minima ท้องถิ่นเช่นที่อยู่ทางขวา ตัวอย่างเช่น หากน้ำหนักมีค่าเป็น 0.6 จะต้องเปลี่ยนเป็น 0.4
ตัวเลขนี้แสดงถึงกรณีที่ง่ายที่สุด ซึ่งข้อผิดพลาดนั้นขึ้นอยู่กับพารามิเตอร์ตัวเดียว อย่างไรก็ตาม ข้อผิดพลาดของเครือข่ายขึ้นอยู่กับน้ำหนักของเครือข่าย ทั้งหมด และฟังก์ชันข้อผิดพลาดนั้นซับซ้อนกว่ามาก
โชคดีที่ backpropagation มีวิธีการปรับปรุงน้ำหนักแต่ละเซลล์ระหว่างเซลล์ประสาทสองเซลล์โดยคำนึงถึงข้อผิดพลาดในการส่งออก ที่มาเองนั้นค่อนข้างซับซ้อน แต่การอัพเดตน้ำหนักสำหรับโหนดที่กำหนดมีรูปแบบ (ง่าย) ดังต่อไปนี้:
โดยที่ E คือข้อผิดพลาดของเอาต์พุต และ w_i คือน้ำหนักของอินพุต i ต่อเซลล์ประสาท
โดยพื้นฐานแล้ว เป้าหมายคือการเคลื่อนที่ไปในทิศทางของการไล่ระดับสีโดยเทียบกับน้ำหนัก ผม คำสำคัญคือ อนุพันธ์ของข้อผิดพลาด ซึ่งคำนวณได้ไม่ง่ายเสมอไป คุณจะหาอนุพันธ์นี้สำหรับน้ำหนักสุ่มของโหนดที่ซ่อนอยู่แบบสุ่มในเครือข่ายขนาดใหญ่ได้อย่างไร
คำตอบ: ผ่านการขยายพันธุ์ด้านหลัง ข้อผิดพลาดจะถูกคำนวณครั้งแรกที่หน่วยผลลัพธ์ซึ่งสูตรค่อนข้างง่าย (ขึ้นอยู่กับความแตกต่างระหว่างเป้าหมายและค่าที่คาดการณ์ไว้) จากนั้นจึงแพร่กระจายกลับผ่านเครือข่ายอย่างชาญฉลาด ทำให้เราอัปเดตน้ำหนักของเราได้อย่างมีประสิทธิภาพระหว่างการฝึกและ (หวังว่า) ถึงขั้นต่ำ
เลเยอร์ที่ซ่อนอยู่
เลเยอร์ที่ซ่อนอยู่นั้นน่าสนใจเป็นพิเศษ ตามทฤษฎีบทการประมาณสากล เครือข่ายชั้นเดียวที่ซ่อนอยู่ซึ่งมีเซลล์ประสาทจำนวนจำกัดสามารถฝึกให้ประมาณฟังก์ชันสุ่มตามอำเภอใจได้ กล่าวอีกนัยหนึ่ง เลเยอร์ที่ซ่อนอยู่เพียงเลเยอร์เดียวนั้นทรงพลังพอที่จะเรียนรู้ฟังก์ชัน ใดๆ ก็ได้ ที่กล่าวว่า เรามักจะเรียนรู้ได้ดีขึ้นในทางปฏิบัติด้วยเลเยอร์ที่ซ่อนอยู่หลายชั้น (เช่น ตาข่ายที่ลึกกว่า)
เลเยอร์ที่ซ่อนอยู่เป็นที่ที่เครือข่ายจัดเก็บไว้เป็นนามธรรมภายในของข้อมูลการฝึกอบรม คล้ายกับวิธีที่สมองของมนุษย์ (การเปรียบเทียบแบบง่ายอย่างมาก) มีการแสดงภายในของโลกแห่งความเป็นจริง ต่อจากนี้ไปในบทช่วยสอน เราจะมาดูวิธีต่างๆ ในการเล่นกับเลเยอร์ที่ซ่อนอยู่
เครือข่ายตัวอย่าง
คุณสามารถดูเครือข่ายนิวรัล feedforward แบบง่าย (4-2-3 เลเยอร์) ที่จัดประเภทชุดข้อมูล IRIS ที่ใช้งานใน Java ที่นี่ผ่านวิธี testMLPSigmoidBP ชุดข้อมูลประกอบด้วยพืชไอริสสามประเภทที่มีคุณสมบัติต่างๆ เช่น ความยาวของกลีบเลี้ยง ความยาวของกลีบดอก เป็นต้น เครือข่ายมีตัวอย่าง 50 ตัวอย่างต่อคลาส คุณลักษณะจะถูกยึดเข้ากับหน่วยอินพุต ในขณะที่หน่วยเอาต์พุตแต่ละหน่วยสอดคล้องกับคลาสเดียวของชุดข้อมูล: “1/0/0” บ่งชี้ว่าโรงงานอยู่ในกลุ่ม Setosa “0/1/0” หมายถึง Versicolour และ “ 0/0/1” หมายถึง Virginica) ข้อผิดพลาดในการจัดประเภทคือ 2/150 (กล่าวคือ จำแนกตัวอย่างผิด 2 ตัวอย่างจาก 150)
ปัญหาเกี่ยวกับเครือข่ายขนาดใหญ่
โครงข่ายประสาทเทียมสามารถมีเลเยอร์ที่ซ่อนอยู่ได้มากกว่าหนึ่งชั้น: ในกรณีนี้ เลเยอร์ที่สูงกว่ากำลัง "สร้าง" นามธรรมใหม่ที่ด้านบนของเลเยอร์ก่อนหน้า และดังที่เราได้กล่าวไว้ก่อนหน้านี้ คุณสามารถเรียนรู้การปฏิบัติจริงได้ดีขึ้นด้วยเครือข่ายที่ใหญ่ขึ้น
อย่างไรก็ตาม การเพิ่มจำนวนเลเยอร์ที่ซ่อนอยู่ทำให้เกิดปัญหาที่ทราบสองประการ:
- การไล่ระดับสีที่หายไป: เมื่อเราเพิ่มเลเยอร์ที่ซ่อนอยู่มากขึ้นเรื่อยๆ การขยายพันธุ์ย้อนหลังจะมีประโยชน์น้อยลงในการส่งข้อมูลไปยังชั้นล่าง ผลก็คือ เมื่อมีการส่งข้อมูลกลับ การไล่ระดับสีเริ่มหายไปและมีขนาดเล็กเมื่อเทียบกับน้ำหนักของเครือข่าย
- Overfitting: อาจเป็นปัญหาหลักในการเรียนรู้ของเครื่อง โดยสังเขป การใส่มากเกินไปจะอธิบายปรากฏการณ์ของการปรับข้อมูลการฝึกให้เหมาะสม เกินไป อาจเป็นเพราะสมมติฐานที่ซับซ้อน เกินไป ในกรณีเช่นนี้ ผู้เรียนของคุณจะปรับข้อมูลการฝึกอบรมได้อย่างเหมาะสม แต่จะมีประสิทธิภาพแย่กว่าในตัวอย่างจริงมาก
มาดูอัลกอริธึมการเรียนรู้เชิงลึกเพื่อแก้ไขปัญหาเหล่านี้กัน
ตัวเข้ารหัสอัตโนมัติ
คลาสแมชชีนเลิร์นนิงเบื้องต้นส่วนใหญ่มักจะหยุดด้วยโครงข่ายประสาทเทียมแบบฟีดฟอร์เวิร์ด แต่พื้นที่ของตาข่ายที่เป็นไปได้นั้นสมบูรณ์กว่ามาก ดังนั้นไปต่อ
ตัวเข้ารหัสอัตโนมัติมักจะเป็นโครงข่ายประสาทเทียมแบบ feedforward ซึ่งมีจุดมุ่งหมายเพื่อ เรียนรู้การแทนค่าแบบกระจายและกระจาย (การเข้ารหัส) ของชุดข้อมูล
ตามแนวคิดแล้ว เครือข่ายได้รับการฝึกฝนให้ "สร้าง" ข้อมูลเข้าใหม่ กล่าวคือ ข้อมูลเข้าและข้อมูลเป้าหมายจะเหมือนกัน กล่าวอีกนัยหนึ่ง: คุณกำลังพยายามส่งออกสิ่งเดียวกันกับที่คุณป้อน แต่ถูกบีบอัดในทางใดทางหนึ่ง นี่เป็นแนวทางที่ทำให้สับสน ลองมาดูตัวอย่างกัน
การบีบอัดข้อมูลเข้า: ภาพระดับสีเทา
สมมติว่าข้อมูลการฝึกประกอบด้วยภาพระดับสีเทาขนาด 28x28 และค่าของแต่ละพิกเซลถูกยึดเข้ากับเซลล์ประสาทชั้นอินพุตหนึ่งเซลล์ (กล่าวคือ ชั้นอินพุตจะมี 784 เซลล์ประสาท) จากนั้น เลเยอร์เอาต์พุตจะมีจำนวนยูนิตเท่ากัน (784) เป็นเลเยอร์อินพุต และค่าเป้าหมายสำหรับแต่ละยูนิตเอาต์พุตจะเป็นค่าระดับสีเทาของหนึ่งพิกเซลของรูปภาพ
สัญชาตญาณเบื้องหลังสถาปัตยกรรมนี้คือเครือข่ายจะไม่เรียนรู้ "การแมป" ระหว่างข้อมูลการฝึกอบรมและป้ายกำกับ แต่จะเรียนรู้ โครงสร้างภายใน และคุณลักษณะของข้อมูลเอง (ด้วยเหตุนี้ เลเยอร์ที่ซ่อนอยู่จึงเรียกอีกอย่างว่าตัว ตรวจจับคุณสมบัติ ) โดยปกติจำนวนของหน่วยที่ซ่อนอยู่จะน้อยกว่าเลเยอร์อินพุต/เอาท์พุต ซึ่งบังคับให้เครือข่ายเรียนรู้เฉพาะคุณสมบัติที่สำคัญที่สุดเท่านั้น และทำให้ได้มิติที่ลดลง
ผลที่ตามมาคือ เราต้องการโหนดเล็กๆ สองสามตัวที่อยู่ตรงกลางเพื่อเรียนรู้ข้อมูลในระดับแนวความคิดอย่างแท้จริง ทำให้เกิดการแสดงข้อมูลแบบกะทัดรัดที่ดึงเอาคุณสมบัติหลักของข้อมูลที่เราได้รับมาในบางวิธี
โรคไข้หวัดใหญ่
ในการสาธิต autoencoders เพิ่มเติม มาดูอีกหนึ่งแอปพลิเคชัน
ในกรณีนี้ เราจะใช้ชุดข้อมูลง่ายๆ ที่ประกอบด้วยอาการไข้หวัดใหญ่ (ให้เครดิตสำหรับแนวคิดนี้ในบล็อกโพสต์) หากคุณสนใจ สามารถดูโค้ดสำหรับตัวอย่างนี้ได้ในเมธอด testAEBackpropagation
ชุดข้อมูลแบ่งออกเป็นดังนี้:
- มีหกคุณสมบัติอินพุตไบนารี
- สามอันดับแรกคืออาการของโรค ตัวอย่างเช่น 1 0 0 0 0 0 แสดงว่าผู้ป่วยรายนี้มีอุณหภูมิสูง ในขณะที่ 0 1 0 0 0 0 บ่งชี้ว่าไอ 1 1 0 0 0 0 บ่งชี้ว่าไอ และ อุณหภูมิสูง เป็นต้น
- คุณสมบัติสามประการสุดท้ายคืออาการ "ตอบโต้"; เมื่อผู้ป่วยมีอาการเหล่านี้ ก็มีโอกาสน้อยที่เขาจะป่วย เช่น 0 0 0 1 0 0 แสดงว่าผู้ป่วยรายนี้มีวัคซีนป้องกันไข้หวัดใหญ่ เป็นไปได้ที่จะมีคุณลักษณะทั้งสองชุดรวมกัน: 0 1 0 1 0 0 หมายถึงวัคซีนที่ผู้ป่วยมีอาการไอ เป็นต้น
เราจะถือว่าผู้ป่วยป่วยเมื่อเขาหรือเธอมีคุณสมบัติ อย่างน้อยสอง ในสามประการแรกและมีสุขภาพดีหากเขาหรือเธอมีอย่างน้อยสองในสามส่วนที่สอง (โดยความสัมพันธ์ที่พังลงเพื่อประโยชน์ของผู้ป่วยที่มีสุขภาพดี) เช่น:
- 111000, 101000, 110000, 011000, 011100 = ป่วย
- 000111, 001110, 000101, 000011, 000110 = สุขภาพดี
เราจะฝึกตัวเข้ารหัสอัตโนมัติ (โดยใช้ backpropagation) ที่มีหน่วยอินพุต 6 หน่วยและหน่วยเอาต์พุต 6 หน่วย แต่ มีหน่วยที่ซ่อนอยู่เพียง 2 หน่วย เท่านั้น
หลังจากการทำซ้ำหลายร้อยครั้ง เราสังเกตว่าเมื่อตัวอย่าง "ป่วย" แต่ละรายการถูกนำเสนอต่อเครือข่ายการเรียนรู้ของเครื่อง หนึ่งในสองหน่วยที่ซ่อนไว้ (หน่วยเดียวกันสำหรับตัวอย่าง "ป่วย" แต่ละรายการ) จะแสดงค่าการเปิดใช้งานที่สูงกว่า อื่น ๆ. ในทางตรงกันข้าม เมื่อมีการนำเสนอตัวอย่างที่ "แข็งแรง" ยูนิตที่ซ่อนอยู่อีกหน่วยจะมีการเปิดใช้งานที่สูงกว่า
กลับไปที่การเรียนรู้ของเครื่อง
โดยพื้นฐานแล้ว หน่วยที่ซ่อนทั้งสองของเราได้ เรียนรู้ การแสดงชุดข้อมูลอาการไข้หวัดใหญ่อย่างคร่าวๆ เพื่อดูว่าสิ่งนี้เกี่ยวข้องกับการเรียนรู้อย่างไร เรากลับมาที่ปัญหาการใส่มากเกินไป การฝึกอบรมเน็ตของเราให้เรียนรู้การแสดงข้อมูลแบบย่อ ทำให้เรานิยมการนำเสนอที่ง่ายกว่า มากกว่าที่จะเป็นสมมติฐานที่ซับซ้อนมากซึ่งเกินข้อมูลการฝึกอบรม
ในทางหนึ่ง เรากำลังพยายามเรียนรู้ข้อมูลในความหมายที่แท้จริง
เครื่องจำกัด Boltzmann
ขั้นตอนต่อไปคือการดูที่เครื่อง Restricted Boltzmann (RBM) ซึ่งเป็น โครงข่ายนิวรัลสุ่มแบบกำเนิดที่สามารถเรียนรู้การแจกแจงความน่าจะเป็นเหนือชุดของอินพุต

RBM ประกอบด้วยเลเยอร์ที่ซ่อนอยู่ มองเห็นได้ และมีอคติ ต่างจากเครือข่าย feedforward การเชื่อมต่อระหว่างเลเยอร์ที่มองเห็นได้และเลเยอร์ที่ซ่อนอยู่นั้นไม่มีทิศทาง (ค่าสามารถแพร่กระจายได้ทั้งในทิศทางที่มองเห็นไปยังซ่อนและซ่อนเพื่อให้มองเห็นได้) และเชื่อมต่ออย่างสมบูรณ์ (แต่ละหน่วยจากเลเยอร์ที่กำหนดเชื่อมต่อกับ แต่ละยูนิตในตอนถัดไป—หากเราอนุญาตให้ยูนิตใดๆ ในเลเยอร์ใดๆ เชื่อมต่อกับเลเยอร์อื่น เราก็จะมีเครื่อง Boltzmann (แทนที่จะเป็น Boltzmann ที่จำกัด )
RBM มาตรฐานมีหน่วยไบนารีที่ซ่อนอยู่และมองเห็นได้ นั่นคือ การเปิดใช้งานหน่วยเป็น 0 หรือ 1 ภายใต้การแจกแจงแบบเบอร์นูลลี แต่มีตัวแปรที่ไม่เป็นเชิงเส้นอื่นๆ
ในขณะที่นักวิจัยรู้จัก RBM มาระยะหนึ่งแล้ว การแนะนำอัลกอริธึมการฝึกอบรมที่ไม่ได้รับการดูแลแบบ contrastive divergence เมื่อเร็ว ๆ นี้ได้รับความสนใจอีกครั้ง
ความแตกต่างที่ตรงกันข้าม
อัลกอริทึมคอนทราสต์ไดเวอร์เจนซ์ขั้นตอนเดียว (CD-1) ทำงานดังนี้:
- ระยะบวก :
- ตัวอย่างอินพุต v ถูกยึดเข้ากับเลเยอร์อินพุต
- v ถูกเผยแพร่ไปยังเลเยอร์ที่ซ่อนอยู่ในลักษณะเดียวกันกับเครือข่าย feedforward ผลลัพธ์ของการเปิดใช้งานเลเยอร์ที่ซ่อนอยู่คือ h
- เฟสเชิงลบ :
- เผยแพร่ h กลับไปยังเลเยอร์ที่มองเห็นได้ด้วยผลลัพธ์ v ' (การเชื่อมต่อระหว่างเลเยอร์ที่มองเห็นได้และเลเยอร์ที่ซ่อนอยู่นั้นไม่มีทิศทางและทำให้สามารถเคลื่อนที่ได้ทั้งสองทิศทาง)
- เผยแพร่ v' ใหม่กลับไปยังเลเยอร์ที่ซ่อนอยู่พร้อมผลการเปิดใช้งาน h'
อัพเดทน้ำหนัก :
โดยที่ a คืออัตราการเรียนรู้และ v , v' , h , h' และ w เป็นเวกเตอร์
สัญชาตญาณเบื้องหลังอัลกอริธึมคือระยะบวก ( h ให้ v ) สะท้อนถึงการแสดงข้อมูลภายในเครือข่ายของข้อมูลใน โลกแห่งความเป็นจริง ในขณะเดียวกัน เฟสเชิงลบแสดงถึงความพยายามในการสร้างข้อมูลขึ้นใหม่ตามการแสดงข้อมูลภายในนี้ ( v' ให้ h ) เป้าหมายหลักคือเพื่อให้ ข้อมูลที่สร้างขึ้น ใกล้เคียงกับโลกแห่งความเป็น จริงมากที่สุด และสิ่งนี้สะท้อนให้เห็นในสูตรการอัพเดทน้ำหนัก
กล่าวอีกนัยหนึ่ง เน็ตมีการรับรู้ถึงวิธีการแสดงข้อมูลที่ป้อนเข้า ดังนั้นจึงพยายามทำซ้ำข้อมูลตามการรับรู้นี้ หากการทำซ้ำไม่ใกล้เคียงกับความเป็นจริง จะทำการปรับเปลี่ยนและลองอีกครั้ง
กลับเป็นไข้หวัดใหญ่
เราจะใช้ชุดข้อมูลอาการเดิมเพื่อแสดงให้เห็นความแตกต่างที่ตรงกันข้าม เครือข่ายทดสอบคือ RBM ที่มีหน่วยที่มองเห็นได้หกหน่วยและหน่วยที่ซ่อนอยู่สองหน่วย เราจะฝึกเครือข่ายโดยใช้ความแตกต่างที่ตรงกันข้ามกับอาการที่ยึดกับ เลเยอร์ ที่มองเห็นได้ ในระหว่างการทดสอบ อาการจะแสดงอีกครั้งที่ชั้นที่มองเห็นได้ จากนั้น ข้อมูลจะแพร่กระจายไปยังเลเยอร์ที่ซ่อนอยู่ หน่วยที่ซ่อนอยู่แสดงถึงสถานะป่วย/สุขภาพ ซึ่งเป็นสถาปัตยกรรมที่คล้ายคลึงกันมากกับตัวเข้ารหัสอัตโนมัติ (เผยแพร่ข้อมูลจากเลเยอร์ที่มองเห็นได้ไปยังเลเยอร์ที่ซ่อนอยู่)
หลังจากการทำซ้ำหลายร้อยครั้ง เราสามารถสังเกตผลลัพธ์เช่นเดียวกับตัวเข้ารหัสอัตโนมัติ: หนึ่งในหน่วยที่ซ่อนอยู่มีค่าการเปิดใช้งานที่สูงกว่าเมื่อมีการนำเสนอตัวอย่างที่ "ป่วย" ในขณะที่อีกหน่วยหนึ่งมีความกระตือรือร้นมากขึ้นสำหรับตัวอย่างที่ "แข็งแรง"
คุณสามารถดูตัวอย่างการทำงานจริงในเมธอด testContrastiveDivergence
เครือข่ายลึก
ตอนนี้เราได้แสดงให้เห็นว่าเลเยอร์ที่ซ่อนอยู่ของตัวเข้ารหัสอัตโนมัติและ RBM ทำหน้าที่เป็นตัวตรวจจับคุณสมบัติที่มีประสิทธิภาพ แต่เราจะใช้คุณสมบัติเหล่านี้โดยตรงได้ไม่บ่อยนัก อันที่จริง ชุดข้อมูลข้างต้นเป็นข้อยกเว้นมากกว่ากฎ เราจำเป็นต้องหาวิธีใช้คุณลักษณะที่ตรวจพบเหล่านี้โดยอ้อมแทน
โชคดีที่พบว่าโครงสร้างเหล่านี้สามารถ ซ้อนกัน เพื่อสร้างเครือข่าย ลึก ได้ เครือข่ายเหล่านี้สามารถฝึกฝนอย่างตะกละตะกลาม ทีละชั้น เพื่อช่วยในการเอาชนะปัญหาการ ไล่ระดับที่หายไป และปัญหา การ overfitting ที่เกี่ยวข้องกับการขยายพันธุ์ย้อนกลับแบบคลาสสิก
โครงสร้างที่ได้มักจะทรงพลังและให้ผลลัพธ์ที่น่าประทับใจ ตัวอย่างเช่น กระดาษ "แมว" ที่มีชื่อเสียงของ Google ซึ่งใช้ตัวเข้ารหัสอัตโนมัติเชิงลึกชนิดพิเศษเพื่อ "เรียนรู้" การตรวจจับใบหน้ามนุษย์และแมวตามข้อมูลที่ ไม่มีป้ายกำกับ
มาดูกันดีกว่า
ตัวเข้ารหัสอัตโนมัติแบบซ้อน
ตามชื่อที่แนะนำ เครือข่ายนี้ประกอบด้วยตัวเข้ารหัสอัตโนมัติหลายชุด
เลเยอร์ที่ซ่อนอยู่ของ autoencoder t ทำหน้าที่เป็นเลเยอร์อินพุตสำหรับ autoencoder t + 1 เลเยอร์อินพุตของตัวเข้ารหัสอัตโนมัติตัวแรกคือเลเยอร์อินพุตสำหรับเครือข่ายทั้งหมด ขั้นตอนการฝึกอบรมที่ชาญฉลาดเป็นชั้น ๆ เช่นนี้:
- ฝึกตัวเข้ารหัสอัตโนมัติตัวแรก ( t=1 หรือการเชื่อมต่อสีแดงในรูปด้านบน แต่มีเลเยอร์เอาต์พุตเพิ่มเติม) แยกกันโดยใช้วิธีการ backpropagation พร้อมข้อมูลการฝึกที่มีอยู่ทั้งหมด
- ฝึกตัวเข้ารหัสอัตโนมัติตัวที่สอง t=2 (การเชื่อมต่อสีเขียว) เนื่องจากเลเยอร์อินพุตสำหรับ t=2 เป็นเลเยอร์ที่ซ่อนอยู่ของ t=1 เราจึงไม่สนใจเลเยอร์เอาต์พุตของ t=1 อีกต่อไป และเราลบมันออกจากเครือข่าย การฝึกอบรมเริ่มต้นด้วยการยึดตัวอย่างอินพุตกับเลเยอร์อินพุตของ t=1 ซึ่งถูกขยายไปข้างหน้าไปยังเลเยอร์เอาต์พุตของ t=2 ถัดไป น้ำหนัก (input-hidden และ hidden-output) ของ t=2 จะได้รับการอัปเดตโดยใช้ backpropagation t=2 ใช้ตัวอย่างการฝึกทั้งหมด คล้ายกับ t=1
- ทำซ้ำขั้นตอนก่อนหน้าสำหรับเลเยอร์ทั้งหมด (เช่น ลบเลเยอร์เอาต์พุตของตัวเข้ารหัสอัตโนมัติก่อนหน้า แทนที่ด้วยตัวเข้ารหัสอัตโนมัติอื่น และฝึกด้วยการขยายพันธุ์ด้านหลัง)
- ขั้นตอนที่ 1-3 เรียกว่า ก่อนการฝึก และปล่อยให้ตุ้มน้ำหนักเริ่มต้นอย่างเหมาะสม อย่างไรก็ตาม ไม่มีการแมประหว่างข้อมูลอินพุตกับป้ายกำกับเอาต์พุต ตัวอย่างเช่น หากเครือข่ายได้รับการฝึกฝนให้จดจำรูปภาพของตัวเลขที่เขียนด้วยลายมือ ก็ยังไม่สามารถจับคู่หน่วยจากตัวตรวจจับคุณสมบัติสุดท้าย (เช่น เลเยอร์ที่ซ่อนอยู่ของตัวเข้ารหัสอัตโนมัติล่าสุด) กับประเภทหลักของรูปภาพ ในกรณีดังกล่าว วิธีแก้ไขที่พบบ่อยที่สุดคือการเพิ่มเลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์ตั้งแต่หนึ่งเลเยอร์ขึ้นไปในเลเยอร์สุดท้าย (การเชื่อมต่อสีน้ำเงิน) ขณะนี้ เครือข่ายทั้งหมดสามารถดูได้ว่าเป็นเพอร์เซปตรอนแบบหลายชั้น และได้รับการฝึกอบรมโดยใช้การขยายพันธุ์ย้อนหลัง (ขั้นตอนนี้เรียกอีกอย่างว่า fine-tuning )
ตัวเข้ารหัสอัตโนมัติแบบเรียงซ้อนนั้นล้วนเกี่ยวกับการจัดเตรียมวิธีการฝึกล่วงหน้าที่มีประสิทธิภาพสำหรับการเริ่มต้นน้ำหนักของเครือข่าย ทำให้คุณมีการรับรู้ที่ซับซ้อนหลายชั้นที่พร้อมสำหรับการฝึก (หรือ ปรับแต่ง )
เครือข่ายความเชื่อลึก
เช่นเดียวกับตัวเข้ารหัสอัตโนมัติ เรายังสามารถซ้อนเครื่อง Boltzmann เพื่อสร้างคลาสที่เรียกว่า เครือข่ายความเชื่อลึก (DBNs)
ในกรณีนี้ เลเยอร์ที่ซ่อนอยู่ของ RBM t จะทำหน้าที่เป็นเลเยอร์ที่มองเห็นได้สำหรับ RBM t+1 เลเยอร์อินพุตของ RBM แรกคือเลเยอร์อินพุตสำหรับเครือข่ายทั้งหมด และการฝึกอบรมล่วงหน้าที่ชาญฉลาดของเลเยอร์ที่โลภมีลักษณะดังนี้:
- ฝึก RBM t=1 ตัวแรกโดยใช้ contrastive divergence กับตัวอย่างการฝึกทั้งหมด
- ฝึก RBM ที่สอง t=2 เนื่องจากเลเยอร์ที่มองเห็นได้สำหรับ t=2 เป็นเลเยอร์ที่ซ่อนอยู่ของ t=1 การฝึกจึงเริ่มต้นด้วยการยึดตัวอย่างอินพุตกับเลเยอร์ที่มองเห็นได้ของ t=1 ซึ่งจะถูกขยายไปยังเลเยอร์ที่ซ่อนอยู่ t=1 จากนั้น ข้อมูลนี้จะใช้เพื่อเริ่มต้นการฝึกอบรม contrastive divergence สำหรับ t=2
- ทำซ้ำขั้นตอนก่อนหน้าสำหรับเลเยอร์ทั้งหมด
- คล้ายกับตัวเข้ารหัสอัตโนมัติแบบซ้อน หลังจากการฝึกอบรมล่วงหน้า เครือข่ายสามารถขยายได้โดยเชื่อมต่อเลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์ตั้งแต่หนึ่งเลเยอร์ขึ้นไปกับเลเยอร์ที่ซ่อนอยู่ RBM สุดท้าย ทำให้เกิดการรับรู้แบบหลายชั้น ซึ่งหลังจากนั้นจะสามารถ ปรับแบบละเอียด ได้โดยใช้การขยายพันธุ์ด้านหลัง
ขั้นตอนนี้คล้ายกับของ autoencoder แบบซ้อนกัน แต่ด้วย autoencoder ที่ถูกแทนที่ด้วย RBM และ backpropagation แทนที่ด้วยอัลกอริธึม contrastive divergence
(หมายเหตุ: สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการสร้างและฝึกอบรมตัวเข้ารหัสอัตโนมัติแบบซ้อนหรือเครือข่ายที่มีความเชื่อลึกๆ ให้ตรวจดูโค้ดตัวอย่างที่นี่)
Convolutional Networks
ในฐานะสถาปัตยกรรมการเรียนรู้เชิงลึกขั้นสุดท้าย มาดูเครือข่าย Convolutional ซึ่งเป็นเครือข่าย feedforward ระดับพิเศษที่น่าสนใจเป็นพิเศษซึ่งเหมาะสมอย่างยิ่งต่อการจดจำภาพ
ก่อนที่เราจะดูโครงสร้างจริงของเครือข่ายแบบ Convolutional ก่อนอื่นเราต้องกำหนด ตัวกรอง ภาพ หรือพื้นที่สี่เหลี่ยมจัตุรัสที่มีน้ำหนักที่เกี่ยวข้องกัน มีการใช้ฟิลเตอร์กับรูปภาพอินพุตทั้งหมด และคุณมักจะใช้ฟิลเตอร์หลายตัว ตัวอย่างเช่น คุณสามารถใช้ตัวกรองขนาด 6x6 สี่ตัวกับภาพที่ป้อนเข้า จากนั้น พิกเซลเอาต์พุตที่มีพิกัด 1.1 คือผลรวมถ่วงน้ำหนักของพิกเซลอินพุตขนาด 6x6 ที่มีมุมซ้ายบน 1,1 และน้ำหนักของฟิลเตอร์ (ซึ่งก็คือ 6x6 สี่เหลี่ยมจัตุรัสด้วย) พิกเซลเอาต์พุต 2,1 เป็นผลจากสี่เหลี่ยมอินพุตที่มีมุมบนซ้าย 2,1 เป็นต้น
เครือข่ายเหล่านี้ถูกกำหนดโดยคุณสมบัติดังต่อไปนี้:
- เลเยอร์ Convolutional ใช้ ตัวกรอง จำนวนหนึ่งกับอินพุต ตัวอย่างเช่น เลเยอร์ที่บิดเป็นเกลียวแรกของรูปภาพอาจมีฟิลเตอร์ขนาด 6x6 สี่ตัว ผลลัพธ์ของฟิลเตอร์หนึ่งตัวที่ใช้กับรูปภาพเรียกว่า ฟีเจอร์แมป (FM) และแมปฟีเจอร์ตัวเลขจะเท่ากับจำนวนฟิลเตอร์ หากเลเยอร์ก่อนหน้านั้นเกิดการบิดเบี้ยวด้วย ตัวกรองจะถูกนำไปใช้กับ FM ทั้งหมดที่มีน้ำหนักต่างกัน ดังนั้นแต่ละอินพุต FM จะเชื่อมต่อกับ FM เอาต์พุตแต่ละรายการ สัญชาตญาณเบื้องหลังน้ำหนักที่ใช้ร่วมกันทั่วทั้งภาพคือคุณลักษณะต่างๆ จะถูกตรวจพบโดยไม่คำนึงถึงตำแหน่ง ในขณะที่ตัวกรองหลายหลากช่วยให้แต่ละตัวกรองสามารถตรวจจับชุดคุณลักษณะต่างๆ ได้
- เลเยอร์ การสุ่มตัวอย่างจะลดขนาดของอินพุต ตัวอย่างเช่น หากอินพุตประกอบด้วยรูปภาพขนาด 32x32 และเลเยอร์มีพื้นที่สุ่มตัวอย่าง 2x2 ค่าเอาต์พุตจะเป็นรูปภาพขนาด 16x16 ซึ่งหมายความว่า 4 พิกเซล (แต่ละ 2x2 สี่เหลี่ยมจัตุรัส) ของรูปภาพอินพุตจะรวมกันเป็นเอาต์พุตเดียว พิกเซล มีหลายวิธีในการสุ่มตัวอย่าง แต่ที่นิยมมากที่สุดคือการรวมกลุ่มสูงสุด การรวมกันเฉลี่ย และการรวมสุ่ม
- เลเยอร์สุ่มย่อยสุดท้าย (หรือคอนโวลูชั่น) มักจะเชื่อมต่อกับเลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์ตั้งแต่หนึ่งเลเยอร์ขึ้นไป ซึ่งสุดท้ายแสดงถึงข้อมูลเป้าหมาย
- การฝึกอบรมดำเนินการโดยใช้ backpropagation ที่แก้ไขแล้วซึ่งนำชั้นการสุ่มตัวอย่างย่อยมาพิจารณาและอัปเดตน้ำหนักตัวกรองแบบบิดตามค่าทั้งหมดที่ใช้ตัวกรองนั้น
คุณสามารถดูตัวอย่างต่างๆ ของเครือข่าย Convolutional ที่ได้รับการฝึกอบรม (ด้วย backpropagation) ในชุดข้อมูล MNIST (รูปภาพระดับสีเทาของตัวอักษรที่เขียนด้วยลายมือ) ที่นี่ โดยเฉพาะในวิธี testLeNet* (ฉันขอแนะนำ testLeNetTiny2 เนื่องจากมีอัตราข้อผิดพลาดต่ำประมาณ 2% ในระยะเวลาอันสั้น) นอกจากนี้ยังมีการแสดงภาพ JavaScript ที่ดีของเครือข่ายที่คล้ายกันที่นี่
การดำเนินการ
ตอนนี้เราได้ครอบคลุมตัวแปรโครงข่ายประสาทเทียมที่พบบ่อยที่สุดแล้ว ฉันคิดว่าฉันจะเขียนเล็กน้อยเกี่ยวกับความท้าทายที่เกิดขึ้นระหว่างการนำโครงสร้างการเรียนรู้เชิงลึกเหล่านี้ไปใช้
พูดกว้างๆ ว่าเป้าหมายของฉันในการสร้างห้องสมุด Deep Learning คือ (และยังคงเป็นอยู่) เพื่อสร้างกรอบงานเครือข่ายประสาทเทียมที่ตรงตามเกณฑ์ต่อไปนี้:
- สถาปัตยกรรมทั่วไปที่สามารถแสดงรูปแบบต่างๆ ได้ (เช่น ตัวแปรทั้งหมดบนโครงข่ายประสาทเทียมที่เราได้เห็นด้านบน เป็นต้น)
- ความสามารถในการใช้อัลกอริธึมการฝึกอบรมที่หลากหลาย (การแพร่กระจายกลับ, ความแตกต่างที่ตรงกันข้าม ฯลฯ )
- ประสิทธิภาพที่ดี
เพื่อให้เป็นไปตามข้อกำหนดเหล่านี้ ฉันจึงใช้แนวทางแบบแบ่งชั้น (หรือโมดูลาร์) ในการออกแบบซอฟต์แวร์
โครงสร้าง
เริ่มจากพื้นฐานกันก่อน:
- NeuralNetworkImpl เป็นคลาสพื้นฐานสำหรับโมเดลโครงข่ายประสาทเทียมทั้งหมด
- แต่ละเครือข่ายมีชุดของเลเยอร์
- แต่ละชั้นมีรายการของการเชื่อมต่อ โดยที่การเชื่อมต่อคือการเชื่อมโยงระหว่างสองชั้น โดยที่เครือข่ายจะเป็นกราฟแบบวนซ้ำโดยตรง
โครงสร้างนี้คล่องตัวพอที่จะใช้สำหรับเครือข่าย feedforward แบบคลาสสิก เช่นเดียวกับ RBM และสถาปัตยกรรมที่ซับซ้อนมากขึ้น เช่น ImageNet
นอกจากนี้ยังอนุญาตให้เลเยอร์เป็นส่วนหนึ่งของเครือข่ายมากกว่าหนึ่งเครือข่าย ตัวอย่างเช่น เลเยอร์ใน Deep Belief Network ก็เป็นเลเยอร์ใน RBM ที่เกี่ยวข้องเช่นกัน
นอกจากนี้ สถาปัตยกรรมนี้ช่วยให้สามารถดู DBN เป็นรายการ RBM แบบซ้อนระหว่างขั้นตอนก่อนการฝึกอบรมและเครือข่ายฟีดฟอร์เวิร์ดระหว่างขั้นตอนการปรับละเอียด ซึ่งทั้งสะดวกและสะดวกทางโปรแกรม
การขยายพันธุ์ข้อมูล
โมดูลถัดไปดูแลการเผยแพร่ข้อมูลผ่านเครือข่าย กระบวนการสองขั้นตอน:
- กำหนดลำดับของเลเยอร์ ตัวอย่างเช่น เพื่อให้ได้ผลลัพธ์จากเพอร์เซปตรอนแบบหลายชั้น ข้อมูลจะถูก "ยึด" ไปยังเลเยอร์อินพุต (ด้วยเหตุนี้ นี่คือเลเยอร์แรกที่จะคำนวณ) และเผยแพร่ไปจนถึงเลเยอร์เอาต์พุต ในการอัปเดตน้ำหนักระหว่างการขยายพันธุ์ย้อนหลัง ข้อผิดพลาดของเอาต์พุตต้องได้รับการเผยแพร่ผ่านทุกเลเยอร์ในลำดับที่กว้างก่อน โดยเริ่มจากเลเยอร์เอาต์พุต ซึ่งทำได้โดยใช้การใช้งาน LayerOrderStrategy ที่หลากหลาย ซึ่งใช้ประโยชน์จากโครงสร้างกราฟของเครือข่าย โดยใช้วิธีการข้ามผ่านกราฟแบบต่างๆ ตัวอย่างบางส่วน ได้แก่ กลยุทธ์แบบกว้างก่อนและการกำหนดเป้าหมายของเลเยอร์เฉพาะ ลำดับนั้นถูกกำหนดโดยการเชื่อมต่อระหว่างเลเยอร์ ดังนั้นกลยุทธ์จะส่งคืนรายการการเชื่อมต่อที่เรียงลำดับ
- คำนวณมูลค่าการเปิดใช้งาน แต่ละชั้นมี ConnectionCalculator ที่เชื่อมโยงกัน ซึ่งจะดึงรายการการเชื่อมต่อ (จากขั้นตอนก่อนหน้า) และค่าที่ป้อนเข้ามา (จากเลเยอร์อื่น) และคำนวณการเปิดใช้งานที่เป็นผลลัพธ์ ตัวอย่างเช่น ในเครือข่ายฟีดฟอร์เวิร์ด sigmoidal อย่างง่าย ConnectionCalculator ของเลเยอร์ที่ซ่อนอยู่จะใช้ค่าของเลเยอร์อินพุตและอคติ (ซึ่งตามลำดับคือข้อมูลอินพุตและอาร์เรย์ 1s ) และน้ำหนักระหว่างหน่วย (ในกรณีที่เชื่อมต่ออย่างสมบูรณ์ จริงๆ แล้ว น้ำหนักจะถูกเก็บไว้ในการเชื่อมต่อแบบ FullyConnected เป็น เมทริกซ์ ) คำนวณผลรวมถ่วงน้ำหนัก และป้อนผลลัพธ์ลงในฟังก์ชัน sigmoid เครื่องคำนวณการเชื่อมต่อใช้ฟังก์ชันการถ่ายโอนที่หลากหลาย (เช่น ผลรวมถ่วงน้ำหนัก การบิดเบี้ยว) และการเปิดใช้งาน (เช่น ลอจิสติกส์และแทนห์สำหรับเพอร์เซปตรอนหลายชั้น ไบนารีสำหรับ RBM) ส่วนใหญ่สามารถดำเนินการบน GPU โดยใช้ Aparapi และใช้ได้กับการฝึกแบบมินิแบทช์
การคำนวณด้วย GPU ด้วย Aparapi
ดังที่ได้กล่าวไว้ก่อนหน้านี้ สาเหตุหนึ่งที่โครงข่ายประสาทเทียมได้ฟื้นคืนชีพขึ้นใหม่ในช่วงไม่กี่ปีที่ผ่านมาก็คือ วิธีการฝึกอบรมของพวกเขาเอื้อต่อการขนานอย่างมาก ช่วยให้คุณเร่งการฝึกอบรมได้อย่างมากด้วยการใช้ GPGPU ในกรณีนี้ ฉันเลือกทำงานกับไลบรารี Aparapi เพื่อเพิ่มการรองรับ GPU
Aparapi กำหนดข้อจำกัดที่สำคัญบางประการเกี่ยวกับเครื่องคำนวณการเชื่อมต่อ:
- อนุญาตให้ใช้อาร์เรย์มิติเดียว (และตัวแปร) ของประเภทข้อมูลพื้นฐานเท่านั้น
- อนุญาตให้เรียกเฉพาะเมธอดสมาชิกของคลาส Aparapi Kernel เท่านั้นจากโค้ดสั่งการของ GPU
ด้วยเหตุนี้ ข้อมูลส่วนใหญ่ (น้ำหนัก อาร์เรย์อินพุต และเอาต์พุต) จึงจัดเก็บไว้ในอินสแตน ซ์เมทริก ซ์ ซึ่งใช้อาร์เรย์โฟลตแบบมิติเดียวภายใน เครื่องคำนวณการเชื่อมต่อ Aparapi ทั้งหมดใช้ AparapiWeightedSum (สำหรับเลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์และฟังก์ชันอินพุตผลรวมแบบถ่วงน้ำหนัก), AparapiSubsampling2D (สำหรับเลเยอร์การสุ่มตัวอย่างย่อย) หรือ AparapiConv2D (สำหรับเลเยอร์ที่บิดเบี้ยว) ข้อจำกัดบางประการเหล่านี้สามารถแก้ไขได้ด้วยการแนะนำสถาปัตยกรรมระบบที่แตกต่างกัน Aparapi ยังอนุญาตให้เรียกใช้โค้ดเดียวกันทั้งบน CPU และ GPU
การฝึกอบรม
The training module implements various training algorithms. It relies on the previous two modules. For example, BackPropagationTrainer (all the trainers are using the Trainer base class) uses feedforward layer calculator for the feedforward phase and a special breadth-first layer calculator for propagating the error and updating the weights.
My latest work is on Java 8 support and some other improvements, will soon be merged into master.
บทสรุป
The aim of this Java deep learning tutorial was to give you a brief introduction to the field of deep learning algorithms, beginning with the most basic unit of composition (the perceptron) and progressing through various effective and popular architectures, like that of the restricted Boltzmann machine.
The ideas behind neural networks have been around for a long time; but today, you can't step foot in the machine learning community without hearing about deep networks or some other take on deep learning. Hype shouldn't be mistaken for justification, but with the advances of GPGPU computing and the impressive progress made by researchers like Geoffrey Hinton, Yoshua Bengio, Yann LeCun and Andrew Ng, the field certainly shows a lot of promise. There's no better time to get familiar and get involved like the present.
Appendix: Resources
If you're interested in learning more, I found the following resources quite helpful during my work:
- DeepLearning.net: a portal for all things deep learning. It has some nice tutorials, software library and a great reading list.
- An active Google+ community.
- Two very good courses: Machine Learning and Neural Networks for Machine Learning, both offered on Coursera.
- The Stanford neural networks tutorial.