0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

チュートリアルStep10

Last updated at Posted at 2024-10-04

スクリーンショット 2024-10-09 22.05.09.png

puyopuyo.gif
 ぷよぷよプログラミングAI学習システムは、中高生の自己調整学習に向けて開発されました。
 どうやって、Chromebookで、10分で、素敵な人工知能を作れるのでしょうか?
 秘密は、3つ。
 1 jupyter liteで、webクライアントがpythonコードを実行
 2 超軽量な機械学習フレームワークdezeroを採用
 3 ぷよぷよのstageとactionがコンパクト

Github&X

ぷよぷよプログラミングAI学習用まとめ

チュートリアルまとめ

Step10 Agent

10 Agentは特徴量抽出が大切。

Agentとbrain(model)の使い分けてです。

modelには、できる限り処理された情報のみを入れたほうが、効率よく学習が進みます。また、actionが存在するかどうかの処理や、actionが有効かどうかの処理などは、やめたほうがいい。また、データを管理して学習を効率よく進める部分なども、やめたほうがいい。そのような、入力と出力のルール化みたいところを、ラップでくるんで行うのがAgentです。

action = agent(state)

主に3つの機能を有するべきです。

  • 入力データから特徴量を抽出する機能
  • 出力データの形式を整える機能
  • 学習を効率よく進める機能

10.1 コードを見ていきます。

import copy
import numpy as np
import dezero_emb as dezero
class DQNAgent:
  def __init__(self):
    self.epsilon = CFG_ML.initial_epsilon
    self.action_size = 2

    self.replay_buffer = ReplayBuffer(CFG_ML.buffer_size, CFG_ML.batch_size)
    self.qnet = DQNet()
    self.qnet_target = DQNet()
    self.optimizer = dezero.optimizers.Adam(CFG_ML.lr)
    self.optimizer.setup(self.qnet)

  def __call__(self, board, puyo):
    action_list = utils.create_action_list(board)

    next_boards = []
    next_reward =[]
    action =(2, 1)
    if len(action_list):
      for action in action_list:
        next_board, reward, done = utils.next_board(board, puyo, action)
        if not done:
          next_boards.append(next_board)
          next_reward.append(reward)
      
      next_boards = np.stack(next_boards)
      predictions = self.eval2(next_boards)
      
      next_reward =np.array(next_reward)[:, np.newaxis]
      predictions += dezero.Variable(next_reward)
      index = predictions.data.argmax()
      action = action_list[index]
    return action


  def boardtostate(self, board):
    cont_b = 2 ** np.arange(CFG.Width,dtype=np.int32)
    b1 = np.zeros(CFG.Height * CFG.Width,dtype = np.int32).reshape(CFG.Height , CFG.Width)
    b1[board == 1] = 1
    b2 = np.zeros(CFG.Height * CFG.Width,dtype = np.int32).reshape(CFG.Height , CFG.Width)
    b2[board == 2] = 1
    b3 = np.zeros(CFG.Height * CFG.Width,dtype = np.int32).reshape(CFG.Height , CFG.Width)
    b3[board == 3] = 1
    b4 = np.zeros(CFG.Height * CFG.Width,dtype = np.int32).reshape(CFG.Height , CFG.Width)
    b4[board == 4] = 1
    board_list = np.concatenate([b1,b2,b3,b4])
    state =  board_list.dot(cont_b)      
    return state

  def eval(self, board):
    state = self.boardtostate(board)      
    return self.qnet_target(state)

  def eval2(self, boards):
    states = []
    for i in range(boards.shape[0]):
      state = self.boardtostate(boards[i])
      states.append(state)
    states = np.stack(states)      
    return self.qnet_target(states)


  def update(self, board, action, reward, next_board, done):
    state =  self.boardtostate(board) 
    next_state =  self.boardtostate(next_board)      
    
    self.replay_buffer.add(state, action, reward, next_state, done)
    if not done:
      return
    if len(self.replay_buffer) < CFG_ML.batch_size:
      return
    state, action, reward, next_state, done = self.replay_buffer.get_batch()

    qs = self.qnet(state)
    next_qs = self.qnet_target(next_state)
    reward =reward[:,np.newaxis]
    done =done[:,np.newaxis]
    target = reward + (1 - done) * CFG_ML.gamma * next_qs

    self.qnet.cleargrads()
    loss = dezero.F.mean_squared_error(qs, target)
    loss.backward()
    self.optimizer.update()


  def sync_qnet(self):
    self.qnet_target = copy.deepcopy(self.qnet)

  def save_model(self,filename):
    self.qnet.save_weights(filename)

  def load_model(self,filename):
    self.qnet.load_weights(filename)
    self.qnet_target.load_weights(filename)

10.2 init

初期化には、agentが持つデータが定義されます。4つあります。

  • replay_buffer
  • DQNet : 訓練対象
  • target_DQNet : 評価用
  • optimizer : lossは関数を使うので、optimizerだけです。
    2つのmodelの使い分けですが、評価用のmodelで計算したpredictionsを使って、訓練用のmodelを学習させます。訓練後に、sync_qnetで同期します。

10.3 board to state

  • cont_bは、boardの横1行のデータを2進法でビット化するために使います。これで、12行6列の72個のデータを、12個に圧縮して特徴量にします。4色あるので、288個のデータが、48個になります。
  • np.concatenate([b1,b2,b3,b4]) : 4色の2次元データを連結しています。
  • board_list.dot(cont_b) : board_list と cont_b の行列積を計算します。

10.3 call

agent()のように呼び出されたときに、この関数が動きます。

  • action_list から next_board を計算して next_statesを作ります。fallblockは、blockを落とす場所をすれば、必ず決まった挙動をするゲームなので、計算可能です。計算ができないゲームでは、この手法は使えません。
  • next_statesから、Qを推測します(predictions)。predictionsにrewardを加えて、一番大きいものを選択します。

10.4 update

  • データをreplay bufferに入れていきます。
  • done(終了)で、バッチデータから学習をします。
  • qnet.cleargrads : 累積しているgradを0にします。
  • loss.backward : 逆伝播させます。
  • optimizer.update : パラメータに反映させます。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?