1. ก่อนเริ่มต้น
ความสำเร็จที่น่าทึ่งของ AlphaGo และ AlphaStar แสดงให้เห็นถึงศักยภาพของการใช้แมชชีนเลิร์นนิงในการสร้างตัวแทนเกมระดับยอดมนุษย์ การสร้างเกมขนาดเล็กที่ขับเคลื่อนด้วย ML เป็นแบบฝึกหัดที่สนุกสนาน เพื่อหาทักษะที่จำเป็นในการสร้างตัวแทนเกมที่ทรงพลัง
ใน Codelab นี้ คุณจะได้เรียนรู้วิธีสร้างเกมกระดานโดยใช้สิ่งต่อไปนี้
- TensorFlow Agent เพื่อฝึก Agent เกมด้วยการเรียนรู้แบบเสริม
- การแสดง TensorFlow เพื่อให้บริการโมเดล
- Flutter พัฒนาแอปเกมกระดานข้ามแพลตฟอร์ม
ข้อกำหนดเบื้องต้น
- ความรู้พื้นฐานเกี่ยวกับการพัฒนา Flutter ด้วย Dart
- ความรู้พื้นฐานเกี่ยวกับแมชชีนเลิร์นนิงด้วย TensorFlow เช่น การฝึกและการติดตั้งใช้งาน
- ความรู้พื้นฐานเกี่ยวกับ Python, เทอร์มินัล และ Docker
สิ่งที่คุณจะได้เรียนรู้
- วิธีฝึก Agent ตัวละครที่ไม่ใช่ผู้เล่น (NPC) โดยใช้ Agent ของ TensorFlow
- วิธีให้บริการโมเดลที่ผ่านการฝึกโดยใช้ TensorFlow ในปัจจุบัน
- วิธีสร้างเกมกระดาน Flutter แบบข้ามแพลตฟอร์ม
สิ่งที่ต้องมี
- Flutter SDK
- การตั้งค่า Android และ iOS สำหรับ Flutter
- การตั้งค่าเดสก์ท็อปสำหรับ Flutter
- การตั้งค่าเว็บสำหรับ Flutter
- การตั้งค่าโค้ด Visual Studio (VS Code) สำหรับ Flutter และ Dart
- Docker
- แบช
- Python 3.7 ขึ้นไป
2. เกมยิงเครื่องบิน
เกมที่คุณสร้างใน Codelab นี้มีชื่อว่า "Plane Strike" ซึ่งเป็นเกมกระดานที่มีผู้เล่น 2 คน ซึ่งคล้ายกับเกมกระดานของ "Battleship" กฎนั้นง่ายมาก:
- ผู้เล่นที่เป็นมนุษย์เล่นกับตัวแทน NPC ที่ฝึกโดยแมชชีนเลิร์นนิง ผู้เล่นที่เป็นมนุษย์สามารถเริ่มเกมได้โดยแตะเซลล์ใดก็ได้ในกระดานของตัวแทน
- ในช่วงต้นเกม ผู้เล่นที่เป็นมนุษย์และตัวแทนแต่ละคนจะมี "เครื่องบิน" (เซลล์สีเขียว 8 เซลล์ที่ก่อเป็น "ระนาบ" ตามที่คุณเห็นบนกระดานของผู้เล่นในภาพเคลื่อนไหวด้านล่าง) บนกระดานของตนเอง "เครื่องบิน" เหล่านี้ ถูกสุ่มเลือกและมีเฉพาะเจ้าของกระดานเท่านั้นที่จะเห็นและซ่อนไว้ไม่ให้คู่ต่อสู้เห็น
- ผู้เล่นที่เป็นมนุษย์และตัวแทนจะผลัดกันไปตีกันที่กระดานของกันและกัน ผู้เล่นที่เป็นมนุษย์จะแตะเซลล์ใดก็ได้ในกระดานของตัวแทน ขณะที่ตัวแทนจะเลือกโดยอัตโนมัติโดยอิงตามการคาดการณ์ของโมเดลแมชชีนเลิร์นนิง เซลล์ที่ต้องการจะเปลี่ยนเป็นสีแดงถ้าเป็น "เครื่องบิน" cell (‘hit'); ไม่เช่นนั้นก็จะเปลี่ยนเป็นสีเหลือง ("หายไป")
- ผู้ที่ได้เซลล์สีแดง 8 เซลล์ก่อนจะเป็นผู้ชนะ เกมจะรีสตาร์ทด้วยกระดานใหม่
ตัวอย่างเกมเพลย์ของเกม
3. ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ Flutter
สำหรับการพัฒนาซอฟต์แวร์ Flutter คุณต้องมีซอฟต์แวร์ 2 ส่วนเพื่อดำเนินการ Codelab ให้เสร็จสมบูรณ์ ได้แก่ Flutter SDK และเครื่องมือแก้ไข
คุณเรียกใช้ Codelab ได้โดยใช้อุปกรณ์ต่อไปนี้
- เครื่องมือจำลอง iOS (ต้องติดตั้งเครื่องมือ Xcode)
- โปรแกรมจำลอง Android (ต้องตั้งค่าใน Android Studio)
- เบราว์เซอร์ (การแก้ไขข้อบกพร่องต้องใช้ Chrome)
- เป็นแอปพลิเคชัน Windows, Linux หรือ macOS บนเดสก์ท็อป คุณต้องพัฒนาบนแพลตฟอร์มที่คุณวางแผนจะทำให้ใช้งานได้ ดังนั้นหากต้องการพัฒนาแอป Windows บนเดสก์ท็อป คุณต้องพัฒนาบน Windows เพื่อเข้าถึงเชนบิลด์ที่เหมาะสม มีข้อกำหนดเฉพาะระบบปฏิบัติการที่ครอบคลุมรายละเอียดใน docs.flutter.dev/desktop
4. ตั้งค่า
วิธีดาวน์โหลดโค้ดสำหรับ Codelab นี้
- ไปที่ที่เก็บ GitHub สำหรับ Codelab นี้
- คลิกโค้ด > ดาวน์โหลดรหัสไปรษณีย์เพื่อดาวน์โหลดรหัสทั้งหมดสำหรับ Codelab นี้
- แตกไฟล์ ZIP ที่ดาวน์โหลดมาเพื่อคลายแพ็กโฟลเดอร์รูท
codelabs-main
ที่มีทรัพยากรทั้งหมดที่คุณต้องการ
สำหรับ Codelab นี้ คุณต้องการเฉพาะไฟล์ในไดเรกทอรีย่อย tfagents-flutter/
ในที่เก็บซึ่งมีหลายโฟลเดอร์ดังนี้
- โฟลเดอร์
step0
ถึงstep6
มีโค้ดเริ่มต้นที่คุณสร้างสำหรับแต่ละขั้นตอนใน Codelab นี้ - โฟลเดอร์
finished
มีโค้ดที่สมบูรณ์สำหรับแอปตัวอย่างที่สมบูรณ์แล้ว - แต่ละโฟลเดอร์จะมีโฟลเดอร์ย่อย
backbend
ซึ่งประกอบด้วยโค้ดแบ็กเอนด์ และโฟลเดอร์ย่อยfrontend
ซึ่งประกอบด้วยโค้ดฟรอนท์เอนด์ของ Flutter
5. ดาวน์โหลดทรัพยากร Dependency สำหรับโปรเจ็กต์
แบ็กเอนด์
เปิดเทอร์มินัลแล้วไปที่โฟลเดอร์ย่อย tfagents-flutter
เรียกใช้โค้ดต่อไปนี้
pip install -r requirements.txt
ฟรอนท์เอนด์
- ใน VS Code ให้คลิก File > เปิดโฟลเดอร์ แล้วเลือกโฟลเดอร์
step0
จากซอร์สโค้ดที่คุณดาวน์โหลดไว้ก่อนหน้านี้ - เปิดไฟล์
step0/frontend/lib/main.dart
หากเห็นกล่องโต้ตอบ "VS Code" ปรากฏขึ้นซึ่งแจ้งให้คุณดาวน์โหลดแพ็กเกจที่จำเป็นสำหรับแอปเริ่มต้น ให้คลิกรับแพ็กเกจ - หากไม่เห็นกล่องโต้ตอบนี้ ให้เปิดเทอร์มินัลแล้วเรียกใช้คำสั่ง
flutter pub get
ในโฟลเดอร์step0/frontend
6. ขั้นตอนที่ 0: เรียกใช้แอปเริ่มต้น
- เปิดไฟล์
step0/frontend/lib/main.dart
ใน VS Code ตรวจสอบว่าได้ตั้งค่าโปรแกรมจำลอง Android หรือ iOS Simulator ไว้อย่างถูกต้องและปรากฏในแถบสถานะ
เช่นสิ่งที่คุณเห็นเมื่อใช้ Pixel 5 กับโปรแกรมจำลอง Android มีดังนี้
สิ่งที่คุณจะเห็นเมื่อใช้ iPhone 13 กับ iOS Simulator มีดังนี้
- คลิก เริ่มแก้ไขข้อบกพร่อง
เรียกใช้และสำรวจแอป
แอปจะเปิดขึ้นในโปรแกรมจำลองของ Android หรือ iOS Simulator UI ค่อนข้างตรงไปตรงมา กระดานเกมมี 2 กระดาน ผู้เล่นที่เป็นมนุษย์สามารถแตะเซลล์ใดก็ได้ในกระดานของตัวแทนที่ด้านบนเป็นตำแหน่งการโจมตี คุณจะได้ฝึกตัวแทนอัจฉริยะให้คาดการณ์ตำแหน่งที่จะจู่โจมโดยอัตโนมัติตามกระดานของผู้เล่น
ในส่วนเบื้องหลัง แอป Flutter จะส่งกระดานปัจจุบันของผู้เล่นไปยังแบ็กเอนด์ ซึ่งจะเรียกใช้โมเดลการเรียนรู้แบบเสริมและส่งคืนตำแหน่งเซลล์ที่คาดการณ์ไว้สำหรับประกาศเตือนถัดไป ส่วนหน้าจะแสดงผลลัพธ์ใน UI หลังจากได้รับการตอบสนอง
หากคุณคลิกเซลล์ใดเซลล์หนึ่งในกระดานของ Agent ในตอนนี้ จะไม่มีอะไรเกิดขึ้นเนื่องจากแอปยังสื่อสารกับแบ็กเอนด์ไม่ได้
7. ขั้นตอนที่ 1: สร้างสภาพแวดล้อม Python สำหรับ TensorFlow Agent
เป้าหมายหลักของ Codelab นี้คือการออกแบบ Agent ที่เรียนรู้จากการโต้ตอบกับสภาพแวดล้อม แม้ว่าเกม Plane Strike จะค่อนข้างเรียบง่ายและสามารถสร้างกฎให้ตัวแทน NPC ได้ แต่คุณใช้การเรียนรู้แบบเสริมกำลังเพื่อฝึกตัวแทน เพื่อให้คุณจะได้เรียนรู้ทักษะและสร้างตัวแทนให้กับเกมอื่นๆ ในอนาคตได้ง่ายๆ
ในการตั้งค่า Reinforcement Learning (RL) มาตรฐาน ตัวแทนจะได้รับการสังเกตการณ์ในทุกขั้นตอนของขั้นตอนและเลือกการดำเนินการ การดำเนินการนี้จะมีผลกับสภาพแวดล้อมและสภาพแวดล้อมจะส่งคืนรางวัลและการสังเกตการณ์ใหม่ ตัวแทนจะฝึกนโยบายเพื่อเลือกการดำเนินการเพื่อเพิ่มจำนวนรางวัลให้ได้สูงสุด หรือที่เรียกว่าการคืนสินค้า การเล่นเกมหลายครั้งทำให้ตัวแทนสามารถเรียนรู้รูปแบบและฝึกฝนทักษะจนเชี่ยวชาญ ในการกำหนดเกม Plane Strike เป็นโจทย์ RL ให้มองว่าสถานะกระดานเป็นการสังเกตการณ์ ตำแหน่งการโจมตีเป็นการดำเนินการ และสัญญาณที่ตี/พลาดเป็นรางวัล
ในการฝึก Agent NPC ให้ใช้ TensorFlow Agent ซึ่งเป็นไลบรารีการเรียนรู้แบบเสริมที่น่าเชื่อถือ รองรับการปรับขนาด และใช้งานง่ายสำหรับ TensorFlow
TF Agent เหมาะอย่างยิ่งสำหรับการส่งเสริมการเรียนรู้เพราะมาพร้อมกับชุด Codelab ที่หลากหลาย ตัวอย่าง และเอกสารที่ครอบคลุมเพื่อช่วยในการเริ่มต้นใช้งาน คุณใช้ตัวแทน TF เพื่อแก้ปัญหา RL ที่สมจริงและซับซ้อนได้ด้วยความสามารถในการปรับขนาดและพัฒนาอัลกอริทึม RL ใหม่อย่างรวดเร็ว คุณสามารถสลับระหว่าง Agent และอัลกอริทึมต่างๆ เพื่อทำการทดสอบได้อย่างง่ายดาย ทั้งยังมีการทดสอบที่ดีและกำหนดค่าได้ง่ายด้วย
มีระบบเกมที่สร้างไว้ล่วงหน้ามากมายที่ใช้งานใน OpenAI Gym (เช่น เกม Atari) Mujuco และอื่นๆ ซึ่งตัวแทน TF สามารถใช้ประโยชน์ได้อย่างง่ายดาย แต่เนื่องจากเกม Plane Strike เป็นเกมที่กำหนดเองที่สมบูรณ์ คุณจึงต้องสร้างสภาพแวดล้อมใหม่ตั้งแต่ต้นก่อน
หากต้องการติดตั้งใช้งานสภาพแวดล้อม Python ของ TF Agent คุณต้องติดตั้งใช้งานเมธอดต่อไปนี้
class YourGameEnv(py_environment.PyEnvironment): def __init__(self): """Initialize environment.""" def action_spec(self): """Return action_spec.""" def observation_spec(self): """Return observation_spec.""" def _reset(self): """Return initial_time_step.""" def _step(self, action): """Apply action and return new time_step."""
ฟังก์ชันที่สำคัญที่สุดคือฟังก์ชัน _step()
ซึ่งจะทำงานและแสดงผลออบเจ็กต์ time_step
ใหม่ ในกรณีของเกม Plane Strike คุณจะมีกระดานเกม เมื่อมีการจู่โจมตำแหน่งใหม่ จากเงื่อนไขของกระดานเกม สิ่งที่จะเกิดขึ้นมีดังนี้
- กระดานเกมควรจะหน้าตาอย่างไรต่อไป (ถ้าเซลล์เปลี่ยนสีเป็นสีแดงหรือสีเหลืองตามตำแหน่งระนาบที่ซ่อนอยู่)
- ผู้เล่นควรได้รางวัลใดสำหรับตำแหน่งนั้น (ได้รางวัลหรือพลาดลูกโทษ)
- เกมควรจบไหม (ใครชนะไหม)
- เพิ่มโค้ดต่อไปนี้ลงในฟังก์ชัน
_step()
ลงในไฟล์_planestrike_py_environment.py
if self._hit_count == self._plane_size: self._episode_ended = True return self.reset() if self._strike_count + 1 == self._max_steps: self.reset() return ts.termination( np.array(self._visible_board, dtype=np.float32), UNFINISHED_GAME_REWARD ) self._strike_count += 1 action_x = action // self._board_size action_y = action % self._board_size # Hit if self._hidden_board[action_x][action_y] == HIDDEN_BOARD_CELL_OCCUPIED: # Non-repeat move if self._visible_board[action_x][action_y] == VISIBLE_BOARD_CELL_UNTRIED: self._hit_count += 1 self._visible_board[action_x][action_y] = VISIBLE_BOARD_CELL_HIT # Successful strike if self._hit_count == self._plane_size: # Game finished self._episode_ended = True return ts.termination( np.array(self._visible_board, dtype=np.float32), FINISHED_GAME_REWARD, ) else: self._episode_ended = False return ts.transition( np.array(self._visible_board, dtype=np.float32), HIT_REWARD, self._discount, ) # Repeat strike else: self._episode_ended = False return ts.transition( np.array(self._visible_board, dtype=np.float32), REPEAT_STRIKE_REWARD, self._discount, ) # Miss else: # Unsuccessful strike self._episode_ended = False self._visible_board[action_x][action_y] = VISIBLE_BOARD_CELL_MISS return ts.transition( np.array(self._visible_board, dtype=np.float32), MISS_REWARD, self._discount,
8. ขั้นตอนที่ 2: ฝึก Agent เกมด้วย TensorFlow Agent
เมื่อสภาพแวดล้อม Agent ของ TF พร้อมใช้งาน คุณจะฝึกอบรมตัวแทนในเกมได้ สำหรับ Codelab นี้ คุณใช้ Agent REINFORCE REINFORCE เป็นอัลกอริทึมการไล่ระดับนโยบายใน RL แนวคิดเบื้องต้นคือการปรับพารามิเตอร์โครงข่ายระบบประสาทเทียมของนโยบายโดยอิงตามสัญญาณรางวัลที่รวบรวมระหว่างการเล่นเกม เพื่อให้เครือข่ายนโยบายเพิ่มผลตอบแทนสูงสุดในการเล่นในอนาคตได้
- ก่อนอื่น คุณต้องสร้างอินสแตนซ์ของสภาพแวดล้อมการฝึกและการประเมิน เพิ่มโค้ดนี้ลงในฟังก์ชัน
train_agent()
ในไฟล์step2/backend/training.py
train_py_env = planestrike_py_environment.PlaneStrikePyEnvironment( board_size=BOARD_SIZE, discount=DISCOUNT, max_steps=BOARD_SIZE**2 ) eval_py_env = planestrike_py_environment.PlaneStrikePyEnvironment( board_size=BOARD_SIZE, discount=DISCOUNT, max_steps=BOARD_SIZE**2 ) train_env = tf_py_environment.TFPyEnvironment(train_py_env) eval_env = tf_py_environment.TFPyEnvironment(eval_py_env)
- ขั้นตอนต่อไปคุณต้องสร้างตัวแทนการเรียนรู้แบบเสริมกำลังที่จะได้รับการฝึกอบรม ใน Codelab นี้ คุณจะใช้ Agent REINFORCE ซึ่งเป็น Agent ที่เป็นไปตามนโยบาย เพิ่มโค้ดนี้ใต้โค้ดด้านบน
actor_net = tfa.networks.Sequential( [ tfa.keras_layers.InnerReshape([BOARD_SIZE, BOARD_SIZE], [BOARD_SIZE**2]), tf.keras.layers.Dense(FC_LAYER_PARAMS, activation="relu"), tf.keras.layers.Dense(BOARD_SIZE**2), tf.keras.layers.Lambda(lambda t: tfp.distributions.Categorical(logits=t)), ], input_spec=train_py_env.observation_spec(), ) optimizer = tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE) train_step_counter = tf.Variable(0) tf_agent = reinforce_agent.ReinforceAgent( train_env.time_step_spec(), train_env.action_spec(), actor_network=actor_net, optimizer=optimizer, normalize_returns=True, train_step_counter=train_step_counter, )
- สุดท้าย ให้ฝึกตัวแทนในการฝึกซ้ำ การวนซ้ำ คุณต้องรวบรวมการเล่นเกม 2-3 ตอนลงในบัฟเฟอร์ จากนั้นฝึกตัวแทนด้วยข้อมูลที่บัฟเฟอร์ เพิ่มโค้ดนี้ลงในฟังก์ชัน
train_agent()
ในไฟล์step2/backend/training.py
# Collect a few episodes using collect_policy and save to the replay buffer. collect_episode( train_py_env, collect_policy, COLLECT_EPISODES_PER_ITERATION, replay_buffer_observer, ) # Use data from the buffer and update the agent's network. iterator = iter(replay_buffer.as_dataset(sample_batch_size=1)) trajectories, _ = next(iterator) tf_agent.train(experience=trajectories) replay_buffer.clear()
- เริ่มการฝึกอบรมกันเลย ในเทอร์มินัล ให้ไปที่โฟลเดอร์
step2/backend
ในคอมพิวเตอร์และเรียกใช้
python training.py
การฝึกจะใช้เวลา 8-12 ชั่วโมงโดยขึ้นอยู่กับการกำหนดค่าฮาร์ดแวร์ (คุณไม่จำเป็นต้องทำการฝึกทั้งหมดด้วยตนเองเพราะโมเดลที่ฝึกไว้แล้วล่วงหน้าจะมีอยู่ใน step3
) ในระหว่างนี้ คุณจะดูความคืบหน้าได้ด้วย TensorBoard เปิดเทอร์มินัลใหม่ ไปที่โฟลเดอร์ step2/backend
ในคอมพิวเตอร์และเรียกใช้
tensorboard --logdir tf_agents_log/
tf_agents_log
คือโฟลเดอร์ที่มีบันทึกการฝึก ตัวอย่างการเรียกใช้การฝึกจะมีดังนี้
คุณจะเห็นได้ว่าความยาวของตอนโดยเฉลี่ยลดลงและผลตอบแทนเฉลี่ยเพิ่มขึ้นเมื่อการฝึกดำเนินต่อไป ซึ่งคุณเข้าใจได้โดยสัญชาตญาณว่าหากตัวแทนฉลาดขึ้นและคาดการณ์ได้ดีขึ้น ความยาวของเกมจะสั้นลงและตัวแทนจะได้รางวัลมากขึ้น ซึ่งเหมาะสมเนื่องจากตัวแทนต้องการเล่นเกมให้เสร็จโดยลดขั้นตอนลงเพื่อลดการให้ส่วนลดรางวัลใหญ่ในขั้นตอนถัดไป
หลังจากการฝึกเสร็จสมบูรณ์ ระบบจะส่งออกโมเดลที่ฝึกไปยังโฟลเดอร์ policy_model
9. ขั้นตอนที่ 3: ทำให้โมเดลที่ฝึกใช้งานได้ด้วยการแสดง TensorFlow
เมื่อฝึก Agent เกมแล้ว คุณก็ทำให้ Agent ใช้งานได้ด้วย TensorFlow Serve
- ในเทอร์มินัล ให้ไปที่โฟลเดอร์
step3/backend
ในคอมพิวเตอร์แล้วเริ่ม TensorFlow Serve ด้วย Docker โดยใช้คำสั่งต่อไปนี้
docker run -t --rm -p 8501:8501 -p 8500:8500 -v "$(pwd)/backend/policy_model:/models/policy_model" -e MODEL_NAME=policy_model tensorflow/serving
Docker จะดาวน์โหลดอิมเมจการแสดงของ TensorFlow โดยอัตโนมัติก่อน ซึ่งจะใช้เวลา 1 นาที หลังจากนั้น การแสดง TensorFlow ควรเริ่มทำงาน บันทึกควรมีลักษณะดังนี้
2022-05-30 02:38:54.147771: I tensorflow_serving/model_servers/server.cc:89] Building single TensorFlow model file config: model_name: policy_model model_base_path: /models/policy_model 2022-05-30 02:38:54.148222: I tensorflow_serving/model_servers/server_core.cc:465] Adding/updating models. 2022-05-30 02:38:54.148273: I tensorflow_serving/model_servers/server_core.cc:591] (Re-)adding model: policy_model 2022-05-30 02:38:54.262684: I tensorflow_serving/core/basic_manager.cc:740] Successfully reserved resources to load servable {name: policy_model version: 123} 2022-05-30 02:38:54.262768: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: policy_model version: 123} 2022-05-30 02:38:54.262787: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: policy_model version: 123} 2022-05-30 02:38:54.265010: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:38] Reading SavedModel from: /models/policy_model/123 2022-05-30 02:38:54.277811: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:90] Reading meta graph with tags { serve } 2022-05-30 02:38:54.278116: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:132] Reading SavedModel debug info (if present) from: /models/policy_model/123 2022-05-30 02:38:54.280229: I external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. 2022-05-30 02:38:54.332352: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle. 2022-05-30 02:38:54.337000: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 2193480000 Hz 2022-05-30 02:38:54.402803: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/policy_model/123 2022-05-30 02:38:54.410707: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 145695 microseconds. 2022-05-30 02:38:54.412726: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/policy_model/123/assets.extra/tf_serving_warmup_requests 2022-05-30 02:38:54.417277: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: policy_model version: 123} 2022-05-30 02:38:54.419846: I tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models 2022-05-30 02:38:54.420066: I tensorflow_serving/model_servers/server.cc:367] Profiler service is enabled 2022-05-30 02:38:54.428339: I tensorflow_serving/model_servers/server.cc:393] Running gRPC ModelServer at 0.0.0.0:8500 ... [warn] getaddrinfo: address family for nodename not supported 2022-05-30 02:38:54.431620: I tensorflow_serving/model_servers/server.cc:414] Exporting HTTP/REST API at:localhost:8501 ... [evhttp_server.cc : 245] NET_LOG: Entering the event loop ...
คุณส่งคำขอตัวอย่างไปยังปลายทางได้เพื่อตรวจสอบว่าคำขอทำงานตามที่คาดไว้
curl -d '{"signature_name":"action","instances":[{"0/discount":0.0,"0/observation":[[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]],"0/reward":0.0,"0/step_type":0}]}' -X POST http://localhost:8501/v1/models/policy_model:predict
อุปกรณ์ปลายทางจะแสดงตำแหน่งที่คาดการณ์ 45
ซึ่งก็คือ (5, 5) ตรงกลางกระดาน (ถ้าสงสัยว่าทำไมจุดกึ่งกลางของกระดานจึงเป็นการคาดเดาตำแหน่งการประกาศเตือนครั้งแรกได้ดี)
{ "predictions": [45] }
เท่านี้ก็เรียบร้อย คุณสร้างแบ็กเอนด์เพื่อคาดการณ์ตำแหน่งประกาศเตือนถัดไปสำหรับตัวแทน NPC เรียบร้อยแล้ว
10. ขั้นตอนที่ 4: สร้างแอป Flutter สำหรับ Android และ iOS
แบ็กเอนด์พร้อมแล้ว คุณเริ่มส่งคำขอไปยังกลุ่มดังกล่าวเพื่อเรียกข้อมูลการคาดการณ์ตำแหน่งประกาศเตือนจากแอป Flutter ได้
- ก่อนอื่น คุณต้องกำหนดคลาสที่รวมอินพุตที่จะส่ง เพิ่มโค้ดนี้ลงในไฟล์
step4/frontend/lib/game_agent.dart
class Inputs { final List<double> _boardState; Inputs(this._boardState); Map<String, dynamic> toJson() { final Map<String, dynamic> data = <String, dynamic>{}; data['0/discount'] = [0.0]; data['0/observation'] = [_boardState]; data['0/reward'] = [0.0]; data['0/step_type'] = [0]; return data; } }
ตอนนี้คุณส่งคำขอไปยัง TensorFlow Serve เพื่อคาดการณ์ได้แล้ว
- เพิ่มโค้ดนี้ลงในฟังก์ชัน
predict()
ในไฟล์step4/frontend/lib/game_agent.dart
var flattenedBoardState = boardState.expand((i) => i).toList(); final response = await http.post( Uri.parse('http://$server:8501/v1/models/policy_model:predict'), body: jsonEncode(<String, dynamic>{ 'signature_name': 'action', 'instances': [Inputs(flattenedBoardState)] }), ); if (response.statusCode == 200) { var output = List<int>.from( jsonDecode(response.body)['predictions'] as List<dynamic>); return output[0]; } else { throw Exception('Error response'); }
เมื่อแอปได้รับการตอบสนองจากแบ็กเอนด์ คุณจะต้องอัปเดต UI ของเกมเพื่อแสดงความคืบหน้าของเกม
- เพิ่มโค้ดนี้ลงในฟังก์ชัน
_gridItemTapped()
ในไฟล์step4/frontend/lib/main.dart
int agentAction = await _policyGradientAgent.predict(_playerVisibleBoardState); _agentActionX = agentAction ~/ _boardSize; _agentActionY = agentAction % _boardSize; if (_playerHiddenBoardState[_agentActionX][_agentActionY] == hiddenBoardCellOccupied) { // Non-repeat move if (_playerVisibleBoardState[_agentActionX][_agentActionY] == visibleBoardCellUntried) { _agentHitCount++; } _playerVisibleBoardState[_agentActionX][_agentActionY] = visibleBoardCellHit; } else { _playerVisibleBoardState[_agentActionX][_agentActionY] = visibleBoardCellMiss; } setState(() {});
เรียกใช้
- คลิก เริ่มแก้ไขข้อบกพร่อง แล้วรอให้แอปโหลด
- แตะเซลล์ใดก็ได้ในกระดานของตัวแทนเพื่อเริ่มเกม
11. ขั้นตอนที่ 5: เปิดใช้แอป Flutter สำหรับแพลตฟอร์มเดสก์ท็อป
นอกเหนือจาก Android และ iOS แล้ว Flutter ยังรองรับแพลตฟอร์มเดสก์ท็อปอย่าง Linux, Mac และ Windows ด้วย
Linux
- ตรวจสอบว่าอุปกรณ์เป้าหมายตั้งค่าเป็น ในแถบสถานะของ VSCode
- คลิก เริ่มแก้ไขข้อบกพร่อง แล้วรอให้แอปโหลด
- คลิกเซลล์ใดก็ได้ในกระดานของตัวแทนเพื่อเริ่มเกม
Mac
- สำหรับ Mac คุณต้องตั้งค่าการให้สิทธิ์ที่เหมาะสมเนื่องจากแอปจะส่งคำขอ HTTP ไปยังแบ็กเอนด์ โปรดดูรายละเอียดเพิ่มเติมที่การให้สิทธิ์และ App Sandbox
เพิ่มโค้ดนี้ลงใน step4/frontend/macOS/Runner/DebugProfile.entitlements
และ step4/frontend/macOS/Runner/Release.entitlements
ตามลำดับ
<key>com.apple.security.network.client</key>
<true/>
- ตรวจสอบว่าอุปกรณ์เป้าหมายตั้งค่าเป็น ในแถบสถานะของ VSCode
- คลิก เริ่มแก้ไขข้อบกพร่อง แล้วรอให้แอปโหลด
- คลิกเซลล์ใดก็ได้ในกระดานของตัวแทนเพื่อเริ่มเกม
Windows
- ตรวจสอบว่าอุปกรณ์เป้าหมายตั้งค่าเป็น ในแถบสถานะของ VSCode
- คลิก เริ่มแก้ไขข้อบกพร่อง แล้วรอให้แอปโหลด
- คลิกเซลล์ใดก็ได้ในกระดานของตัวแทนเพื่อเริ่มเกม
12. ขั้นตอนที่ 6: เปิดใช้แอป Flutter สำหรับแพลตฟอร์มเว็บ
อีกสิ่งหนึ่งที่ทำได้คือการเพิ่มการสนับสนุนผ่านเว็บลงในแอป Flutter โดยค่าเริ่มต้น แพลตฟอร์มเว็บจะเปิดใช้โดยอัตโนมัติสำหรับแอป Flutter ดังนั้นคุณเพียงแค่ต้องเปิดใช้งาน
- ตรวจสอบว่าอุปกรณ์เป้าหมายตั้งค่าเป็น ในแถบสถานะของ VSCode
- คลิก เริ่มแก้ไขข้อบกพร่อง จากนั้นรอให้แอปโหลดในเบราว์เซอร์ Chrome
- คลิกเซลล์ใดก็ได้ในกระดานของตัวแทนเพื่อเริ่มเกม
13. ขอแสดงความยินดี
คุณสร้างแอปเกมกระดานโดยมีตัวแทนที่ขับเคลื่อนด้วย ML มาเล่นแข่งกับผู้เล่นมนุษย์!