1. ก่อนเริ่มต้น
ความก้าวหน้าอันน่าทึ่งของ AlphaGo และ AlphaStar แสดงให้เห็นถึงศักยภาพของการใช้แมชชีนเลิร์นนิงเพื่อสร้างเอเจนต์เกมระดับเหนือมนุษย์ การสร้างเกมขนาดเล็กที่ทำงานด้วย ML เพื่อฝึกทักษะที่จำเป็นในการสร้างเอเจนต์เกมที่มีประสิทธิภาพเป็นวิธีที่สนุก
ใน Codelab นี้ คุณจะได้เรียนรู้วิธีสร้างเกมกระดานโดยใช้สิ่งต่อไปนี้
- TensorFlow Agent เพื่อฝึกเอเจนต์เกมด้วยการเรียนรู้แบบเสริมกำลัง
- TensorFlow Serving เพื่อแสดงโมเดล
- Flutter เพื่อสร้างแอปเกมกระดานข้ามแพลตฟอร์ม
ข้อกำหนดเบื้องต้น
- ความรู้พื้นฐานเกี่ยวกับการพัฒนา Flutter ด้วย Dart
- ความรู้พื้นฐานเกี่ยวกับแมชชีนเลิร์นนิงด้วย TensorFlow เช่น การฝึกเทียบกับการติดตั้งใช้งาน
- มีความรู้พื้นฐานเกี่ยวกับ Python, เทอร์มินัล และ Docker
สิ่งที่คุณจะได้เรียนรู้
- วิธีฝึกเอเจนต์ตัวละครที่ไม่ใช่ผู้เล่น (NPC) โดยใช้ TensorFlow Agents
- วิธีแสดงโมเดลที่ฝึกแล้วโดยใช้ TensorFlow Serving
- วิธีสร้างเกมกระดาน Flutter แบบข้ามแพลตฟอร์ม
สิ่งที่คุณต้องมี
- Flutter SDK
- การตั้งค่า Android และ iOS สำหรับ Flutter
- การตั้งค่า Desktop สำหรับ Flutter
- การตั้งค่า Web สำหรับ Flutter
- การตั้งค่า Visual Studio Code (VS Code) สำหรับ Flutter และ Dart
- Docker
- Bash
- Python 3.7 ขึ้นไป
2. เกม Plane Strike
เกมที่คุณสร้างใน Codelab นี้มีชื่อว่า "Plane Strike" ซึ่งเป็นเกมกระดานขนาดเล็กสำหรับผู้เล่น 2 คนที่มีลักษณะคล้ายกับเกมกระดาน "Battleship" กฎมีดังนี้
- ผู้เล่นที่เป็นมนุษย์จะเล่นกับเอเจนต์ NPC ที่ฝึกโดยแมชชีนเลิร์นนิง ผู้เล่นที่เป็นมนุษย์สามารถเริ่มเกมได้โดยแตะเซลล์ใดก็ได้ในกระดานของเอเจนต์
- เมื่อเริ่มเกม ผู้เล่นที่เป็นมนุษย์และเอเจนต์จะมีออบเจ็กต์ "เครื่องบิน" (เซลล์สีเขียว 8 เซลล์ที่ประกอบกันเป็น "เครื่องบิน" ดังที่เห็นในกระดานของผู้เล่นที่เป็นมนุษย์ในภาพเคลื่อนไหวด้านล่าง) บนกระดานของตนเอง โดย "เครื่องบิน" เหล่านี้จะวางแบบสุ่มและมีเพียงเจ้าของกระดานเท่านั้นที่มองเห็น ส่วนคู่ต่อสู้จะมองไม่เห็น
- ผู้เล่นที่เป็นมนุษย์และเอเจนต์จะผลัดกันโจมตีเซลล์หนึ่งในบอร์ดของกันและกัน ผู้เล่นที่เป็นมนุษย์สามารถแตะช่องใดก็ได้ในกระดานของเอเจนต์ ขณะที่เอเจนต์จะเลือกโดยอัตโนมัติตามการคาดการณ์ของโมเดลแมชชีนเลิร์นนิง เซลล์ที่พยายามจะยิงจะเป็นสีแดงหากเป็นเซลล์ "เครื่องบิน" ("โดน") หรือเป็นสีเหลือง ("พลาด") ในกรณีอื่นๆ
- ใครก็ตามที่ทำได้ 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 นี้
- คลิกโค้ด > ดาวน์โหลด ZIP เพื่อดาวน์โหลดโค้ดทั้งหมดสำหรับ 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 ให้คลิกไฟล์ > เปิดโฟลเดอร์ แล้วเลือกโฟลเดอร์
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 UI ใช้งานง่าย มีกระดานเกม 2 กระดาน ผู้เล่นที่เป็นมนุษย์สามารถแตะเซลล์ใดก็ได้ในกระดานของเอเจนต์ที่ด้านบนเป็นตำแหน่งโจมตี คุณจะฝึกเอเจนต์อัจฉริยะให้คาดการณ์โดยอัตโนมัติว่าจะโจมตีที่ใดโดยอิงตามกระดานของผู้เล่นที่เป็นมนุษย์
เบื้องหลังแล้ว แอป Flutter จะส่งกระดานปัจจุบันของผู้เล่นที่เป็นมนุษย์ไปยังแบ็กเอนด์ ซึ่งเรียกใช้โมเดลการเรียนรู้แบบเสริมกำลังและส่งคืนตำแหน่งเซลล์ที่คาดการณ์ไว้เพื่อโจมตีในครั้งถัดไป ส่วนหน้าจะแสดงผลลัพธ์ใน UI หลังจากได้รับคำตอบ

