# 二、 卷积网络和训练

python几处值得关注的用法（连接）

def conv2d_size_out(size, kernel_size = 5, stride = 2):
return (size - (kernel_size - 1) - 1) // stride  + 1

class DQN(nn.Module):
def __init__(self, h, w, outputs):
super(DQN, self).__init__()
self.conv1 = nn.Conv2d(3, 16, kernel_size=5, stride=2)
self.bn1 = nn.BatchNorm2d(16)
self.conv2 = nn.Conv2d(16, 32, kernel_size=5, stride=2)
self.bn2 = nn.BatchNorm2d(32)
self.conv3 = nn.Conv2d(32, 32, kernel_size=5, stride=2)
self.bn3 = nn.BatchNorm2d(32)

convw = conv2d_size_out(conv2d_size_out(conv2d_size_out(w)))
convh = conv2d_size_out(conv2d_size_out(conv2d_size_out(h)))
linear_input_size = convw * convh * 32

# Called with either one element to determine next action, or a batch
# during optimization. Returns tensor([[left0exp,right0exp]...]).
def forward(self, x):
x = F.relu(self.bn1(self.conv1(x)))
x = F.relu(self.bn2(self.conv2(x)))
x = F.relu(self.bn3(self.conv3(x)))


• Conv 3通道 16通道
• Conv 16通道 32通道
• Conv 32通道 32通道
• Linear 512节点 2节点

conv 为某维度上卷积后的尺寸，X为卷积前的尺寸。

(W - kernel_size + 2 * padding ) // stride + 1


(size - kernel_size) // stride  + 1


def conv2d_size_out(size, kernel_size = 5, stride = 2):
return (size - (kernel_size - 1) - 1) // stride  + 1


        convw = conv2d_size_out(conv2d_size_out(conv2d_size_out(w)))
convh = conv2d_size_out(conv2d_size_out(conv2d_size_out(h)))
linear_input_size = convw * convh * 32


net = DQN(40, 90, 2).to(device)
scr = get_screen()
net(scr)


OK，返回两个值。

EPS_START = 0.9 # 概率从0.9开始
EPS_END = 0.05  #     下降到 0.05
EPS_DECAY = 200 #     越小下降越快
steps_done = 0 # 执行了多少步


100时

200时

def select_action(state):
global steps_done
sample = random.random() #[0, 1)
#epsilon greedy policy。EPS_END 加上额外部分，steps_done 越小，额外部分越接近0.9
eps_threshold = EPS_END + (EPS_START - EPS_END) * math.exp(-1. * steps_done / EPS_DECAY)
steps_done += 1
if sample > eps_threshold:
#选择使用网络来做决定。max返回 0:最大值和 1:索引
return policy_net(state).max(1)[1].view(1, 1)
else:
#选择一个随机数 0 或 1


pytorch 的 tensor.max() 返回所有维度的最大值及其索引，但如果指定了维度，就会返回namedtuple，包含各维度最大值及索引 (values=..., indices=...) 。

max(1)[1] 只取了索引值，也可以用 max(1).indicesview(1,1) 把数值做成[[1]] 的二维数组形式。为何返回一个二维 [[1]] ? 这是因为后面要把所有的state用torch.cat() 合成batch（cat()说明连接）

    return policy_net(state).max(1)[1].view(1, 1)
# return 0 if value[0] > value[1] else 1


for t in count():
# 1. 获取屏幕 1
last_screen = get_screen()
# 2. 选择行为、步进
action = select_action(state)
_, reward, done, _ = env.step(action)
# 3. 获取屏幕 2
current_screen = get_screen()
# 4. 计算差别 2-1
state = current_screen - last_screen
# 5. 优化网络
optimize_model()


• 上边两个分别是step0和step1原图
• 中间灰色图是差值部分，蓝色是少去的部分，棕色是多出的部分
• 下面两图是原始图覆盖差值图，step0将完全复原为step1，step1则多出部分颜色加强

num_episodes = 50
TARGET_UPDATE = 10

for i_episode in range(num_episodes):
env.reset()
last_screen = get_screen()
current_screen = get_screen()
state = current_screen - last_screen

# [0, 无限) 直到 done
for t in count():
action = select_action(state)
_, reward, done, _ = env.step(action.item())
reward = torch.tensor([reward], device=device)
last_screen = current_screen
current_screen = get_screen()
next_state = None if done else current_screen - last_screen
// 保存 state, action, next_state, reward 到列表 memory

