大家好,我是毛毛。
今天是Day 25
換個實驗環境啦~這次是MountainCar~ ヽ(✿゚▽゚)ノ
上圖就是Gym中MountainCar-v0的實驗圖
import os
import gym
import random
import numpy as np
from collections import deque
from keras.optimizers import Adam
from keras.models import Sequential
from keras.layers import Dense, Dropout
引入需要的相關套件。
這次也是一樣,先完成DQN的class,可能看起來會跟CartPole的很類似
def __init__(self, env, gamma=0.85, epsilon=1.0, epsilon_min=0.01, epsilon_decay=0.995, learning_rate=0.005, tau = .125):
self.env = env
self.memory = deque(maxlen=2000)
self.gamma = gamma
self.epsilon = epsilon
self.epsilon_min = epsilon_min
self.epsilon_decay = epsilon_decay
self.learning_rate = learning_rate
self.tau = tau
self.eval_net = self.__build_network()
self.target_net = self.__build_network()
這邊也是在設定神經網路的相關參數,因為eval_net和target_net的神經網路架構是一樣的,所以透過__build_network()
去建立這兩個神經網路就好,不用打兩段一樣的程式碼。
def __build_network(self):
model = Sequential()
state_shape = self.env.observation_space.shape
model.add(Dense(24, input_dim=state_shape[0], activation="relu"))
model.add(Dense(48, activation="relu"))
model.add(Dense(24, activation="relu"))
model.add(Dense(self.env.action_space.n))
model.compile(loss="mean_squared_error", optimizer=Adam(lr=self.learning_rate))
return model
這邊也跟CartPole的時候一樣,在這個function中建立eval_net和target_net,並透過compile函數定義損失函數(loss)、優化函數(optimizer)及成效衡量指標(mertrics)。
def target_replacement(self):
weights = self.eval_net.get_weights()
target_weights = self.target_net.get_weights()
for i in range(len(target_weights)):
target_weights[i] = weights[i] * self.tau + target_weights[i] * (1 - self.tau)
self.target_net.set_weights(target_weights)
target_net需要透過eval_net的權重來更新自己的神經網路的權重。
只是這邊不是完全取代舊的權重,而是根據比例去得到新的權重來更新target_net。
def store_transition(self, state, action, reward, new_state, terminal):
self.memory.append([state, action, reward, new_state, terminal])
這邊是將當下的資訊存起來。
def replay_transition(self):
batch_size = 32
if len(self.memory) < batch_size:
return
samples = random.sample(self.memory, batch_size)
for sample in samples:
state, action, reward, new_state, terminal = sample
target = self.target_net.predict(state)
if terminal:
target[0][action] = reward
else:
Q_future = max(self.target_net.predict(new_state)[0])
target[0][action] = reward + Q_future * self.gamma
self.eval_net.fit(state, target, epochs=1, verbose=0)
這裡就是要隨機地選取過去的經驗,來訓練model。
def choose_action(self, state):
self.epsilon *= self.epsilon_decay
self.epsilon = max(self.epsilon_min, self.epsilon)
if np.random.random() < self.epsilon:
return self.env.action_space.sample()
return np.argmax(self.eval_net.predict(state)[0])
這邊也是一樣,選取動作透過epsilon-greedy的方法。
def save_weights(self, filename):
self.eval_net.save_weights(filename)
print("=================Weights have saved=================")
儲存eval_net的權重。
def load_weights(self, filename):
self.eval_net.load_weights(filename, by_name=True)
讀取eval_net之前訓練的權重。
def get_weights(self):
return self.eval_net.get_weights()
得到現在eval_net的權重,用來看權重使否更新到。
今天就先到這啦,明天在來實際跑MountainCar 0(:3 )~ ('、3_ヽ)_
大家明天見
Reference