Vanilla RNN是什么,它背后又隐藏了什么?


原文来源Medium

作者:Apil Tamang

「雷克世界」编译:嗯~阿童木呀、多啦A亮


众所周知,对于我们来说,循环神经网络(RNN)是确实一个难以理解的神经网络,它们具有一定的神秘性,尤其是对于初学者来说就显得更不可思议了。当人们开始谈论长短期记忆网络(LSTM)或者RNN体系结构的未展开/展开(rolled/unrolled)版本时,我相信,这些讨论肯定会让我们对于其架构等相关知识有一个更为深刻的了解和认识。


我认为,之所以会出现这种情况的原因是,现如今,我们几乎没有材料能够以一种易于视觉化的方式揭示RNN的内部结构。如果对于构建块(building block)是什么,没有一个很好的心理图像认知,我会发现自己往往会一遍又一遍地努力去理解同样的东西。


核心API


现在任何RNN架构的核心都是一个简单的RNN cell或其变体。下面就是用PyTorch创建一个RNN Cell所需要的代码:


rnn_pytorch = nn.RNN(input_size=10, hidden_size=20)


而用Tensorflow创建这样一个RNN Cell所需要的代码应为:


rnn_tensorflow = tf.contrib.BasicRNNCell(num_units=20)


请注意单词Cell的用法。不知何故,术语cell在神经网络中似乎是一个非常陌生词汇,我们习惯于用其通过相互连接来对单个神经元和/或它们在空间中的排列进行可视化。一个RNN cell是如何与神经网络中我们习惯使用的单个神经元的浮动集合相关的呢?这就是我们将在此文的其余部分进行探索的焦点。


传统的观点


一般来说,一个RNN cell应该简单地被认为是将整个网络的一个单元(unit),其中该网络将其某些部分封装在一个同质块(homogeneous block)中。在大多数博客和论文中,RNN cell(块)如下所示:

 

一个简单的RNN结构(左:标准形式,右:展开形式)


这与传统的完全连接(FC)和卷积网络(conv-nets)的描述截然不同。

 

神经网络的典型视图(左:完全连接,右:卷积网络)


后台


如果想要对RNN cell结构有一个透彻的理解,一个的最好方法可能是通过创建一个自己的RNN cell结构!以下是用PyTorch中从头创建的一个基本RNN cell的代码:


class CharLoopModel(nn.Module):

    # This is an RNN!

    def __init__(self, vocab_size, in, h):

        super().__init__()

        self.h = h

        self.e = nn.Embedding(vocab_size, in)

        self.l_in = nn.Linear(in, h)

        self.l_hidden = nn.Linear(h, h)

        self.l_out = nn.Linear(h, vocab_size)

        

    def forward(self, *cs):

        '''

        cs (list(list(int))): input signals to propagate forward.

        Example: ((23,32,34), (12,24,23), (12, 45,23))

        '''

        

        bs = cs[0].size(0)

        hidden_state = Variable(torch.zeros(bs, self.h)).cuda()

        for c in cs:

            inp = F.relu(self.l_in(self.e(c)))

            hidden_state = F.tanh(self.l_hidden(hidden_state+inp))

        

        return F.log_softmax(self.l_out(hidden_state), dim=-1)


上面的代码让我们对于RNN Cell内部有了一个较为清晰的认识。请注意,参与形成RNN的两个主要组成部分是self.l_in和self.l_hidden层。通过对__init__和forward方法的分析,我们可以等效地将其表示如下图所示:

 


从上图可以看出,RNN Cell实际上是一组两个完全连接的线性层。这两层都有'h'神经元,其中'h'是隐藏状态的用户指定维度。而在内部所发生的唯一特别的事情就是,在第一层的输出中增加“隐藏状态”。仅此而已。


隐藏状态在层内(以及RNN cell派生其名称的地方)形成一个环式连接(recurrent connection)。在典型的使用情况中,环式连接使得网络能够记住从上一步中所学到的内容。正是由于这个原因,RNN现如今已经被广泛应用于很多依赖于时间或者序列的问题中。


展开的RNN图

 

同样,稍加努力,我们就可以想象出展开RNN图。它显示了环式连接如何从一步骤流向另一步骤的,从而使得RNN cell能够展示其类似于记忆的特征。

 

训练RNN通常一次执行一步。因此,RNN由于不能利用现代硬件的完全并行体系结构而难以训练,这也是被大家所吐槽的。根据问题的性质(以及提出的解决方案),计算只能一步一步前进。以同样的方式,通过RNN cell的反向传播包括在最后一个时间步骤评估梯度,并且一次向后传播一个时间步。

  

