Reinforcement Learning แบบบ้าน ๆ ตอนที่ 1 — สร้าง Agent สำหรับเล่นเกมส์ Tic-Tac-Toe ด้วย Epsilon-Greedy Algorithm กับ Value Function แบบง่าย ๆ

Pisut Oncharoen
botnoi-classroom
Published in
8 min readDec 5, 2019

สวัสดีครับ ช่วงนี้ผมกำลังพยายามศึกษาด้าน Reinforcement Learning (RL) เลยคิดว่าจะเขียนบทความเพื่อสรุป สิ่งที่ผมได้เรียนรู้มา เพื่อเก็บไว้อ่าน และ แชร์ให้กับคนที่กำลังสนใจศาสตร์ในด้านนี้ครับ

https://dimensionless.in/reinforcement-learning-super-mario-alphago/

What is Reinforcement Learning?

Reinforcement Learning หรือ RL เป็น ด้านหนึ่งของศาสตร์ด้าน Artificial Intelligence (AI) ที่ใช้สำหรับสร้าง agent (หรือ robot) ให้สามารถตัดสินใจ ภายใต้สถานการณ์ต่าง ๆ เพื่อให้ได้ผลลัพธ์ที่ดีสุด โดยที่ agent เหล่านี้จะเรียนรู้วิธีการตัดสินใจ ผ่านกระบวนการทดลอง ลองผิดลองถูก และเรียนรู้ไปเรื่อย ๆ ซึ่งวิธีการดังกล่าว ก็คล้ายคลึงกับวิธีการเรียนของมนุษย์ นั่นเองครับ

ตัวอย่างของการนำเอา Reinforcement Learning มาใช้ได้แก่

  • AlphaGo : AI ที่เอาชนะแชมป์ Go ของโลกได้ในปี 2016
  • OpenAI Five : AI ที่เล่นเกมส์ Dota 2 แบบ 5 vs 5 ในปี 2018
  • Hide and Seek : AI ที่สามารถเรียนรู้เทคนิคใหม่ ๆ จากการเล่นซ่อนหา
Hide and Seek : https://www.youtube.com/watch?v=Lu56xVlZ40M

Terminology

ผมของพูดถึงคำศัพท์ที่ใช้บ่อยใน ด้าน RL เพื่อให้ผู้อ่านสามารถเข้าใจได้ตรงกัน และอ่านบทความนี้ได้เข้าใจง่ายขึ้นนะครับ

https://www.inovex.de/blog/reinforcement-learning-walkthrough-introduction/

Agent :

ตัว AI ที่ทำหน้าที่ตัดสินใจเลือกการกระทำ(action) จากสถานการณ์ (state) ปัจจุบัน เพื่อให้บรรลุเป้าหมายและได้รับรางวัล (reward) ที่มากที่สุด

State :

คือ สถานะ หรือ สภาวะของระบบ ซึ่งเป็นผลจากการกระทำ (action) ของ agent โดยที่ state จะถูกสร้างจาก ระบบ หรือ สภาพแวดล้อมภายนอก (environment)

Action:

การกระทำ ต่าง ๆ ที่ agent สามารถทำได้ในแต่ละสถานการณ์ (state)

Environment :

เป็นระบบ หรือ สภาพแวดล้อมภายนอก ที่คอยรับ action จาก agent หลังจากนั้นจึง ส่งค่ารางวัลที่ได้ (reward) จาก action นั้น ๆ รวมทั้งค่า state ถัดไปที่จะเกิดขึ้น กลับไปยัง agent

Reward :

รางวัล ที่ได้จาก action ที่เกิดขึ้นในแต่ละ state โดยที่เป้าหมายของการสร้าง agent ของเรา คือ การสร้าง agent ที่สามารถตัดสินใจเลือก action เพื่อให้บรรลุเป้าหมายและได้รับ รางวัลสูงที่สุด

Episode :