state = next_state
optimize_model()

if done:
break



1. 从memory列表里选取n个 （state, action, next_state, reward）
2. 用net获取state的（net输出为2个值），再用action选出结果
3. 用net获取next_state获取，取最大值 。如果state没有对应的next_state，则
4. 用公式算出期望y： （常量
5. 用smooth_l1_loss计算误差
6. 用RMSprop 反向传导优化网络

，所以 Q Learning 公式中的

• 序言：七十年代末，一起剥皮案震惊了整个滨河市，随后出现的几起案子，更是在滨河造成了极大的恐慌，老刑警刘岩，带你破解...
沈念sama阅读 143,540评论 1 302
• 序言：滨河连续发生了三起死亡事件，死亡现场离奇诡异，居然都是意外死亡，警方通过查阅死者的电脑和手机，发现死者居然都...
沈念sama阅读 61,539评论 1 258
• 文/潘晓璐 我一进店门，熙熙楼的掌柜王于贵愁眉苦脸地迎上来，“玉大人，你说我怎么就摊上这事。” “怎么了？”我有些...
开封第一讲书人阅读 95,005评论 0 213
• 文/不坏的土叔 我叫张陵，是天一观的道长。 经常有香客问我，道长，这世上最难降的妖魔是什么？ 我笑而不...
开封第一讲书人阅读 41,159评论 0 180
• 正文 为了忘掉前任，我火速办了婚礼，结果婚礼上，老公的妹妹穿的比我还像新娘。我一直安慰自己，他们只是感情好，可当我...
茶点故事阅读 48,946评论 1 258
• 文/花漫 我一把揭开白布。 她就那样静静地躺着，像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上，一...
开封第一讲书人阅读 38,864评论 1 178
• 那天，我揣着相机与录音，去河边找鬼。 笑死，一个胖子当着我的面吹牛，可吹牛的内容都是我干的。 我是一名探鬼主播，决...
沈念sama阅读 30,468评论 2 273
• 文/苍兰香墨 我猛地睁开眼，长吁一口气：“原来是场噩梦啊……” “哼！你这毒妇竟也来了？” 一声冷哼从身侧响起，我...
开封第一讲书人阅读 29,218评论 0 167
• 想象着我的养父在大火中拼命挣扎，窒息，最后皮肤化为焦炭。我心中就已经是抑制不住地欢快，这就叫做以其人之道，还治其人...
爱写小说的胖达阅读 29,070评论 6 234
• 序言：老挝万荣一对情侣失踪，失踪者是张志新（化名）和其女友刘颖，没想到半个月后，有当地人在树林里发现了一具尸体，经...
沈念sama阅读 32,574评论 0 213
• 正文 独居荒郊野岭守林人离奇死亡，尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
茶点故事阅读 29,353评论 2 215
• 正文 我和宋清朗相恋三年，在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
茶点故事阅读 30,683评论 1 232
• 白月光回国，霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前， 不然我有一百种方法让你生不如死。]我...
爱写小说的胖达阅读 24,270评论 0 32
• 序言：一个原本活蹦乱跳的男人离奇死亡，死状恐怖，灵堂内的尸体忽然破棺而出，到底是诈尸还是另有隐情，我是刑警宁泽，带...
沈念sama阅读 27,168评论 2 214
• 正文 年R本政府宣布，位于F岛的核电站，受9级特大地震影响，放射性物质发生泄漏。R本人自食恶果不足惜，却给世界环境...
茶点故事阅读 31,591评论 3 210
• 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹，春花似锦、人声如沸。这庄子的主人今日做“春日...
开封第一讲书人阅读 25,638评论 0 9
• 文/苍兰香墨 我抬头看了看天上的太阳。三九已至，却和暖如春，着一层夹袄步出监牢的瞬间，已是汗流浃背。 一阵脚步声响...
开封第一讲书人阅读 26,035评论 0 166
• 我被黑心中介骗来泰国打工， 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留，地道东北人。 一个月前我还...
沈念sama阅读 33,590评论 2 232
• 正文 我出身青楼，却偏偏与公主长得像，于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子，可洞房花烛夜当晚...
茶点故事阅读 33,685评论 2 233