Machine learning Chainer如何保存和加载DQN模型
我正在学习深层强化学习 框架链接器 我遵循了一个教程,得到了以下代码:Machine learning Chainer如何保存和加载DQN模型,machine-learning,keras,deep-learning,reinforcement-learning,chainer,Machine Learning,Keras,Deep Learning,Reinforcement Learning,Chainer,我正在学习深层强化学习 框架链接器 我遵循了一个教程,得到了以下代码: def train_dddqn(env): class Q_Network(chainer.Chain): def __init__(self, input_size, hidden_size, output_size): super(Q_Network, self).__init__( fc1=L.Linear(input_size, hi
def train_dddqn(env):
class Q_Network(chainer.Chain):
def __init__(self, input_size, hidden_size, output_size):
super(Q_Network, self).__init__(
fc1=L.Linear(input_size, hidden_size),
fc2=L.Linear(hidden_size, hidden_size),
fc3=L.Linear(hidden_size, hidden_size // 2),
fc4=L.Linear(hidden_size, hidden_size // 2),
state_value=L.Linear(hidden_size // 2, 1),
advantage_value=L.Linear(hidden_size // 2, output_size)
)
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
def __call__(self, x):
h = F.relu(self.fc1(x))
h = F.relu(self.fc2(h))
hs = F.relu(self.fc3(h))
ha = F.relu(self.fc4(h))
state_value = self.state_value(hs)
advantage_value = self.advantage_value(ha)
advantage_mean = (F.sum(advantage_value, axis=1) / float(self.output_size)).reshape(-1, 1)
q_value = F.concat([state_value for _ in range(self.output_size)], axis=1) + (
advantage_value - F.concat([advantage_mean for _ in range(self.output_size)], axis=1))
return q_value
def reset(self):
self.cleargrads()
Q = Q_Network(input_size=env.history_t + 1, hidden_size=100, output_size=3)
Q_ast = copy.deepcopy(Q)
optimizer = chainer.optimizers.Adam()
optimizer.setup(Q)
epoch_num = 50
step_max = len(env.data) - 1
memory_size = 200
batch_size = 50
epsilon = 1.0
epsilon_decrease = 1e-3
epsilon_min = 0.1
start_reduce_epsilon = 200
train_freq = 10
update_q_freq = 20
gamma = 0.97
show_log_freq = 5
memory = []
total_step = 0
total_rewards = []
total_losses = []
start = time.time()
for epoch in range(epoch_num):
pobs = env.reset()
step = 0
done = False
total_reward = 0
total_loss = 0
while not done and step < step_max:
# select act
pact = np.random.randint(3)
if np.random.rand() > epsilon:
pact = Q(np.array(pobs, dtype=np.float32).reshape(1, -1))
pact = np.argmax(pact.data)
# act
obs, reward, done = env.step(pact)
# add memory
memory.append((pobs, pact, reward, obs, done))
if len(memory) > memory_size:
memory.pop(0)
# train or update q
if len(memory) == memory_size:
if total_step % train_freq == 0:
shuffled_memory = np.random.permutation(memory)
memory_idx = range(len(shuffled_memory))
for i in memory_idx[::batch_size]:
batch = np.array(shuffled_memory[i:i + batch_size])
b_pobs = np.array(batch[:, 0].tolist(), dtype=np.float32).reshape(batch_size, -1)
b_pact = np.array(batch[:, 1].tolist(), dtype=np.int32)
b_reward = np.array(batch[:, 2].tolist(), dtype=np.int32)
b_obs = np.array(batch[:, 3].tolist(), dtype=np.float32).reshape(batch_size, -1)
b_done = np.array(batch[:, 4].tolist(), dtype=np.bool)
q = Q(b_pobs)
indices = np.argmax(q.data, axis=1)
maxqs = Q_ast(b_obs).data
target = copy.deepcopy(q.data)
for j in range(batch_size):
Q.reset()
loss = F.mean_squared_error(q, target)
total_loss += loss.data
loss.backward()
optimizer.update()
if total_step % update_q_freq == 0:
Q_ast = copy.deepcopy(Q)
# epsilon
if epsilon > epsilon_min and total_step > start_reduce_epsilon:
epsilon -= epsilon_decrease
# next step
total_reward += reward
pobs = obs
step += 1
total_step += 1
total_rewards.append(total_reward)
total_losses.append(total_loss)
if (epoch + 1) % show_log_freq == 0:
log_reward = sum(total_rewards[((epoch + 1) - show_log_freq):]) / show_log_freq
log_loss = sum(total_losses[((epoch + 1) - show_log_freq):]) / show_log_freq
elapsed_time = time.time() - start
print('\t'.join(map(str, [epoch + 1, epsilon, total_step, log_reward, log_loss, elapsed_time])))
start = time.time()
return Q, total_losses, total_rewards
Q, total_losses, total_rewards = train_dddqn(Environment1(train))
def系列dddqn(环境):
Q_类网络(链器链):
定义初始大小(自身大小、输入大小、隐藏大小、输出大小):
超级(Q_网络,自).\u初始化__(
fc1=L.线性(输入大小、隐藏大小),
fc2=L.线性(隐藏大小,隐藏大小),
fc3=L.线性(隐藏大小,隐藏大小//2),
fc4=L.线性(隐藏大小,隐藏大小//2),
状态值=L.Linear(隐藏大小//2,1),
优势值=L.线性(隐藏大小//2,输出大小)
)
self.input\u size=输入大小
self.hidden\u size=隐藏的大小
self.output\u size=输出大小
定义调用(self,x):
h=F.relu(自身fc1(x))
h=F.relu(自身fc2(h))
hs=F.relu(自身fc3(h))
ha=F.relu(自身fc4(h))
状态值=自身状态值(hs)
优势价值=自身优势价值(ha)
优势平均值=(F.sum(优势值,轴=1)/float(自输出大小))。重塑(-1,1)
q_值=F.concat([范围内(自身输出大小)的状态_值],轴=1)+(
优势值-F.concat([优势值表示范围内(自身输出大小)],轴=1))
返回q_值
def重置(自):
self.cleargrads()
Q=Q_网络(输入_大小=env.history_t+1,隐藏_大小=100,输出_大小=3)
Q_ast=copy.deepcopy(Q)
optimizer=chainer.optimizers.Adam()
优化程序设置(Q)
历元数=50
步骤_max=len(环境数据)-1
内存大小=200
批量大小=50
ε=1.0
εu减小=1e-3
epsilon_min=0.1
开始减小ε=200
列车频率=10
更新频率=20
伽马=0.97
显示日志频率=5
内存=[]
总步长=0
奖励总额=[]
总损失=[]
开始=时间。时间()
对于范围内的历元(历元数):
pobs=env.reset()
步长=0
完成=错误
奖励总额=0
总损失=0
未完成和步骤<步骤_max:
#选择行动
pact=np.random.randint(3)
如果np.random.rand()>ε:
pact=Q(np.array(pobs,dtype=np.float32)。重塑(1,-1))
pact=np.argmax(pact.data)
#表演
obs,奖励,完成=环境步骤(契约)
#添加内存
memory.append((POB、契约、奖励、obs、完成))
如果len(内存)>内存大小:
memory.pop(0)
#训练或更新q
如果len(内存)=内存大小:
如果总步长%train\u freq==0:
随机排列记忆=np.随机排列(记忆)
内存\u idx=范围(len(无序\u内存))
对于内存中的i_idx[::批处理大小]:
batch=np.array(洗牌内存[i:i+batch\u大小])
b_pobs=np.array(批处理[:,0]。tolist(),dtype=np.float32)。重塑(批处理大小,-1)
b_pact=np.array(批处理[:,1].tolist(),dtype=np.int32)
b_reward=np.array(批处理[:,2].tolist(),dtype=np.int32)
b_obs=np.array(批处理[:,3].tolist(),dtype=np.float32).重塑(批处理大小,-1)
b_done=np.array(批处理[:,4].tolist(),dtype=np.bool)
q=q(b_pobs)
指数=np.argmax(q.data,轴=1)
maxqs=Q_ast(b_obs).数据
target=copy.deepcopy(q.data)
对于范围内的j(批次尺寸):
Q.重置()
损失=F.均方误差(q,目标)
总损失+=损失数据
loss.backward()
optimizer.update()
如果总步骤%update\u q\u freq==0:
Q_ast=copy.deepcopy(Q)
#ε
如果epsilon>epsilon\u min和total\u step>start\u reduce\u epsilon:
ε-=εu减小
#下一步
总奖励+=奖励
pobs=obs
步骤+=1
总步数+=1
奖励总额。追加(奖励总额)
总损失。追加(总损失)
如果(历元+1)%show\u log\u freq==0:
日志奖励=总和(总奖励[(历元+1)-显示日志频率])/show日志频率
对数损耗=总和(总损耗[(历元+1)-显示对数频率])/显示对数频率
已用时间=time.time()-开始
打印('\t'.join(映射(str、[epoch+1、epsilon、总步长、日志奖励、日志丢失、已用时间)))
开始=时间。时间()
返回Q、总损失、总奖励
Q、 总损失、总奖励=列车dddqn(环境1(列车))
我的问题是如何保存和加载这个已经训练得很好的模型?我知道Kreas有一些功能,比如:Model.save和load\u Model
那么,我需要为这个链表代码指定什么代码呢?您可以使用
序列化程序模块来保存/加载链表的模型参数(链类)
详情见官方文件:
此外,您还可以参考chainerrl
,这是一个用于强化学习的链表库
chainerrl
有一个util函数copy_param
将参数从网络源链接
复制到目标链接
Hi@corochann你能帮我回答这个问题吗:非常感谢!
from chainer import serializers
Q = Q_Network(input_size=env.history_t + 1, hidden_size=100, output_size=3)
Q_ast = Q_Network(input_size=env.history_t + 1, hidden_size=100, output_size=3)
# --- train Q here... ---
# copy Q parameter into Q_ast by saving Q's parameter and load to Q_ast
serializers.save_npz('my.model', Q)
serializers.load_npz('my.model', Q_ast)