คือ 1 รอบที่ทำการเล่นจนจบเกมส์ หรือ จบการจำลองต่าง ๆ (เริ่มจาก initial state ไปยัง terminal state) ซึ่งในการสร้าง RL agent นั้น เราจะทำการจำลองหลาย ๆ รอบ (episode) เพื่อให้ agent สามารถเรียนรู้ที่จะเลือก action ที่เหมาะสมได้

Learning Process

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

ซึ่งเราสามารถนำแนวคิดนี้ไปสร้าง agent เพื่อใช้ตัดสินใจต่าง ๆ จากประสบการณ์ของ agent ได้เหมือนกันครับ

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

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

Epsilon-Greedy Algorithm

เราสามารถเลียนแบบวิธีคิดของมนุษย์ แล้วนำไปสร้าง agent ที่สามารถเลือกเล่นสล็อตแมชชีน โดยใช้ Pythonได้ตามขั้นตอนดังต่อไปนี้

Multi-Armed RL Agent

Step 1 : สร้าง object ที่เป็นตัวแทนของสล็อตแมชชีน ซึ่งใน object นี้จะมี method อยู่ 2 อย่าง คือ

  • observe : คือ การเล่นสล็อตแมชชีน โดยที่ จะ return ค่าเป็น ได้รางวัล (1) และไม่ได้รางวัล (0) ซึ่งจะเกิดขึ้นตามค่าอัตราการได้รางวัลในแต่ละเครื่อง (true_prob)
  • update : คือ การปรับค่า/เรียนรู้ ตามประสบการณ์ที่เกิดขึ้น โดยจะทำการปรับปรุงค่าประมาณของอัตราการได้รางวัล (est_prob)
ตัวอย่าง code ของ object machine

Step 2 : สร้างเป็น function เพื่อจำลองการเล่นสล็อตแมชชีน โดยมีขั้นตอน หลัก ๆดังต่อไปนี้

  • สร้าง list ที่ใช้เก็บ machine object ซึ่งแต่ละตัวจะมีค่าอัตราการได้รางวัลที่แตกต่างกัน
  • ทำการ วน loop จำนวน N ครั้ง (episode) เพื่อจำลองการเล่นสล็อตแมชชีน โดยแต่ละรอบจะทำการสุ่มเลขมากจาก uniform distribution [0, 1) แล้วนำไปเปรียบเทียบกับค่า epsilon หากได้ค่าน้อยกว่า ก็ทำสุ่มเลือกสล็อตแมชชีนจาก list แต่ถ้าได้ค่ามากกว่า ให้เลือกสล็อตแมชชีน ที่มีค่าประมาณของอัตราการได้รางวัลสูงที่สุด (est_prob)

ขั้นตอนเหล่านี้ ก็คือ Epsilon-Greedy Algorithm นั่นเองครับ

  • หลังจากนั้นก็ทำการเล่นสล็อตแมชชีนตัวที่เลือก (observe) แล้วนำผลลัพธ์ที่ได้ไปปรับค่าประมาณการณ์อัตราการได้รางวัล (update)
  • ซึ่งในแต่ละรอบที่ทำการจำลองการเล่นสล็อตแมชชีน ก็จะต้องมีการปรับค่า epsilon ให้ค่อย ๆ ลดลง เพราะว่า ในช่วงแรกของการจำลองเราอยากให้มีการสุ่มเกิดขึ้นบ่อย ๆ เพื่อเก็บสถิติอัตราการได้รางวัล (est_prob) หลังจากนั้น เมื่อเรามีมูลสถิติที่มากพอ เราก็ไม่อยากเลือกเล่นโดยการสุ่มแล้ว แต่อยากจะเลือกเล่นเฉพาะเครื่องสล็อตแมชชีนที่มีอัตราการได้รางวัลสูงที่สุด (est_prob) เท่านั้น
ตัวอย่างการ run experiment โดยใช้ epsilon greedy algorithm

