Schooling Flappy Bird: แบบฝึกหัดการเรียนรู้การเสริมแรง
เผยแพร่แล้ว: 2022-03-11ในการเขียนโปรแกรมแบบคลาสสิก คำแนะนำของซอฟต์แวร์ถูกสร้างขึ้นโดยโปรแกรมเมอร์อย่างชัดเจน และไม่มีการเรียนรู้อะไรจากข้อมูลเลย ในทางตรงกันข้าม แมชชีนเลิร์นนิงเป็นสาขาวิชาวิทยาการคอมพิวเตอร์ที่ใช้วิธีการทางสถิติเพื่อให้คอมพิวเตอร์เรียนรู้และดึงความรู้จากข้อมูลโดยไม่ต้องตั้งโปรแกรมไว้อย่างชัดเจน
ในบทช่วยสอนการเรียนรู้การเสริมแรงนี้ ฉันจะแสดงวิธีที่เราสามารถใช้ PyTorch เพื่อสอนวิธีการเล่น Flappy Bird ให้กับเครือข่ายประสาทการเรียนรู้การเสริมแรง แต่ก่อนอื่น เราจะต้องครอบคลุมการสร้างบล็อคจำนวนหนึ่ง
อัลกอริธึมแมชชีนเลิร์นนิงสามารถแบ่งออกเป็นสองส่วนคร่าวๆ: อัลกอริธึมการเรียนรู้แบบดั้งเดิมและอัลกอริธึมการเรียนรู้เชิงลึก อัลกอริธึมการเรียนรู้แบบดั้งเดิมมักจะมีพารามิเตอร์ที่เรียนรู้ได้น้อยกว่าอัลกอริธึมการเรียนรู้เชิงลึกมากและมีความสามารถในการเรียนรู้น้อยกว่ามาก
นอกจากนี้ อัลกอริธึมการเรียนรู้แบบดั้งเดิมยังไม่สามารถ แยกคุณลักษณะ ได้: ผู้เชี่ยวชาญด้านปัญญาประดิษฐ์จำเป็นต้องค้นหาการแสดงข้อมูลที่ดี ซึ่งจะถูกส่งไปยังอัลกอริทึมการเรียนรู้ ตัวอย่างของเทคนิคการเรียนรู้ของเครื่องแบบดั้งเดิม ได้แก่ SVM, ฟอเรสต์แบบสุ่ม, โครงสร้างการตัดสินใจ และ $k$-mean ในขณะที่อัลกอริธึมกลางในการเรียนรู้เชิงลึกคือ โครงข่ายประสาทเทียมระดับลึก
การป้อนข้อมูลไปยังเครือข่ายประสาทเทียมระดับลึกอาจเป็นภาพดิบ และผู้เชี่ยวชาญด้านปัญญาประดิษฐ์ไม่จำเป็นต้องค้นหาการแสดงข้อมูลใดๆ—เครือข่ายประสาทจะค้นหาการแสดงที่ดีที่สุดในระหว่างกระบวนการฝึกอบรม
เทคนิคการเรียนรู้เชิงลึกจำนวนมากเป็นที่ทราบกันดีมาเป็นเวลานาน แต่ความก้าวหน้าล่าสุดในฮาร์ดแวร์ได้กระตุ้นการวิจัยและพัฒนาการเรียนรู้เชิงลึกอย่างรวดเร็ว Nvidia รับผิดชอบในการขยายสาขาเนื่องจาก GPU ได้เปิดใช้งานการทดลองการเรียนรู้เชิงลึกอย่างรวดเร็ว
พารามิเตอร์ที่เรียนรู้ได้และไฮเปอร์พารามิเตอร์
อัลกอริธึมการเรียนรู้ของเครื่องประกอบด้วยพารามิเตอร์ที่เรียนรู้ได้ซึ่งปรับในกระบวนการฝึกอบรมและพารามิเตอร์ที่ไม่สามารถเรียนรู้ได้ซึ่งตั้งค่าไว้ก่อนกระบวนการฝึกอบรม พารามิเตอร์ที่ตั้งไว้ก่อนการเรียนรู้เรียกว่า ไฮเปอร์ พารามิเตอร์
การค้นหาตาราง เป็นวิธีการทั่วไปในการค้นหาไฮเปอร์พารามิเตอร์ที่เหมาะสมที่สุด เป็นวิธีการแบบเดรัจฉาน: หมายถึงลองใช้ชุดค่าผสมของไฮเปอร์พารามิเตอร์ที่เป็นไปได้ทั้งหมดในช่วงที่กำหนด และเลือกชุดค่าผสมที่เพิ่มเมตริกที่กำหนดไว้ล่วงหน้าให้ได้มากที่สุด
อัลกอริธึมการเรียนรู้ภายใต้การดูแล ไม่ได้รับการดูแล และเสริมกำลัง
วิธีหนึ่งในการจำแนกอัลกอริธึมการเรียนรู้คือการวาดเส้นแบ่งระหว่างอัลกอริธึมภายใต้การดูแลและไม่ได้รับการดูแล (แต่นั่นไม่จำเป็นต้องตรงไปตรงมาเสมอไป: การเรียนรู้การเสริมกำลังอยู่ที่ไหนสักแห่งระหว่างสองประเภทนี้)
เมื่อเราพูดถึงการเรียนรู้ภายใต้การดูแล เราจะดูคู่ $ (x_i, y_i) $ $ x_i $ คืออินพุตของอัลกอริทึมและ $ y_i $ คือเอาต์พุต งานของเราคือค้นหาฟังก์ชันที่จะทำการจับคู่ที่ถูกต้องจาก $ x_i $ ถึง $ y_i $
เพื่อปรับพารามิเตอร์ที่เรียนรู้ได้เพื่อให้กำหนดฟังก์ชันที่แมป $ x_i $ ถึง $ y_i $ จำเป็นต้องกำหนดฟังก์ชันการสูญเสียและตัวเพิ่มประสิทธิภาพ เครื่องมือเพิ่มประสิทธิภาพจะลดฟังก์ชันการสูญเสียให้เหลือน้อยที่สุด ตัวอย่างหนึ่งของฟังก์ชันการสูญเสียคือความคลาดเคลื่อนกำลังสองเฉลี่ย (MSE):
\[MSE = \sum_{i=1}^{n} (y_i - \widehat{y_i} )^2\]ที่นี่ $ y_i $ เป็นป้ายกำกับความจริงพื้นฐาน และ $ \widehat{y_i} $ เป็นป้ายกำกับที่คาดคะเน เครื่องมือเพิ่มประสิทธิภาพหนึ่งที่ได้รับความนิยมอย่างมากในการเรียนรู้เชิงลึกคือ stochastic gradient descent มีรูปแบบต่างๆ มากมายที่พยายามปรับปรุงวิธีการไล่ระดับสีสุ่ม: Adam, Adadelta, Adagrad และอื่นๆ
อัลกอริธึมที่ไม่ได้รับการดูแลจะพยายามค้นหาโครงสร้างในข้อมูลโดยไม่ได้ระบุป้ายกำกับไว้อย่างชัดเจน $k$-means เป็นหนึ่งในตัวอย่างของอัลกอริธึมที่ไม่มีการควบคุมซึ่งพยายามค้นหาคลัสเตอร์ที่เหมาะสมที่สุดในข้อมูล ด้านล่างเป็นรูปภาพที่มีจุดข้อมูล 300 จุด $k$-หมายถึงอัลกอริทึมพบโครงสร้างในข้อมูลและกำหนดป้ายกำกับคลัสเตอร์ให้กับแต่ละจุดข้อมูล แต่ละคลัสเตอร์มีสีของตัวเอง
การเรียนรู้การเสริมกำลังใช้รางวัล: ป้ายกำกับที่กระจัดกระจายและล่าช้า ตัวแทนดำเนินการซึ่งเปลี่ยนแปลงสภาพแวดล้อม ซึ่งจะสามารถได้รับการสังเกตและรางวัลใหม่ การสังเกตคือสิ่งเร้าที่ตัวแทนรับรู้จากสิ่งแวดล้อม อาจเป็นสิ่งที่ตัวแทนเห็น ได้ยิน ได้กลิ่น และอื่นๆ
รางวัลจะมอบให้กับตัวแทนเมื่อมีการดำเนินการ มันบอกตัวแทนว่าการกระทำนั้นดีแค่ไหน โดยการรับรู้การสังเกตและรางวัล ตัวแทนได้เรียนรู้วิธีปฏิบัติตนอย่างเหมาะสมในสภาพแวดล้อม ฉันจะลงรายละเอียดเพิ่มเติมด้านล่าง
การเรียนรู้การเสริมแรงแบบแอคทีฟ พาสซีฟ และผกผัน
มีวิธีการที่แตกต่างกันสองสามวิธีสำหรับเทคนิคนี้ อย่างแรกเลย มีการเรียนรู้การเสริมกำลังเชิงรุก ซึ่งเราใช้ที่นี่ ในทางตรงกันข้าม มีการเรียนรู้แบบเสริมกำลังแบบพาสซีฟ โดยที่รางวัลเป็นเพียงการสังเกตอีกรูปแบบหนึ่ง และการตัดสินใจจะเป็นไปตามนโยบายที่กำหนดไว้
ในที่สุด การเรียนรู้การเสริมแรงผกผันพยายามที่จะสร้างฟังก์ชันการให้รางวัลขึ้นใหม่โดยพิจารณาจากประวัติของการกระทำและรางวัลในสถานะต่างๆ
ลักษณะทั่วไป Overfitting และ Underfitting
อินสแตนซ์ของพารามิเตอร์และไฮเปอร์พารามิเตอร์คงที่ใดๆ เรียกว่าโมเดล การทดลองแมชชีนเลิร์นนิงมักประกอบด้วยสองส่วน: การฝึกอบรมและการทดสอบ
ในระหว่างขั้นตอนการฝึกอบรม พารามิเตอร์ที่เรียนรู้ได้จะถูกปรับโดยใช้ข้อมูลการฝึกอบรม ในกระบวนการทดสอบ พารามิเตอร์ที่เรียนรู้ได้จะถูกระงับ และงานคือตรวจสอบว่าโมเดลคาดการณ์ข้อมูลที่มองไม่เห็นก่อนหน้านี้ได้ดีเพียงใด ลักษณะทั่วไปคือความสามารถของเครื่องเรียนรู้ในการทำงานอย่างถูกต้องกับตัวอย่างหรืองานใหม่ที่มองไม่เห็นหลังจากประสบกับชุดข้อมูลการเรียนรู้
หากแบบจำลองเรียบง่ายเกินไปเมื่อเทียบกับข้อมูล แบบจำลองนั้นจะไม่สามารถพอดีกับข้อมูลการฝึกได้และจะทำงานได้ไม่ดีทั้งในชุดข้อมูลการฝึกและชุดข้อมูลการทดสอบ ในกรณีนั้น เราบอกว่าโมเดลนั้นไม่ พอดี ตัว
หากโมเดลแมชชีนเลิร์นนิงทำงานได้ดีในชุดข้อมูลการฝึก แต่ไม่ดีกับชุดข้อมูลทดสอบ เราจะบอกว่ามันเหมาะสม เกินไป Overfitting คือสถานการณ์ที่โมเดลซับซ้อนเกินไปเมื่อเทียบกับข้อมูล มันสามารถพอดีกับข้อมูลการฝึกได้อย่างสมบูรณ์ แต่มันถูกปรับให้เข้ากับชุดข้อมูลการฝึกอย่างมากซึ่งมันทำงานได้ไม่ดีกับข้อมูลการทดสอบ—กล่าวคือ มันไม่ได้ทำให้เป็นภาพรวม
ด้านล่างนี้คือรูปภาพที่แสดงการสวมใส่ที่พอดีและพอดีตัวเมื่อเปรียบเทียบกับสถานการณ์ที่สมดุลระหว่างข้อมูลโดยรวมและฟังก์ชันการคาดคะเน
ความสามารถในการปรับขนาด
ข้อมูลมีความสำคัญอย่างยิ่งในการสร้างแบบจำลองการเรียนรู้ของเครื่อง โดยปกติอัลกอริธึมการเรียนรู้แบบดั้งเดิมไม่ต้องการข้อมูลมากเกินไป แต่เนื่องจากความจุที่จำกัด ประสิทธิภาพก็จำกัดเช่นกัน ด้านล่างนี้คือแผนภาพที่แสดงให้เห็นว่าวิธีการเรียนรู้เชิงลึกนั้นปรับขนาดได้ดีเพียงใดเมื่อเทียบกับอัลกอริธึมการเรียนรู้ของเครื่องแบบดั้งเดิม
โครงข่ายประสาทเทียม
โครงข่ายประสาทเทียมประกอบด้วยหลายชั้น ภาพด้านล่างแสดงโครงข่ายประสาทเทียมแบบง่ายที่มีสี่ชั้น เลเยอร์แรกเป็นเลเยอร์อินพุต และเลเยอร์สุดท้ายคือเลเยอร์เอาต์พุต สองชั้นระหว่างชั้นอินพุตและเอาท์พุตเป็นชั้นที่ซ่อนอยู่
หากโครงข่ายประสาทเทียมมีเลเยอร์ที่ซ่อนอยู่มากกว่าหนึ่งชั้น เราเรียกว่าโครงข่ายประสาทเทียมระดับลึก ชุดอินพุต $ X $ ถูกกำหนดให้กับโครงข่ายประสาทเทียม และรับเอาต์พุต $ y $ การเรียนรู้ทำได้โดยใช้อัลกอริธึม backpropagation ซึ่งรวมฟังก์ชันการสูญเสียและเครื่องมือเพิ่มประสิทธิภาพ
Backpropagation ประกอบด้วยสองส่วน: การส่งต่อและการส่งต่อย้อนกลับ ในการส่งต่อข้อมูลอินพุตจะถูกใส่เข้ากับอินพุตของโครงข่ายประสาทเทียมและรับเอาต์พุต การสูญเสียระหว่างความจริงภาคพื้นดินและการทำนายจะถูกคำนวณ จากนั้นในการผ่านย้อนกลับ พารามิเตอร์ของโครงข่ายประสาทเทียมจะถูกปรับตามการสูญเสีย
โครงข่ายประสาทเทียม
รูปแบบโครงข่ายประสาทเทียมแบบหนึ่งคือ โครงข่ายประสาทเทียม ใช้เป็นหลักสำหรับงานวิทัศน์คอมพิวเตอร์
เลเยอร์ที่สำคัญที่สุดในโครงข่ายประสาทเทียมคือชั้นที่เกิดการบิดเบี้ยว (จึงเป็นชื่อ) พารามิเตอร์ของมันทำจากตัวกรองที่เรียนรู้ได้หรือที่เรียกว่าเมล็ด เลเยอร์ Convolutional ใช้การดำเนินการ Convolution กับอินพุต โดยส่งผลลัพธ์ไปยังเลเยอร์ถัดไป การดำเนินการ convolution ช่วยลดจำนวนพารามิเตอร์ที่เรียนรู้ได้ ทำหน้าที่เป็นฮิวริสติกชนิดหนึ่ง และทำให้การฝึกอบรมโครงข่ายประสาทเทียมง่ายขึ้น
ด้านล่างนี้คือวิธีการทำงานของเคอร์เนลแบบคอนโวลูชันหนึ่งตัวในเลเยอร์แบบคอนโวลูชัน เคอร์เนลถูกนำไปใช้กับรูปภาพและได้คุณสมบัติที่เชื่อมโยง
เลเยอร์ ReLU ใช้เพื่อแนะนำความไม่เป็นเชิงเส้นในโครงข่ายประสาทเทียม ความไม่เป็นเชิงเส้นมีความสำคัญเพราะด้วยพวกมัน เราสามารถจำลองฟังก์ชันทุกประเภท ไม่เพียงแต่เส้นตรง ทำให้โครงข่ายประสาทเทียมเป็นตัวประมาณฟังก์ชันสากล สิ่งนี้ทำให้ฟังก์ชัน ReLU ถูกกำหนดดังนี้:
\[ReLU = \max(0, x)\]ReLU เป็นหนึ่งในตัวอย่างที่เรียกว่า ฟังก์ชันการเปิดใช้งาน ซึ่งใช้เพื่อแนะนำความไม่เป็นเชิงเส้นในโครงข่ายประสาทเทียม ตัวอย่างของฟังก์ชันการเปิดใช้งานอื่นๆ ได้แก่ ฟังก์ชันซิกมอยด์และไฮเปอร์แทนเจนต์ ReLU เป็นฟังก์ชันการเปิดใช้งานที่ได้รับความนิยมมากที่สุด เนื่องจากแสดงให้เห็นว่าทำให้รถไฟเครือข่ายประสาทเทียมมีประสิทธิภาพมากขึ้นเมื่อเทียบกับฟังก์ชันการเปิดใช้งานอื่นๆ
ด้านล่างเป็นโครงเรื่องของฟังก์ชัน ReLU
อย่างที่คุณเห็น ฟังก์ชัน ReLU นี้เพียงแค่เปลี่ยนค่าลบเป็นศูนย์ ซึ่งจะช่วยป้องกันปัญหาการไล่ระดับสีที่หายไป หากการไล่ระดับสีหายไป จะไม่ส่งผลกระทบมากนักในการปรับน้ำหนักของโครงข่ายประสาทเทียม
โครงข่ายประสาทเทียมประกอบด้วยหลายชั้น: ชั้น Convolutional, ชั้น ReLU และชั้นที่เชื่อมต่ออย่างสมบูรณ์ เลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์จะเชื่อมต่อเซลล์ประสาททุกเซลล์ในชั้นหนึ่งกับเซลล์ประสาททุกเซลล์ในอีกชั้นหนึ่ง ดังที่เห็นได้จากเลเยอร์ที่ซ่อนอยู่ 2 ชั้นในรูปภาพที่จุดเริ่มต้นของส่วนนี้ แมปเลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์ล่าสุดจะส่งออกจากเลเยอร์ก่อนหน้าไปยังค่า number_of_actions
ในกรณีนี้
แอปพลิเคชั่น
การเรียนรู้เชิงลึกประสบความสำเร็จและมีประสิทธิภาพเหนือกว่าอัลกอริธึมการเรียนรู้ของเครื่องแบบคลาสสิกในหลายสาขาย่อยของแมชชีนเลิร์นนิง รวมถึงการมองเห็นด้วยคอมพิวเตอร์ การรู้จำคำพูด และการเรียนรู้แบบเสริมกำลัง สาขาวิชาต่างๆ ของการเรียนรู้เชิงลึกเหล่านี้ถูกนำไปใช้ในด้านต่างๆ ในโลกของความเป็นจริง: การเงิน การแพทย์ ความบันเทิง ฯลฯ
การเรียนรู้การเสริมแรง
การเรียนรู้การเสริมกำลังขึ้นอยู่กับ ตัวแทน ตัวแทนดำเนินการในสภาพแวดล้อมและรับการสังเกตและรางวัลจากมัน ตัวแทนต้องได้รับการฝึกอบรมเพื่อเพิ่มรางวัลสะสมสูงสุด ดังที่ระบุไว้ในบทนำ ด้วยอัลกอริธึมการเรียนรู้ของเครื่องแบบคลาสสิก วิศวกรการเรียนรู้ของเครื่องจำเป็นต้องทำการแยกคุณลักษณะ กล่าวคือ สร้างคุณลักษณะที่ดีซึ่งแสดงถึงสภาพแวดล้อมได้ดี และถูกป้อนเข้าสู่อัลกอริธึมการเรียนรู้ของเครื่อง
การใช้การเรียนรู้เชิงลึกทำให้สามารถสร้างระบบแบบ end-to-end ที่รับอินพุตที่มีมิติสูง เช่น วิดีโอ และจากระบบจะเรียนรู้กลยุทธ์ที่เหมาะสมที่สุดสำหรับตัวแทนในการดำเนินการที่ดี
ในปี 2013 DeepMind สตาร์ทอัพจากลอนดอน AI ได้สร้างความก้าวหน้าครั้งยิ่งใหญ่ในการเรียนรู้ที่จะควบคุมตัวแทนโดยตรงจากอินพุตทางประสาทสัมผัสที่มีมิติสูง พวกเขาตีพิมพ์บทความเรื่อง Playing Atari with Deep Reinforcement Learning ซึ่งแสดงให้เห็นว่าพวกเขาสอนโครงข่ายประสาทเทียมให้เล่นเกม Atari ได้อย่างไรเพียงแค่มองหน้าจอ พวกเขาได้มาโดย Google แล้วจึงตีพิมพ์บทความใหม่ใน Nature พร้อมการปรับปรุงบางอย่าง: การควบคุมระดับมนุษย์ผ่านการเรียนรู้การเสริมแรงเชิงลึก
ตรงกันข้ามกับกระบวนทัศน์แมชชีนเลิร์นนิงอื่นๆ การเรียนรู้แบบเสริมกำลังไม่มีผู้บังคับบัญชา มีเพียงสัญญาณให้รางวัลเท่านั้น ข้อเสนอแนะล่าช้า: ไม่ได้เกิดขึ้นทันทีเหมือนในอัลกอริธึมการเรียนรู้ภายใต้การดูแล ข้อมูลเป็นแบบต่อเนื่องและการกระทำของตัวแทนส่งผลต่อข้อมูลที่ตามมาที่ได้รับ
ขณะนี้ ตัวแทนตั้งอยู่ในสภาพแวดล้อม ซึ่งอยู่ในสถานะหนึ่ง เพื่ออธิบายรายละเอียดเพิ่มเติม เราใช้กระบวนการตัดสินใจของ Markov ซึ่งเป็นวิธีอย่างเป็นทางการในการสร้างแบบจำลองสภาพแวดล้อมการเรียนรู้แบบเสริมกำลังนี้ ประกอบด้วยชุดของสถานะ ชุดของการกระทำที่เป็นไปได้ และกฎ (เช่น ความน่าจะเป็น) สำหรับการเปลี่ยนจากสถานะหนึ่งไปยังอีกสถานะหนึ่ง
เอเจนต์สามารถดำเนินการเปลี่ยนแปลงสภาพแวดล้อมได้ เราเรียกรางวัล $ R_t $ เป็นสัญญาณตอบรับแบบสเกลาร์ที่บ่งชี้ว่าตัวแทนดำเนินการในขั้นตอนที่ $t$ ได้ดีเพียงใด
เพื่อผลงานที่ดีในระยะยาว จะต้องไม่คำนึงถึงรางวัลในทันทีแต่รวมถึงรางวัลในอนาคตด้วย รางวัลรวมสำหรับหนึ่งตอนจากขั้นตอนเวลา $t$ คือ $ R_t = r_t + r_{t+1} + r_{t+2} + \ldots + r_n $ อนาคตเป็นสิ่งที่ไม่แน่นอนและยิ่งเราดำเนินต่อไปในอนาคต การคาดการณ์ในอนาคตอาจแตกต่างออกไปมากขึ้น ด้วยเหตุนี้ จึงใช้รางวัลส่วนลดในอนาคต: $ R_t = r_t +\gamma r_{t+1} + \gamma^2r_{t+2} + \ldots + \gamma^{nt}r_n = r_t + \gamma R_{t+1} $. ตัวแทนควรเลือกการดำเนินการที่จะเพิ่มผลตอบแทนในอนาคตที่มีส่วนลดสูงสุด
การเรียนรู้ Q ลึก
ฟังก์ชัน $ Q(s, a) $ แสดงถึงรางวัลในอนาคตที่มีส่วนลดสูงสุดเมื่อดำเนินการ $ a $
การประมาณการของรางวัลในอนาคตกำหนดโดยสมการ Bellman: $ Q(s, a) = r + \gamma \max_{a'}Q(s', a') $ กล่าวอีกนัยหนึ่ง รางวัลสูงสุดในอนาคตที่มอบให้รัฐ $ s $ และการกระทำ $ a $ คือรางวัลทันทีบวกรางวัลสูงสุดในอนาคตสำหรับสถานะถัดไป
การประมาณค่า Q โดยใช้ฟังก์ชันไม่เชิงเส้น (โครงข่ายประสาทเทียม) ไม่เสถียรมาก ด้วยเหตุนี้ การเล่นซ้ำของประสบการณ์จึงถูกใช้เพื่อความเสถียร ประสบการณ์ระหว่างตอนต่างๆ ในเซสชันการฝึกจะถูกเก็บไว้ในหน่วยความจำเล่นซ้ำ มินิแบทช์สุ่มจากหน่วยความจำรีเพลย์ถูกใช้แทนการเปลี่ยนล่าสุด สิ่งนี้แบ่งความคล้ายคลึงกันของตัวอย่างการฝึกอบรมที่ตามมาซึ่งอาจผลักดันโครงข่ายประสาทให้เหลือน้อยที่สุด
มีประเด็นสำคัญอีกสองประการที่จะกล่าวถึงเกี่ยวกับการเรียนรู้ Q เชิงลึก: การสำรวจและการหาประโยชน์ ด้วยการแสวงหาผลประโยชน์ การตัดสินใจที่ดีที่สุดเมื่อได้รับข้อมูลปัจจุบัน การสำรวจรวบรวมข้อมูลเพิ่มเติม

เมื่ออัลกอริธึมดำเนินการตามที่โครงข่ายประสาทเทียมเสนอ มันกำลังทำการเอารัดเอาเปรียบ: มันใช้ประโยชน์จากความรู้ที่เรียนรู้ของโครงข่ายประสาทเทียม ในทางตรงกันข้าม อัลกอริธึมสามารถดำเนินการแบบสุ่ม สำรวจความเป็นไปได้ใหม่ๆ และแนะนำความรู้ใหม่ที่อาจเกิดขึ้นกับโครงข่ายประสาทเทียม
“อัลกอริธึม Deep Q-learning พร้อมการเล่นซ้ำของประสบการณ์” จากบทความของ DeepMind Playing Atari พร้อม Deep Reinforcement Learning แสดงไว้ด้านล่าง
DeepMind หมายถึงเครือข่าย Convolutional ที่ได้รับการฝึกอบรมด้วยวิธีการของพวกเขาเป็น Deep Q-networks (DQN)
ตัวอย่างการเรียนรู้ Q แบบลึกโดยใช้ Flappy Bird
Flappy Bird เป็นเกมมือถือยอดนิยมที่พัฒนาโดยศิลปินวิดีโอเกมชาวเวียดนามและโปรแกรมเมอร์ Dong Nguyen ในนั้นผู้เล่นควบคุมนกและพยายามบินระหว่างท่อสีเขียวโดยไม่โดนพวกมัน
ด้านล่างนี้เป็นภาพหน้าจอจากโคลน Flappy Bird ที่เข้ารหัสโดยใช้ PyGame:
โคลนได้ถูกแยกและดัดแปลงตั้งแต่นั้นมา: พื้นหลัง เสียง และรูปแบบนกและท่อต่างๆ ถูกลบออก และโค้ดได้รับการปรับปรุงเพื่อให้สามารถใช้งานได้ง่ายด้วยเฟรมเวิร์กการเรียนรู้การเสริมแรงอย่างง่าย เอ็นจิ้นเกมที่ดัดแปลงมาจากโปรเจ็กต์ TensorFlow นี้:
แต่แทนที่จะใช้ TensorFlow ฉันได้สร้างกรอบการเรียนรู้การเสริมแรงเชิงลึกโดยใช้ PyTorch PyTorch เป็นเฟรมเวิร์กการเรียนรู้เชิงลึกสำหรับการทดลองที่รวดเร็วและยืดหยุ่น ให้บริการเทนเซอร์และโครงข่ายประสาทเทียมแบบไดนามิกใน Python พร้อมการเร่งความเร็ว GPU ที่แข็งแกร่ง
สถาปัตยกรรมโครงข่ายประสาทเทียมเหมือนกับ DeepMind ที่ใช้ในกระดาษ การควบคุมระดับมนุษย์ผ่านการเรียนรู้การเสริมแรงเชิงลึก
ชั้น | ป้อนข้อมูล | ขนาดตัวกรอง | สไตรด์ | จำนวนตัวกรอง | การเปิดใช้งาน | เอาท์พุต |
---|---|---|---|---|---|---|
Conv1 | 84x84x4 | 8x8 | 4 | 32 | ReLU | 20x20x32 |
Conv2 | 20x20x32 | 4x4 | 2 | 64 | ReLU | 9x9x64 |
Conv3 | 9x9x64 | 3x3 | 1 | 64 | ReLU | 7x7x64 |
fc4 | 7x7x64 | 512 | ReLU | 512 | ||
fc5 | 512 | 2 | เชิงเส้น | 2 |
มีสามชั้น convolutional และสองชั้นที่เชื่อมต่ออย่างสมบูรณ์ แต่ละชั้นใช้การเปิดใช้งาน ReLU ยกเว้นชั้นสุดท้ายซึ่งใช้การเปิดใช้งานเชิงเส้น โครงข่ายประสาทเทียมจะแสดงค่าสองค่าที่แสดงถึงการกระทำที่เป็นไปได้ของผู้เล่นเท่านั้น: "บินขึ้น" และ "ไม่ทำอะไรเลย"
อินพุตประกอบด้วยภาพขาวดำขนาด 84x84 ต่อเนื่องกันสี่ภาพ ด้านล่างนี้คือตัวอย่างรูปภาพสี่ภาพที่ส่งไปยังโครงข่ายประสาทเทียม
คุณจะสังเกตเห็นว่าภาพถูกหมุน นั่นเป็นเพราะผลลัพธ์ของเอ็นจิ้นเกมของโคลนถูกหมุน แต่ถ้าโครงข่ายประสาทได้รับการสอนและทดสอบโดยใช้ภาพดังกล่าว จะไม่ส่งผลต่อประสิทธิภาพของโครงข่าย
คุณอาจสังเกตเห็นว่ารูปภาพถูกครอบตัดโดยที่พื้นถูกละไว้ เนื่องจากไม่เกี่ยวข้องกับงานนี้ พิกเซลทั้งหมดที่แสดงท่อและนกเป็นสีขาว และพิกเซลทั้งหมดที่แสดงพื้นหลังเป็นสีดำ
นี่เป็นส่วนหนึ่งของรหัสที่กำหนดโครงข่ายประสาทเทียม น้ำหนักของโครงข่ายประสาทเทียมถูกกำหนดให้เป็นไปตามการกระจายแบบสม่ำเสมอ $\mathcal{U}(-0.01, 0.01)$ ส่วนอคติของพารามิเตอร์ของโครงข่ายประสาทเทียมถูกตั้งค่าเป็น 0.01 มีการทดลองเริ่มต้นที่แตกต่างกันหลายอย่าง (ชุด Xavier, Xavier ปกติ, ชุด Kaiming, Kaiming ปกติ, ชุดและปกติ) แต่การเริ่มต้นข้างต้นทำให้โครงข่ายประสาทเทียมมาบรรจบกันและฝึกได้เร็วที่สุด ขนาดของโครงข่ายประสาทเทียมคือ 6.8 MB
class NeuralNetwork(nn.Module): def __init__(self): super(NeuralNetwork, self).__init__() self.number_of_actions = 2 self.gamma = 0.99 self.final_epsilon = 0.0001 self.initial_epsilon = 0.1 self.number_of_iterations = 2000000 self.replay_memory_size = 10000 self.minibatch_size = 32 self.conv1 = nn.Conv2d(4, 32, 8, 4) self.relu1 = nn.ReLU(inplace=True) self.conv2 = nn.Conv2d(32, 64, 4, 2) self.relu2 = nn.ReLU(inplace=True) self.conv3 = nn.Conv2d(64, 64, 3, 1) self.relu3 = nn.ReLU(inplace=True) self.fc4 = nn.Linear(3136, 512) self.relu4 = nn.ReLU(inplace=True) self.fc5 = nn.Linear(512, self.number_of_actions) def forward(self, x): out = self.conv1(x) out = self.relu1(out) out = self.conv2(out) out = self.relu2(out) out = self.conv3(out) out = self.relu3(out) out = out.view(out.size()[0], -1) out = self.fc4(out) out = self.relu4(out) out = self.fc5(out) return out
ในตัวสร้าง คุณจะสังเกตเห็นว่ามีไฮเปอร์พารามิเตอร์ที่กำหนดไว้ การเพิ่มประสิทธิภาพไฮเปอร์พารามิเตอร์ไม่ได้ทำเพื่อจุดประสงค์ในการโพสต์บล็อกนี้ ส่วนใหญ่จะใช้ไฮเปอร์พารามิเตอร์จากเอกสารของ DeepMind แทน ในที่นี้ ไฮเปอร์พารามิเตอร์บางตัวได้รับการปรับขนาดให้ต่ำกว่าในบทความของ DeepMind เนื่องจาก Flappy Bird มีความซับซ้อนน้อยกว่าเกม Atari ที่ใช้ในการปรับแต่ง
นอกจากนี้ epsilon ถูกเปลี่ยนให้สมเหตุสมผลมากขึ้นสำหรับเกมนี้ DeepMind ใช้ epsilon หนึ่งตัว แต่ที่นี่เราใช้ 0.1 นี่เป็นเพราะว่าเอปซิลอนที่สูงขึ้นบังคับให้นกกระพือปีกมาก ซึ่งผลักนกไปที่ขอบด้านบนของตะแกรง ส่งผลให้นกชนเข้ากับท่อในที่สุด
รหัสการเรียนรู้การเสริมแรงมีสองโหมด: ฝึกและทดสอบ ในระหว่างขั้นตอนการทดสอบ เราจะเห็นได้ว่าอัลกอริทึมการเรียนรู้แบบเสริมกำลังเรียนรู้การเล่นเกมได้ดีเพียงใด แต่ก่อนอื่น โครงข่ายประสาทเทียมต้องได้รับการฝึกอบรม เราจำเป็นต้องกำหนดฟังก์ชันการสูญเสียที่จะย่อให้เล็กสุดและตัวเพิ่มประสิทธิภาพซึ่งจะลดฟังก์ชันการสูญเสียให้น้อยที่สุด เราจะใช้วิธีการปรับให้เหมาะสมของ Adam และค่าคลาดเคลื่อนกำลังสองเฉลี่ยสำหรับฟังก์ชันการสูญเสีย:
optimizer = optim.Adam(model.parameters(), lr=1e-6) criterion = nn.MSELoss()
เกมควรสร้างอินสแตนซ์:
game_state = GameState()
หน่วยความจำเล่นซ้ำถูกกำหนดเป็นรายการ Python:
replay_memory = []
ตอนนี้เราต้องเริ่มต้นสถานะแรก การกระทำคือเทนเซอร์สองมิติ:
- [1, 0] หมายถึง "ไม่ทำอะไรเลย"
- [0, 1] หมายถึง “บินขึ้นไป”
เมธอด frame_step
จะแสดงหน้าจอถัดไป รางวัล และข้อมูลว่าสถานะถัดไปคือเทอร์มินัลหรือไม่ รางวัลคือ 0.1
สำหรับการเคลื่อนไหวของนกแต่ละตัวโดยไม่ตายเมื่อไม่ผ่านท่อ 1
หากนกผ่านท่อได้สำเร็จและ -1
หากนกตก
ฟังก์ชัน resize_and_bgr2gray
จะครอบตัดพื้น ปรับขนาดหน้าจอเป็นรูปภาพขนาด 84x84 และเปลี่ยนพื้นที่สีจาก BGR เป็นขาวดำ ฟังก์ชัน image_to_tensor
จะแปลงรูปภาพเป็นเมตริกซ์ PyTorch และใส่ไว้ในหน่วยความจำ GPU หากมี CUDA ในที่สุด หน้าจอต่อเนื่องสี่หน้าจอสุดท้ายจะถูกต่อเข้าด้วยกันและพร้อมที่จะส่งไปยังโครงข่ายประสาทเทียม
action = torch.zeros([model.number_of_actions], dtype=torch.float32) action[0] = 1 image_data, reward, terminal = game_state.frame_step(action) image_data = resize_and_bgr2gray(image_data) image_data = image_to_tensor(image_data) state = torch.cat((image_data, image_data, image_data, image_data)).unsqueeze(0)
epsilon เริ่มต้นถูกตั้งค่าโดยใช้บรรทัดของรหัสนี้:
epsilon = model.initial_epsilon
วงอนันต์หลักดังต่อไปนี้ ความคิดเห็นเขียนในโค้ด และคุณสามารถเปรียบเทียบโค้ดกับ Deep Q-learning ด้วยอัลกอริธึม Experience Replay ที่เขียนไว้ด้านบน
อัลกอริทึมจะสุ่มตัวอย่างมินิแบตช์จากหน่วยความจำรีเพลย์และอัปเดตพารามิเตอร์ของโครงข่ายประสาทเทียม การดำเนินการจะดำเนินการโดยใช้ การสำรวจความโลภของเอปซิลอน Epsilon กำลังถูกอบอ่อนเมื่อเวลาผ่านไป ฟังก์ชั่นการสูญเสียที่ถูกย่อเล็กสุดคือ $ L = \frac{1}{2}\left[\max_{a'}Q(s', a') - Q(s, a)\right]^2 $ $ Q(s, a) $ คือค่าความจริงภาคพื้นดินที่คำนวณโดยใช้สมการ Bellman และได้ $ \max_{a'}Q(s', a') $ จากโครงข่ายประสาทเทียม โครงข่ายประสาทเทียมให้ค่า Q สองค่าสำหรับการกระทำที่เป็นไปได้ทั้งสองอย่าง และอัลกอริทึมจะดำเนินการด้วยค่า Q สูงสุด
while iteration < model.number_of_iterations: # get output from the neural network output = model(state)[0] # initialize action action = torch.zeros([model.number_of_actions], dtype=torch.float32) if torch.cuda.is_available(): # put on GPU if CUDA is available action = action.cuda() # epsilon greedy exploration random_action = random.random() <= epsilon if random_action: print("Performed random action!") action_index = [torch.randint(model.number_of_actions, torch.Size([]), dtype=torch.int) if random_action else torch.argmax(output)][0] if torch.cuda.is_available(): # put on GPU if CUDA is available action_index = action_index.cuda() action[action_index] = 1 # get next state and reward image_data_1, reward, terminal = game_state.frame_step(action) image_data_1 = resize_and_bgr2gray(image_data_1) image_data_1 = image_to_tensor(image_data_1) state_1 = torch.cat((state.squeeze(0)[1:, :, :], image_data_1)).unsqueeze(0) action = action.unsqueeze(0) reward = torch.from_numpy(np.array([reward], dtype=np.float32)).unsqueeze(0) # save transition to replay memory replay_memory.append((state, action, reward, state_1, terminal)) # if replay memory is full, remove the oldest transition if len(replay_memory) > model.replay_memory_size: replay_memory.pop(0) # epsilon annealing epsilon = epsilon_decrements[iteration] # sample random minibatch minibatch = random.sample(replay_memory, min(len(replay_memory), model.minibatch_size)) # unpack minibatch state_batch = torch.cat(tuple(d[0] for d in minibatch)) action_batch = torch.cat(tuple(d[1] for d in minibatch)) reward_batch = torch.cat(tuple(d[2] for d in minibatch)) state_1_batch = torch.cat(tuple(d[3] for d in minibatch)) if torch.cuda.is_available(): # put on GPU if CUDA is available state_batch = state_batch.cuda() action_batch = action_batch.cuda() reward_batch = reward_batch.cuda() state_1_batch = state_1_batch.cuda() # get output for the next state output_1_batch = model(state_1_batch) # set y_j to r_j for terminal state, otherwise to r_j + gamma*max(Q) y_batch = torch.cat(tuple(reward_batch[i] if minibatch[i][4] else reward_batch[i] + model.gamma * torch.max(output_1_batch[i]) for i in range(len(minibatch)))) # extract Q-value q_value = torch.sum(model(state_batch) * action_batch, dim=1) # PyTorch accumulates gradients by default, so they need to be reset in each pass optimizer.zero_grad() # returns a new Tensor, detached from the current graph, the result will never require gradient y_batch = y_batch.detach() # calculate loss loss = criterion(q_value, y_batch) # do backward pass loss.backward() optimizer.step() # set state to be state_1 state = state_1
เมื่อชิ้นส่วนทั้งหมดพร้อมแล้ว ต่อไปนี้คือภาพรวมระดับสูงของการไหลของข้อมูลโดยใช้โครงข่ายประสาทเทียมของเรา:
นี่เป็นลำดับสั้นๆ ลำดับหนึ่งที่มีโครงข่ายประสาทเทียมที่ผ่านการฝึกอบรมมาแล้ว
โครงข่ายประสาทเทียมที่แสดงด้านบนได้รับการฝึกฝนโดยใช้ GPU Nvidia GTX 1080 ระดับไฮเอนด์เป็นเวลาสองสามชั่วโมง โดยใช้โซลูชันที่ใช้ CPU แทน งานนี้จะใช้เวลาหลายวัน FPS ของเอ็นจิ้นเกมถูกตั้งค่าเป็นจำนวนมากระหว่างการฝึก: 999…999—กล่าวอีกนัยหนึ่งคือ ให้มากที่สุดเท่าที่จะมากได้ต่อวินาที ในขั้นตอนการทดสอบ FPS ถูกตั้งค่าเป็น 30
ด้านล่างนี้คือแผนภูมิที่แสดงให้เห็นว่าค่า Q สูงสุดเปลี่ยนแปลงไปอย่างไรในระหว่างการทำซ้ำ การแสดงซ้ำทุกๆ 10,000 ครั้ง การพุ่งสูงขึ้นหมายความว่าสำหรับเฟรมใดเฟรมหนึ่ง (การวนซ้ำหนึ่งครั้งเป็นหนึ่งเฟรม) โครงข่ายประสาทเทียมคาดการณ์ว่านกจะได้รับรางวัลที่ต่ำมากในอนาคต กล่าวคือ มันจะพังในไม่ช้า
ดูโค้ดฉบับเต็มและรุ่นก่อนการฝึกอบรมได้ที่นี่
การเรียนรู้การเสริมแรงอย่างล้ำลึก: 2D, 3D และแม้แต่ชีวิตจริง
ในบทช่วยสอนการเรียนรู้การเสริมแรงของ PyTorch นี้ ฉันแสดงให้เห็นว่าคอมพิวเตอร์สามารถเรียนรู้การเล่น Flappy Bird ได้อย่างไรโดยปราศจากความรู้ใดๆ เกี่ยวกับเกมมาก่อน โดยใช้เพียงวิธีการทดลองและข้อผิดพลาดที่มนุษย์จะทำเมื่อพบกับเกมเป็นครั้งแรก
เป็นเรื่องที่น่าสนใจที่อัลกอริธึมสามารถใช้งานได้ในโค้ดสองสามบรรทัดโดยใช้เฟรมเวิร์ก PyTorch กระดาษที่ใช้วิธีการในบล็อกนี้ค่อนข้างเก่า และมีเอกสารใหม่จำนวนมากที่มีการดัดแปลงต่างๆ ซึ่งช่วยให้เกิดการบรรจบกันได้เร็วขึ้น ตั้งแต่นั้นมา การเรียนรู้การเสริมแรงเชิงลึกได้ถูกนำมาใช้ในการเล่นเกม 3 มิติและในระบบหุ่นยนต์ในโลกแห่งความเป็นจริง
บริษัทต่างๆ เช่น DeepMind, Maluuba และ Vicarious กำลังทำงานอย่างเข้มข้นในการเรียนรู้การเสริมกำลังเชิงลึก เทคโนโลยีดังกล่าวถูกใช้ใน AlphaGo ซึ่งเอาชนะ Lee Sedol หนึ่งในผู้เล่นที่ดีที่สุดในโลกที่ Go ในขณะนั้นถือว่าต้องใช้เวลาอย่างน้อยสิบปีกว่าที่เครื่องจักรจะสามารถเอาชนะผู้เล่นที่ดีที่สุดของโกได้
ความสนใจและการลงทุนจำนวนมากในการเรียนรู้การเสริมแรงเชิงลึก (และโดยทั่วไปในปัญญาประดิษฐ์) อาจนำไปสู่ปัญญาประดิษฐ์ ทั่วไป ที่อาจเกิดขึ้น (AGI)—ปัญญาระดับมนุษย์ (หรือมากกว่านั้น) ที่สามารถแสดงออกได้ในรูปแบบของอัลกอริธึมและ จำลองบนคอมพิวเตอร์ แต่ AGI จะต้องเป็นหัวข้อของบทความอื่น
ข้อมูลอ้างอิง:
- ตอกย้ำการเรียนรู้การเสริมแรงอย่างลึกซึ้ง
- การเรียนรู้การเสริมแรงอย่างล้ำลึกสำหรับ Flappy Bird
- “โครงข่ายประสาทเทียม” ที่วิกิพีเดีย
- “การเรียนรู้การเสริมกำลัง” ที่ Wikipedia
- “กระบวนการตัดสินใจของ Markov” ที่ Wikipedia
- หลักสูตร University College London ในRL