การสร้างเกมกระดานด้วย TensorFlow Agent และ Flutter

1. ก่อนเริ่มต้น

ความก้าวหน้าอันน่าทึ่งของ AlphaGo และ AlphaStar แสดงให้เห็นถึงศักยภาพของการใช้แมชชีนเลิร์นนิงเพื่อสร้างเอเจนต์เกมระดับเหนือมนุษย์ การสร้างเกมขนาดเล็กที่ทำงานด้วย ML เพื่อฝึกทักษะที่จำเป็นในการสร้างเอเจนต์เกมที่มีประสิทธิภาพเป็นวิธีที่สนุก

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีสร้างเกมกระดานโดยใช้สิ่งต่อไปนี้

  • TensorFlow Agent เพื่อฝึกเอเจนต์เกมด้วยการเรียนรู้แบบเสริมกำลัง
  • TensorFlow Serving เพื่อแสดงโมเดล
  • Flutter เพื่อสร้างแอปเกมกระดานข้ามแพลตฟอร์ม

ข้อกำหนดเบื้องต้น

  • ความรู้พื้นฐานเกี่ยวกับการพัฒนา Flutter ด้วย Dart
  • ความรู้พื้นฐานเกี่ยวกับแมชชีนเลิร์นนิงด้วย TensorFlow เช่น การฝึกเทียบกับการติดตั้งใช้งาน
  • มีความรู้พื้นฐานเกี่ยวกับ Python, เทอร์มินัล และ Docker

สิ่งที่คุณจะได้เรียนรู้

  • วิธีฝึกเอเจนต์ตัวละครที่ไม่ใช่ผู้เล่น (NPC) โดยใช้ TensorFlow Agents
  • วิธีแสดงโมเดลที่ฝึกแล้วโดยใช้ TensorFlow Serving
  • วิธีสร้างเกมกระดาน Flutter แบบข้ามแพลตฟอร์ม

สิ่งที่คุณต้องมี

2. เกม Plane Strike

เกมที่คุณสร้างใน Codelab นี้มีชื่อว่า "Plane Strike" ซึ่งเป็นเกมกระดานขนาดเล็กสำหรับผู้เล่น 2 คนที่มีลักษณะคล้ายกับเกมกระดาน "Battleship" กฎมีดังนี้

  • ผู้เล่นที่เป็นมนุษย์จะเล่นกับเอเจนต์ NPC ที่ฝึกโดยแมชชีนเลิร์นนิง ผู้เล่นที่เป็นมนุษย์สามารถเริ่มเกมได้โดยแตะเซลล์ใดก็ได้ในกระดานของเอเจนต์
  • เมื่อเริ่มเกม ผู้เล่นที่เป็นมนุษย์และเอเจนต์จะมีออบเจ็กต์ "เครื่องบิน" (เซลล์สีเขียว 8 เซลล์ที่ประกอบกันเป็น "เครื่องบิน" ดังที่เห็นในกระดานของผู้เล่นที่เป็นมนุษย์ในภาพเคลื่อนไหวด้านล่าง) บนกระดานของตนเอง โดย "เครื่องบิน" เหล่านี้จะวางแบบสุ่มและมีเพียงเจ้าของกระดานเท่านั้นที่มองเห็น ส่วนคู่ต่อสู้จะมองไม่เห็น
  • ผู้เล่นที่เป็นมนุษย์และเอเจนต์จะผลัดกันโจมตีเซลล์หนึ่งในบอร์ดของกันและกัน ผู้เล่นที่เป็นมนุษย์สามารถแตะช่องใดก็ได้ในกระดานของเอเจนต์ ขณะที่เอเจนต์จะเลือกโดยอัตโนมัติตามการคาดการณ์ของโมเดลแมชชีนเลิร์นนิง เซลล์ที่พยายามจะยิงจะเป็นสีแดงหากเป็นเซลล์ "เครื่องบิน" ("โดน") หรือเป็นสีเหลือง ("พลาด") ในกรณีอื่นๆ
  • ใครก็ตามที่ทำได้ 8 เซลล์สีแดงก่อนจะเป็นผู้ชนะในเกม จากนั้นระบบจะรีสตาร์ทเกมด้วยบอร์ดใหม่

ตัวอย่างการเล่นเกมมีดังนี้