Step 3 : ในตัวอย่างนี้ จะทดสอบ run experiment จำนวน 100,000 episodes (N) โดยกำหนดให้มีสล็อตแมชชีนจำนวน 4 เครื่อง ซึ่งแต่ละเครื่องมีอัตราการได้รางวัล (true_prob) เป็น 1%, 3%, 5% และ 10% ตามลำดับ หลังจากนั้นจึงนำผลการเลือกเล่นสล็อตแมชชีน ทั้งหมดมาพล๊อตเป็นกราฟด้านล่าง ซึ่งเราก็จะเห็นได้อย่างชัดเจนว่าตั้งแต่ episode 10,000 ขึ้นไป สล็อตแมชชีนที่มีอัตราการได้รางวัลสูงที่สุด (เครื่องที่ 4) จะถูกเลือกบ่อยขึ้น (cumulative average ของสล็อตแมชชีนที่ถูกเลือก มีค่าเข้าใกล้ เครื่องที่ 4 มากขึ้น)

ผลการทดลองที่ได้

หวังว่า ผู้อ่านจะเห็นภาพของการใช้ epsilon greedy algorithm มากขึ้น จากตัวอย่างข้างต้น ซึ่ง algorithm นี้เป็นพื้นฐานที่สำคัญ และถูกนำไปประยุกต์ใช้ร่วมกับ RL algorithm อื่น ๆ อีกด้วย

Value Function

การสร้าง agent ให้สามารถตัดสินใจเลือก action ต่าง ๆ ได้นั้น เราจะต้องกำหนดค่า function อะไรบางอย่างเพื่อให้ agent สามารถเลือกตัดสินใจได้ จากตัวอย่างการเลือกสล็อตแมชชีน เราได้กำหนดให้ agent ทำการเลือกเล่นสล็อตแมชชีน โดยตัดสินใจจาก ค่าประมาณของอัตราการได้รางวัล (est_prob) เป็นต้น

หากเราต้องการสร้าง agent ที่ซับซ้อนมากขึ้นล่ะ? เราจะต้องใช้ function แบบไหนในการตัดสินใจเลือก action ? แล้ว function ที่ใช้ควรจะมีคุณสมบัติอะไรบ้าง?

เพื่อตอบคำถามเหล่านี้ ผมขอยกตัวอย่างการตัดสินใจของมนุษย์อีกครั้ง

สมมุติว่า ผมเป็นนักศึกษาที่มีเป้าหมายว่าอยากจะได้งานดี ๆ หลังจากที่เรียนจบ แล้วพรุ่งนี้มีสอบ แต่ผมมีเพื่อนอีกกลุ่มซึ่งสอบเสร็จแล้ว และได้ชวนผมไปเลี้ยงฉลองสอบเสร็จในคืนนี้ ผมจึงมีทางเลือก 2 ทาง ที่จะต้องตัดสินใจ คือ ไปฉลองกับเพื่อน หรือ อ่านหนังสือเพื่อเตรียมตัวสอบ ดังนั้น ทางเลือกที่เหมาะสมที่สุดของผม ก็คือ การอ่านหนังสือเพื่อเตรียมตัวสอบในวันพรุ่งนี้ เพราะผมเชื่อว่า หากเรียนจบด้วยเกรดดี ๆ น่าจะช่วยให้งานที่ดี ๆ ได้ง่ายขึ้น

หากเราต้องการนำแนวคิดการตัดสินใจของมนุษย์ข้างต้น มาสร้าง function เพื่อให้ agent สามารถเลือกตัดสินใจได้อย่างเหมาะสม เราก็ควรจะเลือกใช้ function ที่สามารถวัดความสัมพันธ์ของการเลือกตัดสินใจ เทียบกับเป้าหมายของ agent ด้วย ซึ่งในด้าน RL จะเรียกสิ่งเหล่านี้ว่า value function และสามารถแบ่งย่อยออกได้เป็น 2 ประเภทดังนี้

