Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
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)