77cead530c5a4aff.gif

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 นี้

  1. ไปที่ที่เก็บ GitHub สำหรับ Codelab นี้
  2. คลิกโค้ด > ดาวน์โหลด ZIP เพื่อดาวน์โหลดโค้ดทั้งหมดสำหรับ Codelab นี้

2cd45599f51fb8a2.png

  1. แตกไฟล์ ZIP ที่ดาวน์โหลดเพื่อคลายโฟลเดอร์รูท codelabs-main ที่มีทรัพยากรทั้งหมดที่คุณต้องการ

สำหรับ Codelab นี้ คุณจะต้องใช้ไฟล์ในไดเรกทอรีย่อย tfagents-flutter/ ในที่เก็บเท่านั้น ซึ่งมีโฟลเดอร์หลายโฟลเดอร์ดังนี้

  • โฟลเดอร์ step0 ถึง step6 มีโค้ดเริ่มต้นที่คุณจะใช้ต่อยอดสำหรับแต่ละขั้นตอนใน Codelab นี้
  • โฟลเดอร์ finished มีโค้ดที่เสร็จสมบูรณ์สำหรับแอปตัวอย่างที่เสร็จแล้ว
  • แต่ละโฟลเดอร์จะมีโฟลเดอร์ย่อย backbend ซึ่งมีโค้ดแบ็กเอนด์ และโฟลเดอร์ย่อย frontend ซึ่งมีโค้ดฟรอนต์เอนด์ Flutter

5. ดาวน์โหลดทรัพยากร Dependency สำหรับโปรเจ็กต์

แบ็กเอนด์

เปิดเทอร์มินัลแล้วไปที่โฟลเดอร์ย่อย tfagents-flutter เรียกใช้คำสั่งต่อไปนี้

pip install -r requirements.txt

ฟรอนท์เอนด์

  1. ใน VS Code ให้คลิกไฟล์ > เปิดโฟลเดอร์ แล้วเลือกโฟลเดอร์ step0 จากซอร์สโค้ดที่คุณดาวน์โหลดไว้ก่อนหน้านี้
  2. เปิดไฟล์ step0/frontend/lib/main.dart หากเห็นกล่องโต้ตอบ VS Code ปรากฏขึ้นซึ่งแจ้งให้คุณดาวน์โหลดแพ็กเกจที่จำเป็นสำหรับแอปเริ่มต้น ให้คลิกรับแพ็กเกจ
  3. หากไม่เห็นกล่องโต้ตอบนี้ ให้เปิดเทอร์มินัล แล้วเรียกใช้flutter pub getคำสั่งในโฟลเดอร์ step0/frontend

7ada07c300f166a6.png

6. ขั้นตอนที่ 0: เรียกใช้แอปเริ่มต้น

  1. เปิดstep0/frontend/lib/main.dartใน VS Code ตรวจสอบว่าได้ตั้งค่าโปรแกรมจำลองของ Android หรือ iOS Simulator อย่างถูกต้องและปรากฏในแถบสถานะ

ตัวอย่างเช่น สิ่งที่คุณเห็นเมื่อใช้ Pixel 5 กับโปรแกรมจำลองของ Android มีดังนี้

9767649231898791.png

ต่อไปนี้คือสิ่งที่คุณจะเห็นเมื่อใช้ iPhone 13 กับ iOS Simulator

95529e3a682268b2.png

  1. คลิก a19a0c68bc4046e6.png เริ่มแก้ไขข้อบกพร่อง

เรียกใช้และสำรวจแอป

แอปควรเปิดในโปรแกรมจำลองของ Android หรือโปรแกรมจำลอง iOS UI ใช้งานง่าย มีกระดานเกม 2 กระดาน ผู้เล่นที่เป็นมนุษย์สามารถแตะเซลล์ใดก็ได้ในกระดานของเอเจนต์ที่ด้านบนเป็นตำแหน่งโจมตี คุณจะฝึกเอเจนต์อัจฉริยะให้คาดการณ์โดยอัตโนมัติว่าจะโจมตีที่ใดโดยอิงตามกระดานของผู้เล่นที่เป็นมนุษย์

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

734ab3d48a1133e1.png 15cba2e741149c95.png

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

7. ขั้นตอนที่ 1: สร้างสภาพแวดล้อม Python ของ TensorFlow Agents

