elif map_[state[0]][state[1] - 1] == '1': feasible[2] = False # 우 if state[1] >= width - 1: feasible[3] = False elif map_[state[0]][state[1] + 1] == '1': feasible[3] = False return feasible if __name__ == '__main__': ### 3. 기본정보 및 하이퍼파라미터 입력 ### fn = input('파일 이름 입력(예: map.txt):') # 파일 이름 입력 lr = float(input('학습률 입력:')) # 학습률 입력 isPrint = True # 출력 여부 (map_, width, height) = mapReader.readMap(fn, True) # 맵 읽기 Qtable = mapReader.initQtable(width, height) # Q table 초기화 ### 4. 사용자 입력 ### while (1): print('') c = int(input('옵션 입력(0: 학습, 1: 실행, 2: 종료):')) if c == 0: d = int( input( '학습방법 입력(0: 기존 Q-network대로 학습, 1: 학습률을 적용하여 Non-deterministic에 최적화)' )) learning(map_, width, height, Qtable, d, lr, isPrint) elif c == 1: execute(map_, width, height, Qtable, isPrint) elif c == 2: break
def learnFrozenLake(fn, isStochastic, lrStochastic, lrDeepQ, isPrint, deviceName): ## 4-0. 맵 읽고 Q-table 초기화하기 ## info = mapReader.readMap(fn, False) # 맵 읽기 map_ = info[0] width = info[1] # 맵의 가로 길이 height = info[2] # 맵의 세로 길이 Qtable = mapReader.initQtable(width, height) # Q-table 초기화 ## 4-1. Q-learning으로 일단 학습 ## if isPrint: print('\n\n---< 1. Q-learning으로 학습 >---') if isStochastic: data = Qlearning_stochastic.learning(map_, width, height, Qtable, 1, lrStochastic, isPrint) else: data = Qlearning.learning(map_, width, height, Qtable, 0, isPrint) # (S, A, R, S) set의 집합 ## 4-2. 1의 학습 결과 데이터를 사용할 수 있는 데이터로 변환 및 학습 데이터 생성 # Neural Network로 학습시키기 위한 (state, action별 reward)를 저장하기 위한 배열 stateInfo = [] # 형식은 [세로좌표][가로좌표][action별 보상] for i in range(height): temp = [] for j in range(width): temp.append([0, 0, 0, 0]) stateInfo.append(temp) # 학습 데이터 (state, action별 reward) 생성 states = [] # one-hot 적용 outputs = [] # state0, state1에 one-hot을 적용. # width=W, height=H이면 state = [w0, w1, ..., w(W-1), h0, h1, ..., h(H-1)]꼴 # 여기서 현재 위치의 좌표가 (wX, hY)이면 state에서 wX=1, hY=1이고 나머지는 모두 0 # action에 one-hot을 적용. # action = [0, 0, 0, 0]으로 초기화하고 action의 번호가 A이면 action[A]=1로 수정하여 해당 부분만 1로 적용. for i in range(len(data)): # state(t) state0 = [0]*(width+height) # state(t)의 좌표를 (wX, hY)라고 하면 state0[data[i][0][1]] = 1 # state(t)의 wX를 1로 적용 state0[width + data[i][0][0]] = 1 # state(t)의 hY를 1로 적용 # action(t) action0 = [0, 0, 0, 0] action0[data[i][1]] = 1 # reward(t+1) reward1 = data[i][2] # state(t+1) state1 = [0]*(width+height) # state(t+1)의 좌표를 (wX, hY)라고 하면 state1[data[i][3][1]] = 1 # state(t+1)의 wX를 1로 적용 state1[width + data[i][3][0]] = 1 # state(t+1)의 hY를 1로 적용 # 행동을 할 때마다 stateInfo 테이블의 action별 reward 갱신 stateInfo[data[i][0][0]][data[i][0][1]][data[i][1]] = reward1 if i >= len(data)-800: # 마지막 800개만 학습 states.append(state0) # 학습 데이터의 state 부분 temp = [] for j in range(4): rewardVal = stateInfo[data[i][0][0]][data[i][0][1]][j] rewardVal = 1 / (1 + math.exp(-rewardVal)) # sigmoid 함수 적용 temp.append(rewardVal) # 학습 데이터의 action별 reward 부분 outputs.append(temp) # 학습 데이터 일부 출력 if isPrint: print('<학습 데이터 일부>') for i in range(50): print(str(states[i]) + ': ' + str(np.array(outputs[i]))) ## 4-3. Deep Q Learning으로 학습 ## if isPrint: print('\n\n---< 2. Deep learning으로 학습 >---') model = create_model([tf.keras.layers.Flatten(input_shape=(width+height,)), keras.layers.Dense(64, activation='relu'), keras.layers.Dense(64, activation='relu'), keras.layers.Dense(4, activation='sigmoid')], tf.keras.optimizers.Adam(0.001), 'mean_squared_error', isPrint) learning(model, [states], [outputs], 'FrozenLake', 4, deviceName) ## 4-4. 테스트 ## if isPrint: print('\n\n---<3. 테스트>---') # 기존에 학습한 결과 불러오기 jsonFile = open('FrozenLake.json', 'r') loaded_model_json = jsonFile.read() jsonFile.close() newModel = tf.keras.models.model_from_json(loaded_model_json) newModel.load_weights('FrozenLake.h5') if isPrint: newModel.summary() newModel.compile(optimizer=tf.keras.optimizers.Adam(0.001), loss='mean_squared_error', metrics=['accuracy']) Qtable = mapReader.initQtable(width, height) # Q-table 초기화 state = [0, 0] # 상태 초기화 # Q table의 값들을 model로부터 얻은 보상 값들로 바꾸기 input_ = newModel.input output_ = [layer.output for layer in newModel.layers] func = K.function([input_, K.learning_phase()], output_) # state [i, j] 들을 입력으로 받음 testInput = [] for i in range(height): for j in range(width): temp = [0]*(width+height) # testInput에 추가할 배열 temp[j] = 1 temp[width+i] = 1 testInput.append(temp) testInput = np.array(testInput) # state [i, j] 들에 대한 output layer 출력값(action별 보상)의 9.9배를 Q table의 해당 값으로 result = func([testInput, 1]) print('\n\n< deep-learned Q-table >') for i in range(height): for j in range(width): for k in range(4): Qtable[i][j][k] = result[3][i*width+j][k] * 9.9 if isPrint: print('Qtable index ' + str(i) + ',' + str(j) + ' -> ' + str(result[3][i*width+j])) # 실행 및 맵 출력 if isStochastic: Qlearning_stochastic.execute(map_, width, height, Qtable, True) else: Qlearning.execute(map_, width, height, Qtable, True)