PyTorch入门(2)

http://www.csdn.net/article/2015-08-28/2825569   这个网址学RNN基础

其中重点有如下:

我们用随机数来初始化RNN矩阵,通过大量的训练找到一个令人满意的矩阵,并且用一些损失函数来度量,你可以在输入序列x上得到你希望的输出y。

实际上我们大多数人使用一种与上面我所提及稍微不同的网络,它叫做长短期记忆(LSTM)网络。LSTM是一种特殊类型的递归网络,在实践中工作效果更佳,这归功于其强大的更新方程和一些吸引人的动态反向传播功能

因为在我们的训练数据中,下一个出现的字符是“e”,我们将要提高这个字符的置信度(绿色数字)并且降低其他字符的置信度(红色数字)。通常的做法是使用一个交叉熵损失函数,这相当于在每个输出向量上使用Softmax分类器,将下一个出现的字符的索引作为一个正确的分类。该RNN是由小批量随机梯度下降训练的。我喜欢使用RMSProp (每个参数的自适应学习率)来稳定更新。

Paul Graham生成器

首先让我们尝试用一个小英语数据集作一个全面检查。我个人最喜欢的数据集是 Paul Graham散文 串联集。其基本思路是,散文中有很多智慧,不幸的是Paul Graham是一个相对缓慢的生成器。如果我们能够按需生成智慧样本,那不是很强大?RNNs在这里就起到了作用。

连接过去5年所有的论文,我们得到了大约1MB的文本文件,或者说是大约100万个字符(这是一个非常小的数据集)。技术方面:我们用512个隐藏节点(大约350万个参数)来训练一个2层的LSTM,然后在每层之后设定参数为0.5的dropout层。我们将每批训练100个实例,然后每超过100个字符则停止反向传播。通过这些设置,每一批在TITAN Z GPU上处理完成大约需要0.46秒(这通过性能代价忽略不计的50个字符的BPTT算法将它分为两半)。切记,RNN只认识字符,所以它将说话者的名字和内容一起生成为样本。 

http://blog.csdn.net/jerr__y/article/details/53749693 这个网址解释seq2seq

其中重点有如下:

 在以往的很多模型中,我们一般都说输入特征矩阵,每个样本对应矩阵中的某一行。就是说,无论是第一个样本还是最后一个样本,他们都有一样的特征维度。但是对于翻译这种例子,难道我们要让每一句话都有一样的字数吗,这不科学,所以就有了seq2seq 这种结构。

 原文是应用在机器翻译中的,作者将源句子顺序颠倒后再输入 Encoder 中,比如源句子为“A B C”,那么输入 Encoder 的顺序为 “C B A”,经过这样的处理后,取得了很大的提升,而且这样的处理使得模型能够很好地处理长句子。

 论文[3] Bahdanau et al. 是在 Encoder 和 Decoder 的基础上提出了注意力机制。在论文[1] 的 decoder 中,每次预测下一个词都会用到中间语义 c[Math Processing Error]而这个c主要就是最后一个时刻的隐藏状态。在论文[3] 中,我们可以看到在Decoder进行预测的时候,Encoder 中每个时刻的隐藏状态都被利用上了。这样子,Encoder 就能利用多个语义信息(隐藏状态)来表达整个句子的信息了。

 论文[3] 中,Encoder用的是双端的 GRU,这个结构其实非常直观,在这种 seq2seq 中效果也要比单向的 GRU 要好。http://blog.csdn.net/malefactor/article/details/50550211

 论文[4]介绍了机器翻译在训练时经常用到的一个方法(小技巧)sample_softmax ,主要解决词表数量太大的问题。


http://blog.csdn.net/malefactor/article/details/50550211 【【这个网址介绍attention】】讲的很好

Encoder-Decoder是个非常通用的计算框架,至于EncoderDecoder具体使用什么模型都是由研究者自己定的,常见的比如CNN/RNN/BiRNN/GRU/LSTM/Deep LSTM等,这里的变化组合非常多,而很可能一种新的组合就能攒篇论文,所以有时候科研里的创新就是这么简单。比如我用CNN作为Encoder,用RNN作为Decoder,你用BiRNN做为Encoder,用深层LSTM作为Decoder,那么就是一个创新。所以正准备跳楼的憋着劲想攒论文毕业的同学可以从天台下来了,当然是走下来,不是让你跳下来,你可以好好琢磨一下这个模型,把各种排列组合都试试,只要你能提出一种新的组合并被证明有效,那恭喜你:施主,你可以毕业了。

这意味着不论是生成哪个单词,y1,y2还是y3,其实句子X中任意单词对生成某个目标单词yi来说影响力都是相同的,没有任何区别(其实如果EncoderRNN的话,理论上越是后输入的单词影响越大,并非等权的,估计这也是为何Google提出Sequence to Sequence模型时发现把输入句子逆序输入做翻译效果会更好的小Trick的原因)。这就是为何说这个模型没有体现出注意力的缘由。

“汤姆”,“追逐”,“杰瑞”。在翻译“杰瑞”这个中文单词的时候,分心模型里面的每个英文单词对于翻译目标单词“杰瑞”贡献是相同的,很明显这里不太合理,显然“Jerry”对于翻译成“杰瑞”更重要,但是分心模型是无法体现这一点的,这就是为何说它没有引入注意力的原因。

