Triển khai các thuật toán

Một phần của tài liệu Báo cáo đề tài reinforcement learning nhóm 8 (Trang 27 - 31)

CHƯƠNG 3: ÁP DỤNG HỌC TĂNG CƯỜNG VÀO GAME MARIO

3.5 Triển khai các thuật toán

3.5.1 Định nghĩa lớp DQN:

- Đầu tiên ta xây dựng mô hình Deep Learning để phân tích dữ liệu đầu vào.

Mạng nơ ron dùng để ước lượng có các lớp sau:

28

self.online = nn.Sequential(

nn.Conv2d(in_channels=4, out_channels=32, kernel_size=(8,8), stride=4),

nn.ReLU(),

nn.Conv2d(in_channels=32, out_channels=64, kernel_size=(4,4), stride=2),

nn.ReLU(),

nn.Conv2d(in_channels=64, out_channels=64, kernel_size=(3,3), stride=1),

nn.ReLU(),

nn.Flatten(),

nn.Linear(3136, 512),

nn.ReLU(),

nn.Linear(512, output_dim), )

- Ban đầu mô hình mạng nơ ron để tính giá trị đích sẽ sao chép giá trị tham số của mô hình giá trị ước lượng:

self.target = copy.deepcopy(self.online)

- Các tham số của mô hình này không cần tính đạo hàm nên ta để chức năng tự động tính đạo hàm của nó là False:

for p in self.target.parameters():

p.requires_grad = False

- Đầu tiên xây dựng class DQN, trong hàm khởi tạo __init__(), ta tạo và gán giá trị cho các thông số sau:

+ Số lượng hành động

self.action_size = action_size

+ Một bộ nhớ có cấu trúc dạng deque với bộ nhớ 50000 self.replay_buffer = deque(maxlen=5000)

+ Hệ số suy giảm:

self.gamma = 0.95

+ Thời gian cập nhật tham số của giá trị đích:

self.sync_period = 10000

29

+Mạng nơ ron ta đã tạo ở trên:

self.network = DDQNSolver(self.action_dim).cuda()

- Tiếp theo là phương thức để lưu dữ liệu trải nghiệm vào bộ nhớ replay buffer và phương thức để lấy ra dữ liệu từ bộ nhớ:

def remember(self,state,next_state,action,reward, done):

def recall(self):

- Phương thức quan trọng nhất là optimize_model – dùng để tính toán và cập nhật các tham số của mạng nơ ron:

def experience_replay(self, step_reward):

+ Tính tổng phần thưởng đạt được trong một episode:

self.current_episode_reward += step_reward

+ Cứ sau 10000 hành động thì lại cập nhật tham số của giá trị đích:

if self.current_step % self.sync_period == 0:

self.network.target.load_state_dict (self.network.online.state_dict()) + Nếu như dữ liệu bên trong replay buffer chưa đủ thì không thực hiện phương thức này:

if self.batch_size > len(self.memory): return + Lấy dữ liệu từ bộ nhớ replay buffer để train:

state, next_state, action, reward, done = self.recall()

+ Cứ sau 10000 hành động thì lại cập nhật tham số của giá trị đích:

q_estimate = self.network(state.cuda(), model="online")[np.arange(0, self.batch_size), action.cuda()]

30

+ Chọn hành động có giá trị lớn nhất sử dụng mạng nơ ron của giá trị ước lượng và tính giá trị đích. Hàm no_grad () được gọi để đảm bảo torch không tính đạo hàm trong quá trình tính toán:

with torch.no_grad():

best_action = torch.argmax(self.network(next_state.cuda(), model="online"),

dim=1)

next_q = self.network(next_state.cuda(), model="target")[np.arange(0, self.batch_size), best_action]

q_target = (reward.cuda() + (1 - done.cuda().float()) * self.gamma *

next_q).float()

+Tính được td error nhờ vào giá trị đích và giá trị ước lượng có được:

td_error = q_estimate - q_target

+ Tính giá trị mất mát :

value_loss = td_error.pow(2).mul(0.5).mean()

+ Chuyển toàn bộ gradient bên trong bộ nhớ đệm về bằng 0:

self.optimizer.zero_grad()

+ Tính giá trị đạo hàm của hàm mất mát (lan truyền ngược):

value_loss.backward()

+ Cập nhật giá trị của các tham số 𝜃:

self.optimizer.step()

- Nếu muốn lưu lại giá trị các tham số của mạng nơ ron, ta viết thêm 2 phương thức nữa là:

def load_checkpoint(self, path):

def load_checkpoint(self, path):

31

3.5.2 Dueling DDQN

- Với thuật toán Dueling, mô hình mạng nơ ron thay đổi khá nhiều nên ta phải viết một mô hình mới. Ở mô hình này, giai đoạn cuối ta chia mô hình ra làm 2 output: 1 ouput của giá trị trạng thái V và 1 output bao gồm giá trị lợi thế của các hành động

self.CNN_layer = nn.Sequential(

nn.Conv2d(state_dim[0], 32, kernel_size=(8, 8), stride=4),

nn.ReLU(),

nn.Conv2d(32, 64, kernel_size=(4, 4), stride=2),

nn.ReLU(),

nn.Conv2d(64, 64, kernel_size=(3, 3), stride=1),

nn.ReLU(),

)

#Build ANN layer

self.fc1 = nn.Linear(3136, 512)

# DUELING

self.V = nn.Linear(512, 1)

self.A = nn.Linear(512, action_dim)

- Ta tính giá trị Q của các hành động ở phương thức forward:

def forward(self, state):

t = self.CNN_layer(state) t = F.relu(self.fc1(t))

A = self.A(t)

V = self.V(t).expand_as(A)

Q = V + A - A.mean(1, keepdim=True).expand_as(A) return Q

Một phần của tài liệu Báo cáo đề tài reinforcement learning nhóm 8 (Trang 27 - 31)

Tải bản đầy đủ (PDF)

(35 trang)