State value function, V(S)

State-action value function, Q(S, A)

ในบทความนี้ผมจะยกตัวอย่าง V(S) แบบง่ายๆ เพื่อใช้สร้าง agent สำหรับเล่นเกมส์โอเอกซ์ (tic-tac-toe) เท่านั้น สำหรับรายละเอียดลึก ๆ ของ V(S) และ Q(S, A) จะขอเก็บไว้อธิบายใน บทความถัด ๆ ไป นะครับ

Tic-Tac-Toe : Overview

เพื่อให้เห็นภาพของ RL ผมจะยกตัวอย่างการสร้าง agent เพื่อเล่นเกมส์ tic-tac-toe หรือ โอเอ็กซ์ ที่หลาย ๆ คนคุ้นเคยกันดี นะครับ

เกมส์ โอเอ็กซ์ (tic-tac-toe)

การสร้างจะเทรน agent เพื่อใช้เล่นเกมส์ tic-tac-toe ได้นั้น เราจะต้องสร้าง object ที่ใช้ แทน environment (ตาราง 3x3) และ agent ซึ่งสามารถตัดสินใจเลือกตำแหน่งการเล่นได้ตาม value function หรือ V(S) หลังจากนั้น จึงจำลองการเล่นเกมส์ระหว่าง agent หลาย ๆ รอบ (episode) เพื่อเรียนรู้ V(S) ที่ใช้ตัดสินใจเลือก action ต่าง ๆ

สำหรับในแต่ละรอบที่จำลองการเล่นเกมส์ agent แต่ละตัวจะใช้ epsilon greedy algorithm ในการเลือกตำแหน่งที่จะเล่น (สุ่ม หรือ เลือกตาม value function) ซึ่ง agent เหล่านี้จะสลับกันเล่นไปเรื่อย ๆ จนกระทั่งจบเกมส์ (มีผู้ชนะ หรือ เต็มตาราง 3x3) ซึ่งในระหว่างที่กำลังเล่นนั้น จะต้องเก็บค่า state ที่กำลังเกิดขึ้นด้วย และหลังจากที่จบเกมส์ ก็จะต้องนำลำดับของ state ที่เกิดขึ้นไปอัพเดทค่า value function

เราสามารถจำลองการเล่นหลาย ๆ รอบ (episode)เพื่อให้ agent ทั้งสองตัว สามารถเรียนรู้ value function ที่ใช้สำหรับตัดสินใจเลือก action ในการเล่นที่ดีที่สุดได้ครับ

นี่คือ ภาพรวมของการใช้ RL ในการสร้าง agent สำหรับเล่นเกมส์ tic-tac-toe ครับ

ตัวอย่าง Python code สำหรับจำลองการเล่นเกมส์

Tic-Tac-Toe : Value Function, V(S)

ขั้นตอนแรกของการสร้าง agent เพื่อเล่นเกมส์นั้น เราจะต้องกำหนดค่าของ V(S) เริ่มต้น เพื่อให้ agent สามารถเลือกตัดสินใจตามค่า V(S) หลังจากนั้นจึงค่อย ๆ ปรับค่าของ V(S) ผ่านการจำลองการเล่นซ้ำ หลาย ๆ ครั้ง เพื่อให้ได้ V(S) ที่สามารถนำมาใช้ตัดสินใจเลือก action ได้อย่างเหมาะสม

สำหรับ V(S) เริ่มต้นนั้น เราอาจจะกำหนดได้ดังนี้

V(S) = 1 ถ้า ชนะ

V(S) = 0 ถ้า แพ้ หรือ เสมอ

V(S) = 0.5 กรณีอื่น ๆ

หรือเราอาจจะมองว่า V(S) ในแต่ละ state คือโอกาสที่จะชนะ (probability)ก็ได้เหมือนกันครับ และเป้าหมายของเรา ก็คือ การสอนให้ agent รู้จักที่จะประเมิน โอกาสการชนะ หากเลือก action ต่าง ๆ ผ่าน V(S) นั่นเองครับ