没有引入注意力的模型在输入句子比较短的时候估计问题不大,但是如果输入句子比较长,此时所有语义完全通过一个中间语义向量来表示,单词自身的信息已经消失,可想而知会丢失很多细节信息,这也是为何要引入注意力模型的重要原因。

上面的例子中,如果引入AM模型的话,应该在翻译“杰瑞”的时候,体现出英文单词对于翻译当前中文单词不同的影响程度,比如给出类似下面一个概率分布值:

Tom,0.3(Chase,0.2)(Jerry,0.5)

同理,目标句子中的每个单词都应该学会其对应的源语句子中单词的注意力分配概率信息。理解AM模型的关键就是这里,即由固定的中间语义表示C换成了根据当前输出单词来调整成加入注意力模型的变化的Ci

一般文献里会把AM模型看作是单词对齐模型,这是非常有道理的。目标句子生成的每个单词对应输入句子单词的概率分布可以理解为输入句子单词和这个目标生成单词的对齐概率,这在机器翻译语境下是非常直观的。AM模型理解成影响力模型也是合理的,就是说生成目标单词的时候,输入句子每个单词对于生成这个单词有多大的影响程度。



PyTorch深度学习:60分钟入门(Translation) :   文章来源:   http://blog.csdn.net/scutjy2015/article/details/71214928    此处笔记:  

# 特别注明:任何可以改变tensor内容的操作都会在方法名后加一个下划线'_'
    例如:x.copy_(y), x.t_(),y.add_(x) 都会改变x的值。

······ PyTorch中所有的神经网络都来自于autograd包
···· Autograd: 自动求导
autograd 包提供Tensor所有操作的自动求导方法。
这是一个运行时定义的框架,这意味着你的反向传播是根据你代码运行的方式来定义的,因此每一轮迭代都可以各不相同。

··· autograd.Variable 这是这个包中最核心的类。 
它包装了一个Tensor,并且几乎支持所有的定义在其上的操作。
一旦完成了你的运算,你可以调用 .backward()来自动计算出所有的梯度。
你可以通过属性 .data 来访问原始的tensor,而关于这一Variable的梯度则集中于 .grad 属性中。

··· 另一个在自动求导中非常重要的类 Function。
Variable 和 Function 二者相互联系并且构建了一个描述整个运算过程的无环图。每个Variable拥有一个 .creator 属性,其引用了一个创建Variable的 Function。(除了用户创建的Variable其 creator 部分是 None)。

如果你想要进行求导计算,你可以在Variable上调用.backward()。 如果Variable是一个标量(例如它包含一个单元素数据),你无需对backward()指定任何参数,然而如果它有更多的元素,你需要指定一个和tensor的形状想匹配的grad_output参数。


try1.py


import torch
from torch.autograd import Variable
x = Variable(torch.ones(2, 2), requires_grad = True)
y = x + 2
y.creator
# y 是作为一个操作的结果创建的因此y有一个creator 
z = y * y * 3
out = z.mean()
# 现在我们来使用反向传播
out.backward()
# out.backward()和操作out.backward(torch.Tensor([1.0]))是等价的
# 在此处输出 d(out)/dx
x.grad
最终得出的结果是一个全是4.5的矩阵:
Variable containing:
 4.5000  4.5000
 4.5000  4.5000
[torch.FloatTensor of size 2x2]


``````使用 torch.nn 包可以进行神经网络的构建。
nn建立在autograd的基础上来进行模型的定义和微分。nn.Module中包含着神经网络的层,同时forward(input)方法能够将output进行返回。




一个简单的前馈神经网络。 从前面获取到输入的结果,从一层传递到另一层,最后输出最后结果。


一个典型的神经网络的训练过程是这样的:
定义一个有着可学习的参数(或者权重)的神经网络
对着一个输入的数据集进行迭代   
用神经网络对输入进行处理    (在网络中处理数据)
计算代价值 (对输出值的修正到底有多少)   [计算损失(输出离分类正确有多远)]
将梯度传播回神经网络的参数中
更新网络中的权重, 通常使用简单的更新规则: weight = weight + learning_rate * gradient


[[[[[[    https://gaussic.github.io/2017/05/05/pytorch-60-minutes/    ]]]]]


```回顾:
torch.Tensor 一个多维数组
autograd.Variable 包装一个Tensor并且记录应用在其上的历史运算操作。拥有与Tensor相同的API,添加了一些像backward()的操作。还包括相关tensor的梯度。
nn.Module 神经网络模块。封装参数的方便方式,带有将它们转移到GPU、导出、载入等的帮助函数。
nn.Parameter 一种Variable,当给Module赋值时自动注册一个参数。
autograd.Function 实现一个autograd 操作的 forward 和 backward 定义。每一个Variable操作,创建至少一个Function节点,来连接那些创建Variable的函数,并且记录其历史。


在这里,我们涵盖了:
定义神经网络
处理输入并调用backward
还剩下:
计算损失
更新网络权重


``````损失函数
一个损失函数以一个(output, target)对为输入,然后计算一个值用以估计输出结果离目标结果多远。存在多种的损失函数。
```一个简单的损失函数:nn.MSELoss,它计算输出与目标的均方误差。


现在,如果你跟随loss从后往前看,使用.creator属性你可以看到这样的一个计算流程图:
input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d  
      -> view -> linear -> relu -> linear -> relu -> linear 
      -> MSELoss

      -> loss












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值