質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
強化学習

強化学習とは、ある環境下のエージェントが現状を推測し行動を決定することで報酬を獲得するという見解から、その報酬を最大限に得る方策を学ぶ機械学習のことを指します。問題解決時に得る報酬が選択結果によって変化することで、より良い行動を選択しようと学習する点が特徴です。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

966閲覧

numpy.whereでエージェントの初期位置のインデックスを決定したいです

tebask

総合スコア2

強化学習

強化学習とは、ある環境下のエージェントが現状を推測し行動を決定することで報酬を獲得するという見解から、その報酬を最大限に得る方策を学ぶ機械学習のことを指します。問題解決時に得る報酬が選択結果によって変化することで、より良い行動を選択しようと学習する点が特徴です。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/07/08 08:56

前提・実現したいこと

PythonにてQ学習のプログラムを組んでみました。
具体的には迷路をQ学習で解くプログラムです。
######エージェントのスタート位置の決定方法をできるだけ汎用性を高くするため、numpy.where関数を用いてスタートのインデックスを決定しようと思っています。

繰り返し学習を行うので、その都度reset()で初期座標に戻します。
しかし、毎回スタートのインデックスがずれていしまいます。
今回使用した迷路は左下がスタート、右下がゴールなので、エージェントの初期位置は常に[13,1]を返してほしいのですが、、、
改善方法等教えていただければ幸いです。
使用した迷路は壁を0、通路を1、スタートを2、ゴールを3で表現した15x15の配列です。
また、main()内で1度通った道を4に書き換えていくことで、引き返さないようにしています。

迷路の配列
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 1 0 1 1 1 1 1 1 1 1 1 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 1 0 1 1 1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 0 0 1 0 0 0 0 0 1 0
0 1 0 1 0 1 1 1 1 1 0 1 1 1 0
0 1 0 1 0 1 0 1 0 0 0 0 0 0 0
0 1 0 1 0 1 0 1 1 1 1 1 1 1 0
0 1 0 1 0 1 0 0 0 0 0 1 0 0 0
0 1 0 1 0 1 1 1 1 1 0 1 1 1 0
0 0 0 1 0 1 0 0 0 1 0 0 0 0 0
0 1 1 1 0 1 0 1 1 1 1 1 1 1 0
0 1 0 0 0 1 0 0 0 0 0 0 0 1 0
0 2 0 1 1 1 1 1 0 1 1 1 1 3 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

発生している問題・エラーメッセージ

Episode:1, start:[[13] [ 1]] Episode:2, start:[[14] [ 1]] Episode:3, start:[[13] [ 1]] Episode:4, start:[[12] [ 2]] Episode:5, start:[[12] [ 2]] Episode:6, start:[[13] [ 2]] Episode:7, start:[[14] [ 2]] Episode:8, start:[[13] [ 2]] Episode:9, start:[[13] [ 1]] Episode:10, start:[[13] [ 2]] Episode:11, start:[[12] [ 3]] Episode:12, start:[[10] [ 4]] Episode:13, start:[[11] [ 4]] Episode:14, start:[[11] [ 4]]

該当のソースコード

python

1import numpy as np 2import matplotlib as mpl 3import matplotlib.pyplot as plt 4class MyEnviromentSimurator(): 5 def __init__(self, maze_name): 6 self._maze=np.loadtxt(f'{maze_name}', delimiter=' ',dtype='int32') 7 self._base=np.loadtxt(f'{maze_name}', delimiter=' ',dtype='int32') 8 self._prime=np.where(self._base==2) 9 self.reset() 10 11 def reset(self): 12 self._maze=self._base #迷路のリセット 13 self._state=list(self._prime) #初期座標のリセット 14 return np.array(self._maze), np.array(self._state) 15 16 def step(self, action): #報酬設定 17 reward=0 18 if action==0: 19 self._state[0]-=1 20 elif action==1: 21 self._state[1]+=1 22 elif action==2: 23 self._state[0]+=1 24 else: 25 self._state[1]-=1 26 b=self._maze[self._state[0], self._state[1]] 27 if b==3: #goal 28 reward=1 29 elif b==0: #wall 30 reward=-1 31 elif b==1: #road 32 reward=-0.01 33 else: #start 34 reward=-0.5 35 return np.array(self._state), reward 36 37class MyQtable(): 38 def __init__(self, maze_size): 39 self._Qtable=np.zeros((4, maze_size, maze_size)) 40 41 def get_action(self, state, epsilon): 42 if epsilon > np.random.uniform(0, 1): 43 next_action=np.random.choice([0, 1, 3, 4]) 44 else: 45 a=np.where(self._Qtable[:, state[0], state[1]]==self._Qtable[:, state[0], state[1]].max())[0] 46 next_action=np.random.choice(a) 47 return next_action 48 49 def update_Qtable(self, state, action, next_state, reward): 50 alpha=0.5 51 gamma=0.9 52 next_maxQ=max(self._Qtable[:, next_state[0], next_state[1]]) 53 self._Qtable[action, state[0], state[1]] = (1-alpha)*self._Qtable[action, state[0], state[1]] + alpha*( reward + gamma*next_maxQ ) 54 return self._Qtable 55 56def main(): 57 maze_size=15 58 maze_name='maze15x15_0.txt' 59 num_episodes=500 60 max_number_of_steps=300 61 epsilon=np.linspace(start=0.0, stop=0.0, num=num_episodes) 62 env=MyEnviromentSimurator(maze_name) 63 tab=MyQtable(maze_size) 64 for episode in range(num_episodes): 65 maze, state=env.reset() 66 print(f'Episode:{episode+1},\nstate:{state}') 67 episode_reward=0 68 for t in range(max_number_of_steps): 69 action=tab.get_action(state, epsilon[episode]) 70 next_state, reward=env.step(action) 71 q_table=tab.update_Qtable(state, action, next_state, reward) 72 state=next_state 73 maze[state[0], state[1]]=4 74 episode_reward+=reward 75 if episode_reward<=-0.5 or episode_reward>0: 76 break 77 78if __name__=='__main__': 79 main() 80

試したこと

スタート位置を直接数値として与えた場合は迷路を解くことが出来ました。なので、プログラム全体としては間違ってはいないと思います。

補足情報(FW/ツールのバージョンなど)

python 3.8.8
numpy 1.20.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

python

1 def reset(self): 2 self._maze=self._base #迷路のリセット 3 self._state=list(self._prime) #初期座標のリセット 4 return np.array(self._maze), np.array(self._state)

では、self._mazeがself._baseと同じものになってしまっています。
そのため、次回からは変更された_baseをもとに開始してしまいます。

python

1 def reset(self): 2 self._maze=self._base.copy #迷路のリセット 3 self._state=list(self._prime) #初期座標のリセット 4 return np.array(self._maze), np.array(self._state)

に修正してコピーを使うようにしましょう。

投稿2021/07/08 09:42

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tebask

2021/07/08 11:02

無事に改善することが出来ました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問