ถ้าเราเอาแนวคิดว่า V(S) คือ อัตราการชนะ ในแต่ละ state มาใช้ หมายความว่า ค่า V(S) ในช่วงต้นเกมส์ ควรจะมีความน่าเชื่อถือน้อยกว่า V(S) ในช่วงท้ายเกมส์ ที่สามารถประเมินผู้ชนะได้ง่ายกว่า ดังนั้น การปรับค่า V(S) จึงควรจะปรับค่าไล่จาก terminal state กลับมายัง initial state ซึ่งสามารถทำได้โดยสมการด้านล่างครับ

โดยที่ S(t) = current state, S(t+1) = next state และ alpha = learning rate

เพื่อให้เห็นภาพการปรับค่า V(S) ผมจะจำลองการเล่นเกมส์มา 1 รอบดังนี้

เราสามารถไล่ปรับค่า V(S) ในแต่ละ state โดยใช้ค่า learning rate = 0.5 ได้ดังนี้

ตัวอย่างการปรับ V(S) จากลำดับของ state ที่เกิดขึ้น

สำหรับการเทรน RL agent นั้น เราจะค่อย ๆ ปรับค่า V(S) จากเล่นในแต่ละรอบ แล้วนำค่า V(S) ใหม่ที่ได้ ไปใช้ในการจำลองการเล่นในรอบถัด ๆ ไป ซึ่งสุดท้ายแล้ว เมื่อเราจำลองการเล่นไปหลาย ๆ รอบ (episode) ค่า V(S) ที่ได้ก็จะมีค่าแม่นยำมากขึ้น

นี่คือ วิธีการ สร้าง agent ที่สามารถประเมินโอกาสในการชนะ จาก action ต่าง ๆ ผ่าน V(S) นั่นเองครับ

Tic-Tac-Toe : State Representation

การจะสร้าง V(S) ได้นั้น เราจะต้องรู้จำนวน state ที่เป็นไปได้ทั้งหมด ซึ่งในกรณีนี้ คือ ตราราง 3x3 และมีค่าที่เป็นไปได้ในแต่ละช่อง จำนวน 3 ค่า (O, X, empty) ดังนั้นจำนวน state ที่เป็นไปได้ทั้งหมด คือ 3⁹ = 19,683

นอกจากนี้ เราจะต้องหาวิธีแปลงตาราง 3x3 และค่าในแต่ละช่อง ให้เป็นตัวเลขเพื่อให้สามารถสร้างเป็น Python Dictionary ที่สามารถ map ระหว่าง state กับ value function ได้ ตัวอย่าง เช่น

กำหนดให้ที่ว่าง คือ 0, X คือ 1 และ O คือ 2

หรือเราสามารถมองชุดของตัวเลข 0, 1, 2 ข้างต้น เป็นตัวเลขฐาน 3 และทำการแปลงให้เป็นตัวเลขฐาน 10 เพื่อประหยัดหน่วยความจำและสามารถเแปลงเป็น ตำแหน่ง (index) ของค่า ใน value array ขนาด 19,683 ได้

สำหรับวิธีการแปลงเลขฐาน 3 เป็น ฐาน 10 นั้น เราสามารถทำคล้าย ๆ กับการแปลงฐาน 2 เป็นฐาน 10 ตามรูปตัวอย่างข้างล่าง แต่เปลี่ยนเป็นใช้เลข 3 ยกกำลังแทน

https://www.rapidtables.com/convert/number/binary-to-decimal.html

ซึ่งเราสามารถเขียน function ที่ใช้แปลงค่าต่าง ๆ ในตาราง 3x3 เป็นตัวเลขที่ใช้แทน state ได้ตาม code ตัวอย่าง ด้านล่างครับ