หากคุณคลิกเซลล์ใดๆ ในบอร์ดของตัวแทนตอนนี้ จะไม่มีอะไรเกิดขึ้นเนื่องจากแอปยังสื่อสารกับแบ็กเอนด์ไม่ได้
7. ขั้นตอนที่ 1: สร้างสภาพแวดล้อม Python ของ TensorFlow Agents
เป้าหมายหลักของ Codelab นี้คือการออกแบบ Agent ที่เรียนรู้โดยการโต้ตอบกับสภาพแวดล้อม แม้ว่าเกม Plane Strike จะค่อนข้างเรียบง่ายและสามารถสร้างกฎสำหรับเอเจนต์ NPC ได้ด้วยตนเอง แต่คุณก็ใช้การเรียนรู้แบบเสริมกำลังเพื่อฝึกเอเจนต์เพื่อให้ได้เรียนรู้ทักษะและสร้างเอเจนต์สำหรับเกมอื่นๆ ในอนาคตได้อย่างง่ายดาย
ในการตั้งค่าการเรียนรู้แบบเสริมกำลัง (RL) มาตรฐาน เอเจนต์จะได้รับการสังเกตการณ์ในทุกขั้นตอนเวลาและเลือกการดำเนินการ การดำเนินการจะมีผลกับสภาพแวดล้อม และสภาพแวดล้อมจะให้รางวัลและการสังเกตการณ์ใหม่ เอเจนต์จะฝึกนโยบายในการเลือกการดำเนินการเพื่อเพิ่มผลรวมของรางวัลให้สูงสุด หรือที่เรียกว่าผลตอบแทน การเล่นเกมซ้ำๆ หลายครั้งช่วยให้เอเจนต์เรียนรู้รูปแบบและฝึกฝนทักษะจนเชี่ยวชาญเกมได้ หากต้องการกำหนดเกม Plane Strike เป็นปัญหา RL ให้คิดว่าสถานะกระดานคือการสังเกต ตำแหน่งการโจมตีคือการดำเนินการ และสัญญาณการโจมตี/พลาดคือรางวัล

