: 어떤 환경에서 어떤 행동을 했을 때 그것이 잘된 행동인지 잘못된 행동인지를 판단하고 보상 또는 벌칙을 주는 과정을 반복해서 스스로 학습하게 하는 분야
어떤 상태가 일정한 간격으로 변하고, 다음 상태는 현재 상태에만 의존하는 확률적 상태 변화
마르코프 특성을 지니는 이산 시간에 대한 확률 과정
: 시간에 따른 상태 변화
: 마르코프 프로세스에서 각 상태마다 좋고 나쁨이 추가된 확률 모델
웹 서핑 가치 = -2.4, 진찰 가치 = 1.2
γ = 0
γ = 0.9
웹 서핑 가치 = -24, 진찰 가치 = 0.3
: 마르코프 보상 과정에서 행동이 추가된 확률 모델
: 각각의 상태마다 행동 분포를 표현하는 함수
상태-가치 함수
: 주어진 정책 π에 따라 행동을 결정하면서 상태 s에서 얻을 수 있는 리턴의 기댓값
행동-가치 함수
: 상태 s에서 a라는 행동을 취했을 때 얻을 수 있는 리턴의 기댓값
가치함수를 계산하는 방법은 시간 복잡도가 필요해 상태 수가 많으면 적용하기 어렵다는 문제를 해결하는 방법
: 상태-가치 함수와 행동-가치 함수의 관계를 나타내는 방정식
: 정책을 고려한 다음 상태의 이동
: 벨만 방정식을 다이어그램으로 표현한 것
Step 1: 처음 에이전트가 접하는 상태 s나 행동 a를 임의의 값으로 설정
Step 2: 환경과 상호 작용하면서 얻은 보상과 상태에 대한 정보를 이용하여 어떤 상태에서 어떤 행동을 취하는 것이 최대의 보상을 얻을 수 있는지 판단
Step 3: 최적의 행동을 판단하는 수단이 상태-가치 함수, 행동-가치 함수이며 벨만 기대 방정식을 이용하여 이를 업데이트하면서 높은 보상을 얻을 수 있는 상태와 행동 학습
Step 4: 최대 보상을 갖는 행동을 선택하도록 최적화된 정책 찾기
: 미래 가치 함수 값을 이용하여 초기화된 임의의 값들을 업데이트하면서 최적의 가치함수로 다가가는 것
: 최대의 보상을 갖는 가치 함수
: 연속적으로 발생되는 문제를 수학적으로 최적화하여 풀어내는 것
: 최적의 정책을 가정하고 벨만 최적 방정식을 이용하여 순차적으로 행동 결정
: 큐-함수를 사용하여 최적화된 정책을 학습하는 강화 학습 기법
: 합성곱 신경망을 이용하여 큐 함수를 학습하는 강화 학습 기법
택시가 승객을 랜덤한 위치에서 태워 목적지까지 이동
########## 에이전트 구현
class Agent:
def __init__(self, env, optimizer): # 상태와 행동 초기화
self._state_size = env.observation_space.n
self._action_size = env.action_space.n
self._optimizer = optimizer
self.expirience_replay = deque(maxlen=2000) #과거 행동 기억 초기화
self.gamma = 0.6 # 할인율 초기화
self.epsilon = 0.1 # 탐험 비율 초기화
self.q_network = self.build_compile() # 큐 네트워크 구성
self.target_network = self.build_compile() # 타깃 큐 네트워크 구성
self.target_model()
def store(self, state, action, reward, next_state, terminated):
self.expirience_replay.append((state, action, reward, next_state, terminated))
def build_compile(self): # 네트워크 구성을 위한 함수
model = Sequential()
model.add(Embedding(self._state_size, 10, input_length=1))
model.add(Reshape((10,)))
model.add(Dense(50, activation='relu'))
model.add(Dense(50, activation='relu'))
model.add(Dense(50, activation='relu'))
model.add(Dense(self._action_size, activation='linear'))
model.compile(loss='mse', optimizer=self._optimizer)
return model
def target_model(self): # 가중치 적용하기 위한 함수
self.target_network.set_weights(self.q_network.get_weights())
def act(self, state): # 탐험을 위한 함수
if np.random.rand() <= self.epsilon: # 탐험(이동방향) 결정하는 방법: 임의의 랜덤 값을 선택하여 행동을 취하는 방법 선택
return env.action_space.sample()
q_values = self.q_network.predict(state)
return np.argmax(q_values[0])
def retrain(self, batch_size): # 큐 네트워크 훈련에 대한 함수
minibatch = random.sample(self.expirience_replay, batch_size) # 리플레이 메모리에서 랜덤한 데이터 선택
for state, action, reward, next_state, terminated in minibatch:
target = self.q_network.predict(state)
if terminated:
target[0][action] = reward
else:
t = self.target_network.predict(next_state)
target[0][action] = reward + self.gamma * np.amax(t)
self.q_network.fit(state, target, epochs=1, verbose=0) # 큐 네트워크 훈련
########## 훈련 준비
optimizer = Adam(learning_rate=0.01)
agent = Agent(env, optimizer)
batch_size = 32
num_of_episodes = 10
timesteps_per_episode = 10
agent.q_network.summary()
########## 모델 훈련
for e in range(0, num_of_episodes):
state = env.reset() # 환경 재설정
state = np.reshape(state, [1, 1])
reward = 0 # 보상 변수 초기화
terminated = False
for timestep in range(timesteps_per_episode):
action = agent.act(state)
next_state, reward, terminated, info = env.step(action) # 에이전트가 단계별 행동을 취함
next_state = np.reshape(next_state, [1, 1])
agent.store(state, action, reward, next_state, terminated)
state = next_state
if terminated:
agent.target_model()
break
if len(agent.expirience_replay) > batch_size:
agent.retrain(batch_size)
if (e + 1) % 10 == 0:
print("**********************************")
print("Episode: {}".format(e + 1))
env.render()
print("**********************************")
: 모든 트리 노드를 대상으로 탐색하는 대신 게임 시뮬레이션을 이용하여 가장 가능성이 높아 보이는 방향으로 행동 결정하는 탐색 방법
비어있는 보드 생성 후 플레이어에게서 입력을 받아 승리 조건 확인하고 승자를 선언하거나, 전체 보드가 채워졌음에도 아무도 이기지 않으면 결과 동점으로 선언
########## 보드 생성
boarder = {'1': ' ' , '2': ' ' , '3': ' ' ,
'4': ' ' , '5': ' ' , '6': ' ' ,
'7': ' ' , '8': ' ' , '9': ' ' }
board_keys = []
for key in boarder:
board_keys.append(key)
########## 화면 출력 함수 정의
def visual_Board(board_num):
print(board_num['1'] + '|' + board_num['2'] + '|' + board_num['3'])
print('-+-+-')
print(board_num['4'] + '|' + board_num['5'] + '|' + board_num['6'])
print('-+-+-')
print(board_num['7'] + '|' + board_num['8'] + '|' + board_num['9'])
########## 보드 이동 함수 정의
def game():
turn = 'X'
count = 0
for i in range(8):
visual_Board(boarder)
print("당신 차례입니다," + turn + ". 어디로 이동할까요?")
move = input()
if boarder[move] == ' ':
boarder[move] = turn
count += 1
else:
print("이미 채워져있습니다.\n어디로 이동할까요?")
continue
if count >= 5: # 플레이어가 다섯 번 이동 후 이겼는지 확인
if boarder['1'] == boarder['2'] == boarder['3'] != ' ':
visual_Board(boarder)
print("\n게임 종료.\n")
print(" ---------- " +turn + "가 승리했습니다. -----------")
break
elif boarder['4'] == boarder['5'] == boarder['6'] != ' ':
visual_Board(boarder)
print("\n게임 종료.\n")
print(" ---------- " +turn + "가 승리했습니다. -----------")
break
elif boarder['7'] == boarder['8'] == boarder['9'] != ' ':
visual_Board(boarder)
print("\n게임 종료.\n")
print(" ---------- " +turn + "가 승리했습니다. -----------")
break
elif boarder['1'] == boarder['4'] == boarder['7'] != ' ':
visual_Board(boarder)
print("\n게임 종료.\n")
print(" ---------- " +turn + "가 승리했습니다. -----------")
break
elif boarder['2'] == boarder['5'] == boarder['8'] != ' ':
visual_Board(boarder)
print("\n게임 종료.\n")
print(" ---------- " +turn + "가 승리했습니다. -----------")
break
elif boarder['3'] == boarder['6'] == boarder['9'] != ' ':
visual_Board(boarder)
print("\n게임 종료.\n")
print(" ---------- " +turn + "가 승리했습니다. -----------")
break
elif boarder['1'] == boarder['5'] == boarder['9'] != ' ':
visual_Board(boarder)
print("\n게임 종료.\n")
print(" ---------- " +turn + "가 승리했습니다. -----------")
break
elif boarder['3'] == boarder['5'] == boarder['7'] != ' ':
visual_Board(boarder)
print("\n게임 종료.\n")
print(" ---------- " +turn + "가 승리했습니다. -----------")
break
if count == 9: # 동점인 경우
print("\n게임 종료.\n")
print("동점입니다")
if turn =='X': # 움직임이 있을 때마다 플레이어 변경
turn = 'Y'
else:
turn = 'X'
if __name__ == "__main__":
game()
너무 유익한 내용이네요~