ตัวอย่าง function ที่ใช้แปลงค่าในตาราง 3x3 ให้เป็นตัวเลขฐาน 10

Tic-Tac-Toe : Environment

หลังจากที่ได้เห็นภาพรวมของการจำลองการเล่นเกมส์ แนวคิดการค่าปรับค่า V(S) และการแปลงตาราง 3x3 ให้เป็นตัวเลข เพื่อใช้แทน state แล้ว สิ่งถัดมาที่ผมจะอธิบายคือ environment หรือ object ที่ใช้แทนตางราง 3x3 นั่นเองครับ

โดยที่ใน object นี้จะต้องมี method ดังต่อไปนี้

  • __init__ : ประกาศค่าเริ่มต้น เพื่อเก็บค่าต่าง ๆ เช่น ค่าในตาราง 3x3 , ผู้ชนะ , ..
  • is_empty : ตรวจสอบว่า สามารถเล่น (ใส่ค่า X, O) ในช่อง (i, j) ได้รึเปล่า
  • get_state : เพื่อแปลง ตาราง 3x3 ในขณะนั้น ให้เป็นตัวเลขแทน state
  • get_reward : เพื่อ return ค่า reward ที่ได้ในแต่ละ state
  • is_game_over : ตรวจสอบว่าจบเกมส์แล้วหรือไม่ (มีผู้ชนะ หรือ เสมอ)
  • print_board : เพื่อใช้แสดงตาราง ในกรณีที่เราต้องการเล่นแข่งกับ agent
method ที่ต้องมีใน Environment

Tic-Tac-Toe : Agent

สิ่งสุดท้ายที่ขาดไม่ได้สำหรับงานนี้คือ object ที่ใช้แทน agent ครับ โดยที่เป้าหมายของการทำ RL ของเราก็คือ การพยายามสอนให้ agent สามารถเล่นเกมส์ได้ โดยการตัดสินใจเลือก action ที่เหมาะสมที่สุด จาก V(S)

ดังนั้น object นี้ควรจะต้องมี method ดังต่อไปนี้

  • __init__ : ประกาศค่าเริ่มต้น เพื่อเก็บค่าต่าง ๆ เช่น epsilon, learning rate, ..
  • set_print_value_fn : เพื่อแสดง ค่า value function ของแต่ละช่องในตาราง
  • set_eps : เพื่อใช้ปรับค่า epsilon ของ epsilon greedy algorithm
  • set_value_fn : เพื่อกำหนดค่า value function, V(S)
  • set_symbol : เพื่อกำหนดค่า ว่า agent ตัวนี้แทน X หรือ O
  • update_winner_hist : เพื่อเก็บสถิติการเล่น
  • update_state_hist : เพื่อเก็บลำดับของ state ที่เกิดขึ้นในแต่ละรอบ
  • reset_state_hist : เพื่อลบค่า ลำดับของ state ที่เกิดขึ้นในกรณีที่เล่นรอบใหม่
  • update_value_fn : ปรับค่า V(S) โดยใช้วิธีการที่ได้อธิบายในหัวข้อก่อนหน้า
  • take_action : เลือก action โดยใช้ V(S) ร่วมกับ epsilon greedy algorithm
method ที่ต้องมีใน Agent

RL agent เราสร้างขึ้นมา จะใช้ epsilon greedy algorithm เพื่อใช้ในการเลือกว่า จะ take action (ตำแหน่งที่จะเล่น) แบบสุ่ม หรือ เลือกโดยใช้ V(S) ที่ได้เรียนรู้มาครับ แต่อย่างไรก็ตาม เราจะใช้ epsilon greedy algorithm เฉพาะตอนที่ จำลองการเล่นระหว่าง agent เท่านั้น ตอนที่เราเอาไปใช้จริง (เอาไปเล่นแข่งกับคน) ทุก ๆ action จะถูกเลือกโดย V(S) ที่ได้เรียนรู้จากการจำลองการเล่นระหว่าง agent ครับ

