-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel.py
107 lines (84 loc) · 3.11 KB
/
model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import gym, os
from itertools import count
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.distributions import Categorical
import gym_game2048
from actor_critic import Actor,Critic
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
env = gym.make("game2048-v0", board_size=4, seed=None, binary=True, extractor="mlp", penalty=0)
state_size = env.observation_space.shape[0]
action_size = env.action_space.n
lr = 0.0001
def print_board(board):
print("-------------")
for line in board:
print("+",*line,"+", sep = " ")
print("-------------")
def compute_returns(next_value, rewards, masks, gamma=0.99):
R = next_value
returns = []
for step in reversed(range(len(rewards))):
R = rewards[step] + gamma * R * masks[step]
returns.insert(0, R)
return returns
def trainIters(actor, critic, n_iters):
optimizerA = optim.Adam(actor.parameters())
optimizerC = optim.Adam(critic.parameters())
for iter in range(n_iters):
state = env.reset()
log_probs = []
values = []
rewards = []
masks = []
entropy = 0
env.reset()
for i in count():
env.render()
state = torch.FloatTensor(state).to(device)
dist, value = actor(state), critic(state)
action = dist.sample()
next_state, reward, done, _ = env.step(action.cpu().numpy())
log_prob = dist.log_prob(action).unsqueeze(0)
entropy += dist.entropy().mean()
log_probs.append(log_prob)
values.append(value)
rewards.append(torch.tensor([reward], dtype=torch.float, device=device))
masks.append(torch.tensor([1-done], dtype=torch.float, device=device))
state = next_state
if done:
print('Iteration: {}, Score: {}'.format(iter, i))
print_board(env.get_board())
break
next_state = torch.FloatTensor(next_state).to(device)
next_value = critic(next_state)
returns = compute_returns(next_value, rewards, masks)
log_probs = torch.cat(log_probs)
returns = torch.cat(returns).detach()
values = torch.cat(values)
advantage = returns - values
actor_loss = -(log_probs * advantage.detach()).mean()
critic_loss = advantage.pow(2).mean()
optimizerA.zero_grad()
optimizerC.zero_grad()
actor_loss.backward()
critic_loss.backward()
optimizerA.step()
optimizerC.step()
torch.save(actor, 'model/actor.pkl')
torch.save(critic, 'model/critic.pkl')
env.close()
if __name__ == '__main__':
if os.path.exists('model/actor.pkl'):
actor = torch.load('model/actor.pkl')
print('Actor Model loaded')
else:
actor = Actor(state_size, action_size).to(device)
if os.path.exists('model/critic.pkl'):
critic = torch.load('model/critic.pkl')
print('Critic Model loaded')
else:
critic = Critic(state_size, action_size).to(device)
trainIters(actor, critic, n_iters=100)