หากต้องการฝึกเอเจนต์ NPC คุณต้องใช้ประโยชน์จาก TensorFlow Agents ซึ่งเป็นไลบรารีการเรียนรู้แบบเสริมกำลังที่เชื่อถือได้ ปรับขนาดได้ และใช้งานง่ายสำหรับ TensorFlow
TF Agents เหมาะสำหรับการเรียนรู้แบบเสริมกำลังเนื่องจากมีชุด Codelab ตัวอย่าง และเอกสารประกอบมากมายที่จะช่วยให้คุณเริ่มต้นใช้งานได้ คุณใช้ TF-Agents เพื่อแก้ปัญหา RL ที่ซับซ้อนและสมจริงได้โดยมีความสามารถในการปรับขนาด และพัฒนาอัลกอริทึม RL ใหม่ๆ ได้อย่างรวดเร็ว คุณสามารถสลับระหว่างเอเจนต์และอัลกอริทึมต่างๆ เพื่อทำการทดลองได้อย่างง่ายดาย นอกจากนี้ยังได้รับการทดสอบอย่างดีและกำหนดค่าได้ง่าย
OpenAI Gym (เช่น เกม Atari), Mujuco และอื่นๆ มีสภาพแวดล้อมของเกมที่สร้างไว้ล่วงหน้ามากมาย ซึ่ง TF Agents สามารถใช้ประโยชน์ได้อย่างง่ายดาย แต่เนื่องจากเกม Plane Strike เป็นเกมที่กำหนดเองทั้งหมด คุณจึงต้องใช้สภาพแวดล้อมใหม่ตั้งแต่ต้นก่อน
หากต้องการติดตั้งใช้งานสภาพแวดล้อม Python ของ TF Agents คุณต้องติดตั้งใช้งานเมธอดต่อไปนี้
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: ฝึกตัวแทนเกมด้วย TensorFlow Agents
เมื่อมีสภาพแวดล้อม TF Agents แล้ว คุณจะฝึกตัวแทนเกมได้ สำหรับ 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 ตอนลงในบัฟเฟอร์ก่อน จากนั้นจึงฝึก Agent ด้วยข้อมูลที่บัฟเฟอร์ไว้ เพิ่มโค้ดนี้ลงในฟังก์ชัน
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 คือโฟลเดอร์ที่มีบันทึกการฝึก ตัวอย่างการเรียกใช้การฝึกมีลักษณะดังนี้
คุณจะเห็นว่าความยาวของตอนโดยเฉลี่ยลดลงและผลตอบแทนเฉลี่ยเพิ่มขึ้นเมื่อการฝึกดำเนินไป คุณจะเข้าใจได้โดยสัญชาตญาณว่าหาก Agent ฉลาดขึ้นและคาดการณ์ได้ดีขึ้น ระยะเวลาของเกมจะสั้นลงและ Agent จะได้รับรางวัลมากขึ้น ซึ่งสมเหตุสมผลเนื่องจากเอเจนต์ต้องการจบเกมในขั้นตอนที่น้อยลงเพื่อลดการลดทอนรางวัลอย่างมากในขั้นตอนต่อๆ ไป
หลังจากฝึกเสร็จแล้ว ระบบจะส่งออกโมเดลที่ฝึกแล้วไปยังโฟลเดอร์ policy_model
9. ขั้นตอนที่ 3: ทำให้โมเดลที่ฝึกแล้วใช้งานได้ด้วย TensorFlow Serving
เมื่อฝึก Agent เกมแล้ว คุณสามารถนำไปใช้งานกับ TensorFlow Serving ได้
- ในเทอร์มินัล ให้ไปที่โฟลเดอร์
step3/backendในคอมพิวเตอร์ แล้วเริ่ม TensorFlow Serving ด้วย 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 Serving โดยอัตโนมัติก่อน ซึ่งจะใช้เวลา 1 นาที หลังจากนั้น TensorFlow Serving ควรจะเริ่มทำงาน โดยบันทึกควรมีลักษณะดังข้อมูลโค้ดต่อไปนี้
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 Serving เพื่อทำการคาดการณ์ได้แล้ว
- เพิ่มโค้ดนี้ลงในฟังก์ชัน
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 ไปยังแบ็กเอนด์ โปรดดูรายละเอียดเพิ่มเติมในสิทธิ์และแซนด์บ็อกซ์ของแอป
เพิ่มโค้ดนี้ลงใน step4/frontend/macOS/Runner/DebugProfile.entitlements และ step4/frontend/macOS/Runner/Release.entitlements ตามลำดับ
<key>com.apple.security.network.client</key>
<true/>
- ตรวจสอบว่าได้ตั้งค่าอุปกรณ์เป้าหมายเป็น
ในแถบสถานะของ VSCode - คลิก
Start debugging แล้วรอให้แอปโหลด - คลิกเซลล์ใดก็ได้ในกระดานของเอเจนต์เพื่อเริ่มเกม

Windows
- ตรวจสอบว่าได้ตั้งค่าอุปกรณ์เป้าหมายเป็น
ในแถบสถานะของ VSCode - คลิก
Start debugging แล้วรอให้แอปโหลด - คลิกเซลล์ใดก็ได้ในกระดานของเอเจนต์เพื่อเริ่มเกม

12. ขั้นตอนที่ 6: เปิดใช้แอป Flutter สำหรับแพลตฟอร์มเว็บ
อีกสิ่งหนึ่งที่คุณทำได้คือการเพิ่มการรองรับเว็บลงในแอป Flutter โดยค่าเริ่มต้น แพลตฟอร์มเว็บจะเปิดใช้โดยอัตโนมัติสำหรับแอป Flutter ดังนั้นสิ่งที่คุณต้องทำก็คือเปิดใช้
- ตรวจสอบว่าได้ตั้งค่าอุปกรณ์เป้าหมายเป็น
ในแถบสถานะของ VSCode - คลิก
Start debugging แล้วรอให้แอปโหลดในเบราว์เซอร์ Chrome - คลิกเซลล์ใดก็ได้ในกระดานของเอเจนต์เพื่อเริ่มเกม

13. ขอแสดงความยินดี
คุณสร้างแอปเกมกระดานที่มีเอเจนต์ที่ทำงานด้วย ML เพื่อเล่นกับผู้เล่นที่เป็นมนุษย์