ผู้อ่านสามามารถดูตัวอย่าง code ของ method take_action ที่มีการใช้ epsilon greed algorithm เพื่อเลือก action ได้จากภาพด้านล่างครับ

ตัวอย่าง method take_action

Training Process

ภาพรวมของการเทรนโมเดล RL เพื่อใช้เล่นเกมส์ tic-tac-toe มีดังนี้

  • Step 1 : สร้าง agent 2 ตัว และ environment สำหรับ จำลองการเล่นเกมส์
  • Step 2 : หา state ที่เป็นไปได้ทั้งหมด คำนวณหาผู้ชนะ กับ terminal state
  • Step 3 : กำหนดค่าเริ่มต้น ของ V(S) โดยใช้ข้อมูล state จาก step ก่อนหน้า
  • Step 4 : กำหนดค่า V(S) และ symbol ไปยัง agent แต่ละตัว
  • Step 5 : ทำการจำลองการเล่นหลาย ๆ ครั้ง (episode) เพื่อค่อยๆ ปรับค่า V(S)
ตัวอย่าง code การเทรน agent

Result

คราวนี้เราลองมาดูค่าสถิติ ที่ได้ในระหว่างการจำลองการเล่นระหว่าง agent นะครับ จากค่า อัตราการชนะสะสม (cumulative win rate) ของ agent ทั้ง 2 ตัวที่แสดงในรูปล่าง เราจะเห็นได้ว่า ช่วงแรก agent1 จะมีอัตราการชนะสะสม ที่สูงกว่า หลังจากนั้น เมื่อทำการจำลองการเล่นเกมส์ไปประมาณ 10 รอบ agent2 จะเริ่มเรียนรู้ V(S) ที่เหมาะสมมากขึ้น และ agent ทั้ง 2 ตัวก็ค่อย ๆ สลับกันแพ้/ชนะ ไปเรื่อย ๆ จนกระทั้ง หลังจากที่จำลองการเล่นได้ ประมาน 100 รอบ agent1 จะเริ่ม เรียนรู้ V(S) ที่ถูกต้องมากขึ้น จนสามารถเอาชนะ agent2 ได้มากขึ้นเรื่อย ๆ ส่งผลให้อัตราการชนะสะสมกลับมาสูงขึ้นอีกครั้งครับ

ผลการทดลองที่ได้

จากผลการทดลองนี้ เราสามารถตีความได้อีกอย่างว่า ในเกมส์ tic-tac-toe ผู้เล่นที่เริ่มเล่นก่อน (agent1) มักจะได้เปรียบมากกว่า ผู้เล่นที่เริ่มเล่นหลัง (agent2) ดังนั้นเมื่อ agent1 ได้เล่นเกมส์จำนวนหลาย ๆ ครั้ง ก็จะสามารถเรียนรู้ที่จะเลือก action ที่ได้เปรียบ จนทำให้ สามารถชนะได้อย่างต่อเนื่องนั่นเองครับ

Demo : RL Agent (X) vs Human (O)

เมื่อเราได้ RL agent ที่ผ่านการเทรน มาแล้ว เราจะลองมาเล่นเกมส์แข่งกับ agent ดูครับ ในที่นี้ ผมจะลองแข่งกับ agent1 เนื่องจากเป็น agent ที่มีอัตราการชนะสูงกว่า

Step1 : ผมลอง print ค่า value function ของ agent1 ออกมาดูตามรูปด้านล่าง จะเห็นได้ว่า ค่า V(S) ตรงมุม ซ้ายบนจะสูงที่สุด ดังนั้น agent1 จะเลือก ตรงนี้

Step 1

Step2 : พอผมเลือกเล่นตรงกลาง agent1 ก็จะคำนวณ V(S) ของช่องที่เหลือ แล้วก็จะได้ว่า ถ้าเลือกเล่นตรงมุมขวาล่าง จะมีโอกาสชนะสูงถึง 92% และ agent1 จะเลือกเล่นที่ตำแหน่งนั้น