随着时间的推移,RNN cell的计算图展示出来

 

最后


RNN被广泛用于时间或序列相关的建模问题。它们对于问题所带来的进展,特别是在机器翻译、语音识别和文本摘要等语言建模领域,已经远远优于传统方法。


在其核心,一个RNN cell(或其任何变体)实际上是一个线性密集层的组合,通过一些适度的连接引入了循环的概念。实际上,现代的RNN架构很少使用我们上面研究的基本RNN cell。相反,他们最经常使用LSTM cell,它只是一种引入更多内部环式连接的RNN cell。最后,对基本RNN cell结构的了解可以帮助更直观地理解更复杂的cell以及它们的功能。


致谢


我再一次感谢Jeremy的fastai课程为在这篇文章提供的许多见解,包括从零开始的RNN的PyTorch实现核心代码。github上附带的源代码(https://github.com/fastai/fastai/blob/master/courses/dl1/lesson6-rnn.ipynb)继续演示如何使用此代码作为示例文本语料库,以及探索RNN的附加变体。


我以前也曾经通过纯tensorflow来实现RNN,但是包括演示在内的端到端的实现(https://github.com/apiltamang/tensorflow_rtp_materials/blob/master/week-7/Vanilla_RNN_Using_Embeddings.ipynb)在这里涉及更多。这个实现的关键是使用tensorflow的扫描方法,它基本上执行了计算图的动态展开,从而使这个问题变得相当混乱!


原文链接:https://medium.com/@apiltamang/unmasking-a-vanilla-rnn-what-lies-beneath-912120f7e56c


欢迎个人分享,媒体转载请后台回复「转载」获得授权,微信搜索「BOBO_AI」关注公众号


中国人工智能产业创新联盟于2017年6月21日成立,超200家成员共推AI发展,相关动态:

中新网:中国人工智能产业创新联盟成立

ChinaDaily:China forms 1st AI alliance

证券时报:中国人工智能产业创新联盟成立 启动四大工程搭建产业生态“梁柱”

工信部网站:中国人工智能产业创新联盟与贵阳市政府、英特尔签署战略合作备忘录


点击下图加入联盟


下载中国人工智能产业创新联盟入盟申请表


关注“雷克世界”后不要忘记置顶

我们还在搜狐新闻、雷克世界官网、腾讯新闻、网易新闻、一点资讯、天天快报、今日头条、雪球财经……

↓↓↓点击阅读原文查看中国人工智能产业创新联盟手册

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RNN经典的模型包括: 1. Vanilla RNN(Simple RNN):它是最简单的RNN模型,每个时间步都有一个隐藏状态,网络结构包括输入层、隐藏层和输出层。 2. LSTM(Long Short-Term Memory):它是一种特殊的RNN,旨在解决长期依赖的问题。它包括输入门、遗忘门和输出门,以及一个记忆单元,网络结构比Vanilla RNN更复杂。 3. GRU(Gated Recurrent Unit):它也是一种特殊的RNN,旨在解决长期依赖的问题。它比LSTM更简单,只包括更新门和重置门,以及一个隐藏状态。 FNN经典的模型包括: 1. MLP(Multilayer Perceptron):它是最基本的前馈神经网络,由一个或多个全连接的隐藏层和一个输出层组成。 2. CNN(Convolutional Neural Network):实际上,CNN也可以看作是一种前馈神经网络,但它特别适用于处理图像,包括卷积层、池化层和全连接层等。 3. Autoencoder:它是一种无监督学习的前馈神经网络,旨在学习数据的压缩表示。它由编码器和解码器组成,其中编码器将数据压缩为一个隐藏状态,解码器将隐藏状态解码为原始数据。 CNN典型的模型包括: 1. LeNet:它是最早的CNN模型之一,由卷积层和池化层组成,用于手写数字识别。 2. AlexNet:它是第一个在ImageNet上获得显著改进的CNN模型,由多个卷积层、池化层和全连接层组成。 3. VGGNet:它是一种非常深的CNN模型,由多个卷积层、池化层和全连接层组成。它有多个版本,其中VGG16和VGG19最为著名。 4. ResNet:它是一种非常深的CNN模型,解决了网络越深性能越差的问题,通过残差块来实现。它有多个版本,其中ResNet50和ResNet101最为著名。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值