大家好,我是毛毛。
今天是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