Step 2

Step3 : คราวนี้ พอผมเลือกเดินที่แถวล่างช่องกลาง เพื่อให้ได้เรียงกัน 2 ตำแหน่งซึ่ง ผมอยากรู้ว่า agent1 จะสามารถรู้ว่า ต้องเดินเพื่อ block ไม่ให้ผมชนะได้รึเปล่า ผลที่ได้ คือ ค่า V(S) ของตำแหน่งที่จะทำให้ผมชนะ จะสูงกว่าตำแหน่งอื่น ๆ ซึ่งก็ทำให้ agent1 เลือกเดินไป block ตำแหน่งนั้นได้ สำเร็จครับ

Step 3

Step4 : หลังจากนั้น ผมก็เลือกเดินเพื่อ block ไม่ให้ agent1 ชนะ คราวนี้เรามาลองดู V(S) ในแต่ละตำแหน่งครับ ปรากฏว่า ค่าของ V(S) ในตำแหน่งนี่จะ block ไม่ให้ผมชนะ ก็ยังคงสูงที่สุดเหมือนเดิม ดังนั้น agent1 ก็จะเลือกเดินไปยังตำแหน่งนั้น เพื่อ block ไม่ให้ผมชนะ แต่จุดที่อยากให้ผู้อ่านได้สังเกต คือ V(S) ครับ

จากที่ได้ยกตัวอย่างไปในหัวข้อก่อนหน้า ว่า เราสามารถมอง V(S) ได้เป็น โอกาสการชนะ หากเลือก take action ในตำแหน่งนั้น ๆ เราจะเห็นได้ว่า ถ้า agent กำลังเจอกับ state ที่ชนะได้ยาก ค่า V(S) น้อยลงอย่างเห็นได้ชัด

Step 4

Step5 : คราวนี้ผมลองเลือกเดินตำแหน่งที่ผมจะต้องแพ้แน่นอน เพื่อดูว่า V(S) ของ agent1 เป็นอย่างไรบ้าง ก็จะเห็นได้ว่า V(S) ก็จะกลับมาสูงอีกครั้ง และ agent1 ก็จะเลือกเล่นที่ตำแหน่งนั้น เพื่อให้ชนะเกมส์ได้ครับ

Step 5

เป็นไงกันบ้างครับ หวังว่าผู้อ่านจะได้เห็นภาพของ RL มากขึ้น ผ่านตัวอย่าง ง่าย ๆ ที่ประยุกต์ใช้ RL ในการสร้าง agent สำหรับเล่นเกมส์ tic-tac-toe

ผมได้แชร์ code ทั้งหมดไว้ที่ link นี้ นะครับ ใครที่สนใจสามารถลองเอาไปเทรน agent แล้วลองเล่นเกมส์แข่งกับ agent ที่ได้เลยครับ

Disclaimer

บทความนี้เหมาะสำหรับการศึกษาแนวคิดเบื้องต้นของ RL เท่านั้น เนื่องผู้เขียนได้เขียนตามความเข้าใจของตนเองที่ได้ศึกษามา อาจจะมีข้อผิดพลาดอยู่บ้าง ดังนั้นจึงไม่เหมาะสำหรับการนำไปใช้เป็นแหล่งอ้างอิงทางวิชา หากผู้อ่านท่านในเจอข้อผิดพลาดหรือมีข้อเสนอแนะกรุณา comment ได้ที่ด้านล่างนะครับ

References

— — — — — — — — — — — — — — — — — — — — — — — —

สนใจเรียน Data science -> Botnoi Classroom

สนใจใช้บริการในสร้างแชทบอท หรือให้คำปรึกษาเกี่ยวกับ AI & data science ติดต่อได้ผ่านเวป -> Botnoi และ FB Page Botnoi Consulting

--

--