เป้าหมายหลักของ Codelab นี้คือการออกแบบ Agent ที่เรียนรู้โดยการโต้ตอบกับสภาพแวดล้อม แม้ว่าเกม Plane Strike จะค่อนข้างเรียบง่ายและสามารถสร้างกฎสำหรับเอเจนต์ NPC ได้ด้วยตนเอง แต่คุณก็ใช้การเรียนรู้แบบเสริมกำลังเพื่อฝึกเอเจนต์เพื่อให้ได้เรียนรู้ทักษะและสร้างเอเจนต์สำหรับเกมอื่นๆ ในอนาคตได้อย่างง่ายดาย

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

bc5da07bc45062f4.png

หากต้องการฝึกเอเจนต์ 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 คือโฟลเดอร์ที่มีบันทึกการฝึก ตัวอย่างการเรียกใช้การฝึกมีลักษณะดังนี้

33e12e2b387c063a.png 8488632ccf43348a.png

คุณจะเห็นว่าความยาวของตอนโดยเฉลี่ยลดลงและผลตอบแทนเฉลี่ยเพิ่มขึ้นเมื่อการฝึกดำเนินไป คุณจะเข้าใจได้โดยสัญชาตญาณว่าหาก 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(() {});

ดำเนินการ

  1. คลิก a19a0c68bc4046e6.png เริ่มการแก้ไขข้อบกพร่อง แล้วรอให้แอปโหลด
  2. แตะเซลล์ใดก็ได้ในกระดานของเอเจนต์เพื่อเริ่มเกม

852942d0de299c1f.png 6ae3601470c8e33a.png

11. ขั้นตอนที่ 5: เปิดใช้แอป Flutter สำหรับแพลตฟอร์มเดสก์ท็อป

นอกจาก Android และ iOS แล้ว Flutter ยังรองรับแพลตฟอร์มเดสก์ท็อปด้วย ซึ่งรวมถึง Linux, Mac และ Windows

Linux

  1. ตรวจสอบว่าได้ตั้งค่าอุปกรณ์เป้าหมายเป็น 86cba523de82b4f9.png ในแถบสถานะของ VSCode
  2. คลิก a19a0c68bc4046e6.png เริ่มการแก้ไขข้อบกพร่อง แล้วรอให้แอปโหลด
  3. คลิกเซลล์ใดก็ได้ในกระดานของเอเจนต์เพื่อเริ่มเกม

48594c7c0a589733.png

Mac

  1. สำหรับ Mac คุณต้องตั้งค่าสิทธิ์ที่เหมาะสมเนื่องจากแอปจะส่งคำขอ HTTP ไปยังแบ็กเอนด์ โปรดดูรายละเอียดเพิ่มเติมในสิทธิ์และแซนด์บ็อกซ์ของแอป

เพิ่มโค้ดนี้ลงใน step4/frontend/macOS/Runner/DebugProfile.entitlements และ step4/frontend/macOS/Runner/Release.entitlements ตามลำดับ

<key>com.apple.security.network.client</key>
<true/>
  1. ตรวจสอบว่าได้ตั้งค่าอุปกรณ์เป้าหมายเป็น eb4b0b5563824138.png ในแถบสถานะของ VSCode
  2. คลิก a19a0c68bc4046e6.png Start debugging แล้วรอให้แอปโหลด
  3. คลิกเซลล์ใดก็ได้ในกระดานของเอเจนต์เพื่อเริ่มเกม

55a5de3674194e89.png

Windows

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

41d9f87d84c5e755.png

12. ขั้นตอนที่ 6: เปิดใช้แอป Flutter สำหรับแพลตฟอร์มเว็บ

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

  1. ตรวจสอบว่าได้ตั้งค่าอุปกรณ์เป้าหมายเป็น 71db93efa928d15d.pngในแถบสถานะของ VSCode
  2. คลิก a19a0c68bc4046e6.png Start debugging แล้วรอให้แอปโหลดในเบราว์เซอร์ Chrome
  3. คลิกเซลล์ใดก็ได้ในกระดานของเอเจนต์เพื่อเริ่มเกม

fae7490304e28dfe.png

13. ขอแสดงความยินดี

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

ดูข้อมูลเพิ่มเติม