- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是我为 CartPole-v0 实现的 DQN 和 DDQN,我认为这是正确的。
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import gym
import torch.optim as optim
import random
import os
import time
class NETWORK(torch.nn.Module):
def __init__(self, input_dim: int, output_dim: int, hidden_dim: int) -> None:
super(NETWORK, self).__init__()
self.layer1 = torch.nn.Sequential(
torch.nn.Linear(input_dim, hidden_dim),
torch.nn.ReLU()
)
self.layer2 = torch.nn.Sequential(
torch.nn.Linear(hidden_dim, hidden_dim),
torch.nn.ReLU()
)
self.final = torch.nn.Linear(hidden_dim, output_dim)
def forward(self, x: torch.Tensor) -> torch.Tensor:
x = self.layer1(x)
x = self.layer2(x)
x = self.final(x)
return x
class ReplayBuffer(object):
def __init__(self, capacity=50000):
self.capacity = capacity
self.memory = []
self.position = 0
def push(self, s0, a0, r, s1):
if len(self.memory) < self.capacity:
self.memory.append(None)
self.memory[self.position] = (s0, a0, r, s1)
self.position = (self.position + 1) % self.capacity
def sample(self, batch_size=64):
return random.sample(self.memory, batch_size)
def __len__(self):
return len(self.memory)
class DQN(object):
def __init__(self):
self.state_dim = 4
self.action_dim = 2
self.lr = 0.001
self.discount_factor = 0.99
self.epsilon = 1
self.epsilon_decay = 0.95
self.num_train = 0
self.num_train_episodes = 0
self.batch_size = 64
self.predict_network = NETWORK(input_dim=4, output_dim=2, hidden_dim=16).double()
self.memory = ReplayBuffer(capacity=50000)
self.optimizer = torch.optim.Adam(self.predict_network.parameters(), lr=self.lr)
self.loss = 0
def select_action(self, states: np.ndarray) -> int:
if np.random.uniform(0, 1) < self.epsilon:
return np.random.choice(self.action_dim)
else:
states = torch.from_numpy(states).unsqueeze_(dim=0)
with torch.no_grad():
Q_values = self.predict_network(states)
action = torch.argmax(Q_values).item()
return action
def policy(self, states: np.ndarray) -> int:
states = torch.from_numpy(states).unsqueeze_(dim=0)
with torch.no_grad():
Q_values = self.predict_network(states)
action = torch.argmax(Q_values).item()
return action
def train(self, s0, a0, r, s1, sign):
if sign == 1:
self.num_train_episodes += 1
if self.epsilon > 0.01:
self.epsilon = max(self.epsilon * self.epsilon_decay, 0.01)
return
self.num_train += 1
self.memory.push(s0, a0, r, s1)
if len(self.memory) < self.batch_size:
return
batch = self.memory.sample(self.batch_size)
state_batch = torch.from_numpy(np.stack([b[0] for b in batch]))
action_batch = torch.from_numpy(np.stack([b[1] for b in batch]))
reward_batch = torch.from_numpy(np.stack([b[2] for b in batch]))
next_state_batch = torch.from_numpy(np.stack([b[3] for b in batch]))
Q_values = self.predict_network(state_batch)[torch.arange(self.batch_size), action_batch]
next_state_Q_values = self.predict_network(next_state_batch).max(dim=1)[0]
Q_targets = self.discount_factor * next_state_Q_values + reward_batch
loss = F.mse_loss(Q_values, Q_targets.detach())
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
self.loss = loss.data.item()
class DDQN(object):
def __init__(self):
self.state_dim = 4
self.action_dim = 2
self.lr = 0.001
self.discount_factor = 0.9
self.epsilon = 1
self.epsilon_decay = 0.95
self.num_train = 0
self.num_train_episodes = 0
self.batch_size = 64
self.predict_network = NETWORK(input_dim=4, output_dim=2, hidden_dim=16).double()
self.target_network = NETWORK(input_dim=4, output_dim=2, hidden_dim=16).double()
self.target_network.load_state_dict(self.predict_network.state_dict())
self.target_network.eval()
self.memory = ReplayBuffer(capacity=50000)
self.optimizer = torch.optim.Adam(self.predict_network.parameters(), lr=self.lr)
self.loss = 0
def select_action(self, states: np.ndarray) -> int:
if np.random.uniform(0, 1) < self.epsilon:
return np.random.choice(self.action_dim)
else:
states = torch.from_numpy(states).unsqueeze_(dim=0)
with torch.no_grad():
Q_values = self.predict_network(states)
action = torch.argmax(Q_values).item()
return action
def policy(self, states: np.ndarray) -> int:
states = torch.from_numpy(states).unsqueeze_(dim=0)
with torch.no_grad():
Q_values = self.predict_network(states)
action = torch.argmax(Q_values).item()
return action
def train(self, s0, a0, r, s1, sign):
if sign == 1:
self.num_train_episodes += 1
if self.num_train_episodes % 2 == 0:
self.target_network.load_state_dict(self.predict_network.state_dict())
self.target_network.eval()
if self.epsilon > 0.01:
self.epsilon = max(self.epsilon * self.epsilon_decay, 0.01)
return
self.num_train += 1
self.memory.push(s0, a0, r, s1)
if len(self.memory) < self.batch_size:
return
batch = self.memory.sample(self.batch_size)
state_batch = torch.from_numpy(np.stack([b[0] for b in batch]))
action_batch = torch.from_numpy(np.stack([b[1] for b in batch]))
reward_batch = torch.from_numpy(np.stack([b[2] for b in batch]))
next_state_batch = torch.from_numpy(np.stack([b[3] for b in batch]))
Q_values = self.predict_network(state_batch)[torch.arange(self.batch_size), action_batch]
next_state_action_batch = torch.argmax(self.predict_network(next_state_batch), dim=1)
next_state_Q_values = self.target_network(next_state_batch)[torch.arange(self.batch_size), next_state_action_batch]
Q_targets = self.discount_factor * next_state_Q_values + reward_batch
loss = F.smooth_l1_loss(Q_values, Q_targets.detach())
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
self.loss = loss.data.item()
我使用以下方法来评估和训练我的 DQN 和 DDQN。
def eval_policy(agent, env_name, eval_episodes=10):
eval_env = gym.make(env_name)
avg_reward = 0.
for _ in range(eval_episodes):
state, done = eval_env.reset(), False
while not done:
action = agent.policy(state)
state, reward, done, _ = eval_env.step(action)
avg_reward += reward
avg_reward /= eval_episodes
print("---------------------------------------")
print(f"Evaluation over {eval_episodes} episodes: {avg_reward:.3f}")
print("---------------------------------------")
return avg_reward
env_name = 'CartPole-v0'
env = gym.make(env_name)
agent = DQN() # agent = DDQN()
for i in range(1000):
state, done = env.reset(), False
episodic_reward = 0
while not done:
action = agent.select_action(np.squeeze(state))
next_state, reward, done, info = env.step(action)
episodic_reward += reward
sign = 1 if done else 0
agent.train(state, action, reward, next_state, sign)
state = next_state
print(f'episode: {i}, reward: {episodic_reward}')
if i % 20 == 0:
eval_reward = eval_policy(agent, env_name, eval_episodes=50)
if eval_reward >= 195:
print("Problem solved in {} episodes".format(i + 1))
break
问题是我的 DQN 网络没有训练,并且在损失计算中使用 target.detach() 使损失呈指数增长。如果我不使用 .detach(),DQN 对象将进行训练,但我认为这不是正确的方法。对于 DDQN,我的网络总是不训练。任何人都可以就可能出错的地方提供一些建议吗?
最佳答案
所以您实现中的一个错误是您从未将一集的结尾添加到您的重播缓冲区。在您的火车功能中,如果 sign==1 (剧集结束),您将返回。删除该返回并通过 (1-dones)*... 调整目标计算,以防您对剧集结尾的过渡进行采样。剧集结尾之所以重要,是因为它是唯一的体验,目标不是通过自举逼近。然后DQN训练。为了再现性,我使用了 0.99 的折扣率和 2020 种子(用于 torch、numpy 和健身房环境)。经过 241 次训练后,我获得了 199.100 的奖励。
希望对您有所帮助,顺便说一下,代码非常易读。
关于使用 .detach() 的 Pytorch DQN、DDQN 导致非常大的损失(呈指数增长)并且根本不学习,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64690471/
我正在尝试使用 Spark 从 Cassandra 读取数据。 DataFrame rdf = sqlContext.read().option("keyspace", "readypulse
这是代码: void i_log_ (int error, const char * file, int line, const char * fmt, ...) { /* Get erro
我必须调试一个严重依赖 Gtk 的程序。问题是由于某些原因,在使用 GtkWindow 对象时开始出现许多运行时警告。问题是,即使 Gtk 提示严重错误,它也不会因这些错误而中止。我没有代码库的更改历
我正在尝试从已有效编译和链接的程序中检索二进制文件。我已经通过 GL_PROGRAM_BINARY_LENGTH 收到了它的长度。该文档说有两个实例可能会发生 GL_INVALID_OPERATION
我有一个托管在 Azure 环境中的服务。我正在使用控制台应用程序使用该服务。这样做时,我得到了异常: "The requested service, 'http://xxxx-d.yyyy.be/S
我有以下代码,它被 SEGV 信号杀死。使用调试器表明它被 main() 中的第一个 sem_init() 杀死。如果我注释掉第一个 sem_init() ,第二个会导致同样的问题。我试图弄清楚是什么
目前我正在编写一个应用程序(目标 iOS 6,启用 ARC),它使用 JSON 进行数据传输,使用核心数据进行持久存储。 JSON 数据由 PHP 脚本通过 json_encode 从 MySQL 数
我对 Xamarin.Forms 还是很陌生。我在出现的主页上有一个非常简单的功能 async public Task BaseAppearing() { if (UserID
这是我的代码的简化版本。 public class MainActivity extends ActionBarActivity { private ArrayList entry = new Arr
我想弄明白为什么我的两个 Java 库很难很好地协同工作。这是场景: 库 1 有一个类 A,其构造函数如下: public A(Object obj) { /* boilerplate */ } 在以
如果网站不需要身份验证,我的代码可以正常工作,如果需要,则在打印“已创建凭据”后会立即出现 EXC_BAD_ACCESS 错误。我不会发布任何内容,并且此代码是直接从文档中复制的 - 知道出了什么问题
我在使用 NSArray 填充 UITableView 时遇到问题。我确信我正在做一些愚蠢的事情,但我无法弄清楚。当我尝试进行简单的计数时,我得到了 EXC_BAD_ACCESS,我知道这是因为我试图
我在 UITableViewCell 上有一个 UITextField,在另一个单元格上有一个按钮。 我单击 UITextField(出现键盘)。 UITextField 调用了以下方法: - (BO
我有一个应用程序出现间歇性崩溃。崩溃日志显示了一个堆栈跟踪,这对我来说很难破译,因此希望其他人看到了这一点并能为我指出正确的方向。 基本上,应用程序在启动时执行反向地理编码请求,以在标签中显示用户的位
我开发了一个 CGImage,当程序使用以下命令将其显示在屏幕上时它工作正常: [output_view.layer performSelectorOnMainThread:@selector(set
我正在使用新的 EncryptedSharedPreferences以谷歌推荐的方式上课: private fun securePrefs(context: Context): SharedPrefe
我有一个中继器,里面有一些控件,其中一个是文本框。我正在尝试使用 jquery 获取文本框,我的代码如下所示: $("#").click(function (event) {}); 但我总是得到 nu
在以下场景中观察到 TTS 初始化错误,太随机了。 已安装 TTS 引擎,存在语音集,并且可以从辅助功能选项中播放示例 tts。 TTS 初始化在之前初始化和播放的同一设备上随机失败。 在不同的设备(
maven pom.xml org.openjdk.jol jol-core 0.10 Java 类: public class MyObjectData { pr
在不担心冲突的情况下,可以使用 MD5 作为哈希值,字符串长度最多为多少? 这可能是通过为特定字符集中的每个可能的字符串生成 MD5 哈希来计算的,长度不断增加,直到哈希第二次出现(冲突)。没有冲突的
我是一名优秀的程序员,十分优秀!