- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- 強化学習/LEGO MINDSTORMS EV3で強化学習する へ行く。
- 1 (2017-10-18 (水) 21:48:14)
- 2 (2017-10-26 (木) 15:07:26)
- 3 (2018-01-26 (金) 11:03:30)
はじめに †
LEGO MINDSTORMS EV3でライントレースを強化学習します。
まずは、EV3でPythonを動かせるようにします。
- LEGO MINDSTORMS EV3でPythonを使う - とうごろうぃき
準備 †
numpyをEV3にインストールします。
robot@ev3dev:~$ sudo apt-get update robot@ev3dev:~$ sudo apt-get install python3-numpy
クラス構造 †
- 環境を表す Environment
- EV3のライントレースを表す EV3LineTrace
- 強化学習エージェントを表す ReinformentLearningAgent
- Q学習エージェントを表す QLearningAgent
Environmentクラス、ReinformentLearningAgentクラス、QLearningAgentクラスは、「Pythonで強化学習する」で作成したものと同じです。
EV3のライントレース EV3LineTrace †
#!/usr/bin/python3 # -*- coding: utf-8 -*- # # ev3lt.py # # Copyright 2017-2018 Tohgoroh Matsui All Rights Reserved. # import ev3dev.ev3 as ev3 import environment as env import numpy as np import time class EV3LineTrace(env.Environment): """EV3でライントレース問題。状態は (左光センサー観測値, 右光センサー観測値) で表される。""" states = 4 # 状態数 actions = 2 # 行動数 motor_l = ev3.LargeMotor('outB') # 左モーター motor_r = ev3.LargeMotor('outC') # 右モーター sensor_l = ev3.LightSensor('in2') # 左光センサー sensor_r = ev3.LightSensor('in3') # 右光センター sleep = 0.1 # スリープ時間 @classmethod def init_state(cls): """初期状態として現在の状態を返す。""" state = cls.get_state() return state @classmethod def is_terminal(cls, state): """渡された状態が終端状態ならTrue, そうでないならFalseを返す。""" return False @classmethod def get_state(cls): """現在の状態(センサーの値)を返す。""" light_l = cls.sensor_l.reflected_light_intensity # 左側光センサーの反射光の強さ light_r = cls.sensor_r.reflected_light_intensity # 右側光センサーの反射光の強さ return (light_l, light_r) @classmethod def get_s(cls, state): """状態を状態番号に変換して返す。""" light_l, light_r = state[0], state[1] if light_l < 40 and light_r < 40: s = 0 elif light_l < 40: s = 1 elif light_r < 40: s = 2 else: s = 3 return s @classmethod def get_a(cls, action): """行動を行動番号に変して返す。""" return action @classmethod def get_reward(cls, state): """報酬を返す。""" light_l, light_r = state[0], state[1] if light_l < 40 or light_r < 40: # どちらかの光センサーの値が40未満(黒)なら reward = 1.0 else: reward = -0.01 return reward @classmethod def take_action(cls, state, action): """行動を実行して状態を更新し、報酬と次の状態を返す。""" if action == 0: state_ = cls.turn_l() else: state_ = cls.turn_r() reward = cls.get_reward(state_) return reward, state_, @classmethod def str_state(cls, state): """状態を表す文字列を返す。""" light_l, light_r = state[0], state[1] return '(%.3f, %.3f)' % (light_l, light_r) @classmethod def str_action(cls, action): """行動を表す文字列を返す。""" if action == 0: str = 'turnL' else: str = 'turnR' return str @classmethod def turn_l(cls): """左に曲がる。""" cls.motor_l.run_forever(speed_sp=-25) # 左のモーターを後ろに、 cls.motor_r.run_forever(speed_sp=100) # 右のモーターを前に回す time.sleep(cls.sleep) state_ = cls.get_state() return state_ @classmethod def turn_r(cls): """右に曲がる。""" cls.motor_l.run_forever(speed_sp=100) # 左のモーターを前に、 cls.motor_r.run_forever(speed_sp=-25) # 右のモーターを後ろに回す time.sleep(cls.sleep) state_ = cls.get_state() return state_ @classmethod def stop(cls): """止まる。""" cls.motor_l.stop() cls.motor_r.stop() def __init__(self): super().__init__()
実行用ファイル †
#!/usr/bin/python3 # -*- coding: utf-8 -*- # # ev3ltql.py # # Copyright 2017-2018 Tohgoroh Matsui All Rights Reserved. # import ev3lt import qlagent if __name__ == '__main__': ev3lt = ev3lt.EV3LineTrace() # 環境 agent = qlagent.QLearningAgent(environment=ev3lt, epsilon=0.1, max_steps=10000, evaluation=False, verbose_level=2) # Q学習エージェント agent.learn() # 学習する
実行 †
$ python3 ev3ltql.py # 0, (59.2, 65.5), turnR, -0.010000, (58.8, 65.1) # 1, (58.8, 65.1), turnL, -0.010000, (58.8, 64.7) # 2, (58.8, 64.7), turnR, -0.010000, (57.9, 64.3) # 3, (57.9, 64.3), turnL, -0.010000, (58.4, 64.0) # 4, (58.4, 64.0), turnL, 1.000000, (33.1, 63.7) # 5, (33.1, 63.7), turnL, 1.000000, (58.4, 36.1) # 6, (58.4, 36.1), turnR, -0.010000, (58.0, 56.1) # 7, (58.0, 56.1), turnL, -0.010000, (58.1, 52.7) # 8, (58.1, 52.7), turnL, -0.010000, (58.1, 63.7) # 9, (58.1, 63.7), turnL, -0.010000, (58.3, 63.7)