# 에피소드 수만큼 학습
episode_count=1000
# 플레이를 저장할 메모리 리스트를 만듬
# 최근 플레이 10000개까지 기억 - 넘기면 앞쪽 기억은 삭제
memory=deque(maxlen=10000)
# 점수를 기록할 리스트
scores = []
# E-Greedy 에서 탐험할 입실론 - epsilon_decay 만큼 조금씩 줄어들어 min값으로 변경됨
epsilon= 0.9
epsilon_min = 0.1
epsilon_decay = epsilon_min / epsilon
epsilon_decay = epsilon_decay ** (1. / float(300))
# 배치 사이즈
batch_size=64
# 리워드 할인율
reward_discount_rate=0.999
# 타겟데이터 업데이트 비율
train_count=0
target_update_count=30
for episode in range(episode_count):
state = env.reset()
# 차원을 맞추어 준다
state = np.reshape(state, [1, state_num])
done = False
total_reward = 0
while not done:
# 입실론값보다 작으면 랜덤 / 아니면 DQN모델에 물어보고 가장 점수가 높은 행동을 한다
if(np.random.rand()) < epsilon:
action=env.action_space.sample()
else:
q_val=dqn_model.predict(state)
action=np.argmax(q_val[0])
next_state, reward, done, _ = env.step(action)
next_state = np.reshape(next_state, [1, state_num])
i=(state,action,reward/100.,next_state,done)
# 메모리에 작업 내용을 기록한다
memory.append(i)
# 다음상태를 현사태로 변경하여 계속 진행한다
state = next_state
total_reward += reward
# 메모리가 일정량 차면 학습 (배치 사이즈보단 커야 함)
if len(memory) >= 1000:
sample=random.sample(memory,batch_size)
# 학습에 쓰일 리스트
state_batch=[]
q_val_batch=[]
# 샘플에 있던 내용으로 학습
for _state,_action,_reward,_next_state,_done in sample:
q_val=dqn_model.predict(_state)
# dqn - q=r + d_r*max(q')
target_q_val=_reward+ reward_discount_rate * np.max(target_model.predict(_next_state)[0])
#double-dqn
# target_q_val=np.argmax(dqn_model.predict(_next_state)[0])
# target_q_val=target_model.predict(_next_state)[0][target_q_val]
# target_q_val=_reward+ reward_discount_rate * target_q_val
if _done:
q_val[0][_action] = _reward
else:
q_val[0][_action] = target_q_val
state_batch.append(_state[0])
q_val_batch.append(q_val[0])
# 학습하고 타겟모델을 DQN모델로 업데이트 하고, 입실론 값을 줄임
dqn_model.train_on_batch(np.array(state_batch),np.array(q_val_batch))
if(epsilon>epsilon_min):
epsilon *= epsilon_decay
train_count=train_count+1
if train_count%target_update_count==0:
target_model.set_weights(dqn_model.get_weights())
print('타겟모델 업데이트')
scores.append(total_reward)
if(total_reward>450):
dqn_model.save('/gdrive/My Drive/hjk_dqn_r1_model.h5')
mean_score = np.mean(scores)
print(episode+1,total_reward,epsilon)
if (episode+1) % 20 == 0:
print("Episode %d: Mean survival = %0.2lf in %d episodes" %(episode+1, mean_score, 20))
if mean_score >= 400:
break
scores = []
env.close()