def __init__(self, point_reward=None, scope_limit=1, traning_count=2, learning_rate=0.1): ''' 初期化する Args: point_reward: 壁、スタート地点、ゴール地点の報酬 scope_limit: 深層ボルツマンマシンによる探索範囲 (例) 距離的な概念であるため 1なら上下左右斜め1個分隣のマスが範囲になる traning_count: 深層ボルツマンマシンの訓練回数 learning_rate: 深層ボルツマンマシンの学習率 ''' if point_reward is not None: self.__point_reward = point_reward self.__scope_limit = scope_limit neuron_count = self.__decide_neuron_count(scope_limit) self.__dbm = DeepBoltzmannMachine(DBMMultiLayerBuilder(), [neuron_count, 3, 1], SigmoidFunction(), ContrastiveDivergence(), learning_rate) self.__traning_count = traning_count
def __init__( self, point_reward=None, scope_limit=1, traning_count=2, learning_rate=0.1 ): ''' 初期化する Args: point_reward: 壁、スタート地点、ゴール地点の報酬 scope_limit: 深層ボルツマンマシンによる探索範囲 (例) 距離的な概念であるため 1なら上下左右斜め1個分隣のマスが範囲になる traning_count: 深層ボルツマンマシンの訓練回数 learning_rate: 深層ボルツマンマシンの学習率 ''' if point_reward is not None: self.__point_reward = point_reward self.__scope_limit = scope_limit neuron_count = self.__decide_neuron_count(scope_limit) self.__dbm = DeepBoltzmannMachine( DBMMultiLayerBuilder(), [neuron_count, 3, 1], SigmoidFunction(), ContrastiveDivergence(), learning_rate ) self.__traning_count = traning_count
class MazeDeepBoltzmannQLearning(object): ''' 深層強化学習による迷路探索 深層ボルツマンマシンを自己符号化器のように利用することで 状態の特徴を周辺の状態との関連から事前学習した上で Q学習を実行する ''' # 迷路探索のインターフェイス __maze_q_learning_interface = None def get_maze_q_learning_interface(self): if isinstance(self.__maze_q_learning_interface, MazeQLearningInterface) is False: raise TypeError() return self.__maze_q_learning_interface def set_maze_q_learning_interface(self, value): if isinstance(value, MazeQLearningInterface) is False: raise TypeError() self.__maze_q_learning_interface = value # 迷路探索のインターフェイスを実現したオブジェクトのプロパティ maze_q_learning_interface = property(get_maze_q_learning_interface, set_maze_q_learning_interface) # 深層ボルツマンマシンのオブジェクト __dbm = None # 訓練回数 __traning_count = 2 # 各地点の報酬 __point_reward = { "S": 1, # スタート地点 "G": 100, # ゴール地点 "#": 0, # 壁 "NULL": 0 # scope_limit分進んだ場合にマップ外になる場合 } # 探索範囲 __scope_limit = 1 def __init__( self, point_reward=None, scope_limit=1, traning_count=2, learning_rate=0.1 ): ''' 初期化する Args: point_reward: 壁、スタート地点、ゴール地点の報酬 scope_limit: 深層ボルツマンマシンによる探索範囲 (例) 距離的な概念であるため 1なら上下左右斜め1個分隣のマスが範囲になる traning_count: 深層ボルツマンマシンの訓練回数 learning_rate: 深層ボルツマンマシンの学習率 ''' if point_reward is not None: self.__point_reward = point_reward self.__scope_limit = scope_limit neuron_count = self.__decide_neuron_count(scope_limit) self.__dbm = DeepBoltzmannMachine( DBMMultiLayerBuilder(), [neuron_count, 3, 1], SigmoidFunction(), ContrastiveDivergence(), learning_rate ) self.__traning_count = traning_count def initialize(self, square_map_data): ''' 迷路を初期化する 文字列の迷路マップデータ:square_map_dataを2次元のリスト:map_data_listに格納する。 深層ボルツマンマシンにより、迷路マップデータの特徴を学習した上でQ学習を開始するべく、 前処理を実行していく Args: square_map_data: n×nの二次元リストに格納されることを前提としたCSV形式の文字列 ''' map_data_matrix = [] [map_data_matrix.append(line.split(",")) for line in square_map_data.split("\n") if line.strip() != ""] all_count = len(map_data_matrix) * len(map_data_matrix[0]) map_vector_matrix = [] vector_matrix = [] for i in range(len(map_data_matrix)): map_vector_list = [] for j in range(len(map_data_matrix[i])): vector_list = [] for k in range(i - self.__scope_limit, i + self.__scope_limit + 1): for l in range(j - self.__scope_limit, j + self.__scope_limit + 1): if k < 0 or k >= len(map_data_matrix): vector_list.append(self.__point_reward["NULL"]) else: if l < 0 or l >= len(map_data_matrix[k]): vector_list.append(self.__point_reward["NULL"]) else: if map_data_matrix[k][l] in self.__point_reward: reward = self.__point_reward[map_data_matrix[k][l]] / all_count else: reward = float(map_data_matrix[k][l]) / all_count vector_list.append(reward) map_vector_list.append(vector_list) vector_matrix.append(vector_list) map_vector_matrix.append(map_vector_list) self.__dbm.learn(vector_matrix, traning_count=self.__traning_count) map_feature_matrix = [] for i in range(len(map_vector_matrix)): map_feature_list = [] for j in range(len(map_vector_matrix[i])): # ヘブ則的連想 self.__dbm.learn([map_vector_matrix[i][j]], traning_count=1) if map_data_matrix[i][j] not in self.__point_reward: map_feature_list.append( self.__dbm.get_feature_point_list(1)[0] ) else: map_feature_list.append( map_data_matrix[i][j] ) map_feature_matrix.append(map_feature_list) square_map_data = "\n".join( [",".join([str(map_feature) for map_feature in map_feature_list]) for map_feature_list in map_feature_matrix] ) self.maze_q_learning_interface.initialize(square_map_data) def learning(self, limit=1000): ''' Q学習を実行する Args: limit: 学習回数 ''' self.maze_q_learning_interface.learn(limit=limit) def __decide_neuron_count(self, scope_limit): ''' 探索範囲に応じてニューロン数を調節する Args: scope_limit: 探索範囲 ''' return ((scope_limit * 2) + 1) ** 2
class MazeDeepBoltzmannQLearning(object): ''' 深層強化学習による迷路探索 深層ボルツマンマシンを自己符号化器のように利用することで 状態の特徴を周辺の状態との関連から事前学習した上で Q学習を実行する ''' # 迷路探索のインターフェイス __maze_q_learning_interface = None def get_maze_q_learning_interface(self): if isinstance(self.__maze_q_learning_interface, MazeQLearningInterface) is False: raise TypeError() return self.__maze_q_learning_interface def set_maze_q_learning_interface(self, value): if isinstance(value, MazeQLearningInterface) is False: raise TypeError() self.__maze_q_learning_interface = value # 迷路探索のインターフェイスを実現したオブジェクトのプロパティ maze_q_learning_interface = property(get_maze_q_learning_interface, set_maze_q_learning_interface) # 深層ボルツマンマシンのオブジェクト __dbm = None # 訓練回数 __traning_count = 2 # 各地点の報酬 __point_reward = { "S": 1, # スタート地点 "G": 100, # ゴール地点 "#": 0, # 壁 "NULL": 0 # scope_limit分進んだ場合にマップ外になる場合 } # 探索範囲 __scope_limit = 1 def __init__(self, point_reward=None, scope_limit=1, traning_count=2, learning_rate=0.1): ''' 初期化する Args: point_reward: 壁、スタート地点、ゴール地点の報酬 scope_limit: 深層ボルツマンマシンによる探索範囲 (例) 距離的な概念であるため 1なら上下左右斜め1個分隣のマスが範囲になる traning_count: 深層ボルツマンマシンの訓練回数 learning_rate: 深層ボルツマンマシンの学習率 ''' if point_reward is not None: self.__point_reward = point_reward self.__scope_limit = scope_limit neuron_count = self.__decide_neuron_count(scope_limit) self.__dbm = DeepBoltzmannMachine(DBMMultiLayerBuilder(), [neuron_count, 3, 1], SigmoidFunction(), ContrastiveDivergence(), learning_rate) self.__traning_count = traning_count def initialize(self, square_map_data): ''' 迷路を初期化する 文字列の迷路マップデータ:square_map_dataを2次元のリスト:map_data_listに格納する。 深層ボルツマンマシンにより、迷路マップデータの特徴を学習した上でQ学習を開始するべく、 前処理を実行していく Args: square_map_data: n×nの二次元リストに格納されることを前提としたCSV形式の文字列 ''' map_data_matrix = [] [ map_data_matrix.append(line.split(",")) for line in square_map_data.split("\n") if line.strip() != "" ] all_count = len(map_data_matrix) * len(map_data_matrix[0]) map_vector_matrix = [] vector_matrix = [] for i in range(len(map_data_matrix)): map_vector_list = [] for j in range(len(map_data_matrix[i])): vector_list = [] for k in range(i - self.__scope_limit, i + self.__scope_limit + 1): for l in range(j - self.__scope_limit, j + self.__scope_limit + 1): if k < 0 or k >= len(map_data_matrix): vector_list.append(self.__point_reward["NULL"]) else: if l < 0 or l >= len(map_data_matrix[k]): vector_list.append(self.__point_reward["NULL"]) else: if map_data_matrix[k][ l] in self.__point_reward: reward = self.__point_reward[ map_data_matrix[k][l]] / all_count else: reward = float( map_data_matrix[k][l]) / all_count vector_list.append(reward) map_vector_list.append(vector_list) vector_matrix.append(vector_list) map_vector_matrix.append(map_vector_list) self.__dbm.learn(vector_matrix, traning_count=self.__traning_count) map_feature_matrix = [] for i in range(len(map_vector_matrix)): map_feature_list = [] for j in range(len(map_vector_matrix[i])): # ヘブ則的連想 self.__dbm.learn([map_vector_matrix[i][j]], traning_count=1) if map_data_matrix[i][j] not in self.__point_reward: map_feature_list.append( self.__dbm.get_feature_point_list(1)[0]) else: map_feature_list.append(map_data_matrix[i][j]) map_feature_matrix.append(map_feature_list) square_map_data = "\n".join([ ",".join([str(map_feature) for map_feature in map_feature_list]) for map_feature_list in map_feature_matrix ]) self.maze_q_learning_interface.initialize(square_map_data) def learning(self, limit=1000): ''' Q学習を実行する Args: limit: 学習回数 ''' self.maze_q_learning_interface.learn(limit=limit) def __decide_neuron_count(self, scope_limit): ''' 探索範囲に応じてニューロン数を調節する Args: scope_limit: 探索範囲 ''' return ((scope_limit * 2) + 1)**2
# 深層ボルツマンマシンの引数の形式に前処理する traning_y = traning_y.reshape((len(traning_y), 1)) data_arr = np.hstack((traning_y, traning_x)) traning_data_matrix = list(data_arr) test_y = test_y.reshape((len(test_y), 1)) data_arr = np.hstack((test_y, test_x)) test_data_matrix = list(data_arr) evaluate_data_list = [] # 深層ボルツマンマシンを構築する(第二引数の各層のニューロンの個数はデモのためアトランダムに規定) dbm = DeepBoltzmannMachine( DBMMultiLayerBuilder(), [len(traning_data_matrix[0]), 8, 6, 4, 2], LogisticFunction(), ContrastiveDivergence(), 0.05 ) dbm.learn(traning_data_matrix, traning_count=1) evaluate_dict = dbm.evaluate_bool(test_data_matrix) evaluate_data_list.append(evaluate_dict) dbm = DeepBoltzmannMachine( DBMMultiLayerBuilder(), [len(traning_data_matrix[0]), 8, 6, 4], LogisticFunction(), ContrastiveDivergence(), 0.05 ) dbm.learn(traning_data_matrix, traning_count=1)