从零实现深度学习框架——seq2seq从理论到实战理论(代码片段)

愤怒的可乐 愤怒的可乐     2022-12-08     652

关键词:

引言

本着“凡我不能创造的,我就不能理解”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。

要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽量不使用外部完备的框架前提下,实现我们想要的模型。本系列文章的宗旨就是通过这样的过程,让大家切实掌握深度学习底层实现,而不是仅做一个调包侠。

本文介绍seq2seq模型,由论文Sequence to Sequence Learning with Neural Networks提出,能解决输入和输出序列长度不等的任务——机器翻译、自动摘要、自动问答等。

博主针对该经典论文提供了中文翻译:[论文翻译]Sequence to Sequence Learning with Neural Networks

Seq2Seq

Seq2Seq网络即sequence to sequence,序列到序列网络,输入一个序列,输出另一个序列。这个架构重要之处在于,输入序列和输出序列的长度是可变的。

Seq2Seq使用的具体方法基本都属于编码器-解码器模型。

其核心思想是通过编码器(Encoder)将输入序列编码成一个定长的向量表示,也称为具有上下文信息的表示,简称为上下文(context)。然后将上下文向量喂给解码器(Decoder),来生成任务相关的输出序列。

总结一下,编码器-解码器架构包含三个组件:

  • 编码器接收一个输入序列, x 1 n x^n_1 x1n,然后生成对应的上下文表示, h 1 n h^n_1 h1n。常用于编码器的网络可以为RNN、CNN或Transformer等。
  • 上下文向量 c c c,由一个函数基于 h 1 n h_1^n h1n生成,传递输入的核心信息到解码器。
  • 解码器接收 c c c作为输入,然后生成一个任意长度的隐藏状态序列 h 1 m h_1^m h1m,从中可以得到对应的输出 y 1 m y_1^m y1m。和编码器一样,也有多种实现方案。

基于RNN实现编码器-解码器

[翻译]Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation使用RNN作为编码器和解码器实现机器翻译。

我们本小节来看如何通过RNN来实现编码器-解码器网络。

实际上会有两个不同的RNN网络,一个作为编码器,将变长的输入序列转换为定长的编码(上下文向量);另一个作为解码器,通过该上下文向量连续生成输出序列,基于输入序列的编码信息和输出序列已经生成的单词来预测一下单词。上图演示了如何在机器翻译中使用两个RNN进行序列号序列学习。

这里有两个特殊单词<eos><bos>,分别表示序列结束和开始标志。

还有一种方式,如上图,我们只需要在输入末尾添加<EOS>,比如这里有输入序列A B C <EOS>。我们将输入序列传入模型后,将其映射为序列W X Y Z <EOS>作为输出。

回顾RNN语言模型计算序列 y y y的概率 p ( y ) p(y) p(y)
p ( y ) = p ( y 1 ) p ( y 2 ∣ y 1 ) p ( y 3 ∣ y 1 : 2 ) ⋯ p ( y m ∣ y 1 : m − 1 ) = ∏ k = 1 m p ( y k ∣ y 1 : k − 1 ) (1) p(y) = p(y_1)p(y_2|y_1)p(y_3|y_1:2) \\cdots p(y_m|y_1:m-1) = \\prod_k=1^m p(y_k|y_1:k-1) \\tag 1 p(y)=p(y1)p(y2y1)p(y3y1:2)p(ymy1:m1)=k=1mp(yky1:k1)(1)
即我们先生成输出序列第一个单词 y 1 y_1 y1,然后根据 y 1 y_1 y1生成 y 2 y_2 y2,然后根据 y 1 , y 2 y_1,y_2 y1,y2生成 y 3 y_3 y3,依此类推,这是典型的自回归(Autoregressive model)模型。

自回归模型(英语:Autoregressive model,简称AR模型),是统计上一种处理时间序列的方法,用同一变量例如 x x x的之前各期,即 x 1 t − 1 x_1^t-1 x1t1来预测本期 x t x_t xt的表现,并假设它们为一线性关系。因为这是从线性回归发展而来,不过不用 x x x预测 y y y,而是用 x x x预测 x x x(自己)。因此叫做自回归

——维基百科

编码器的目标是生成一个输入的上下文表示,体现在编码器最后的那个隐藏状态, h n e h_n^e hne,也用 c c c来表示,代表上下文。

在时刻 t t t,将前面的 t − 1 t-1 t1个单词输入到语言模型,通过前向推理生成隐藏状态序列,并且以最后一个单词的隐藏状态作为起点来生成下一个单词。

g g g为激活函数(tanh或ReLU),计算时刻 t t t的输出和隐藏状态 h t h_t ht的公式为:
h t = g ( h t − 1 , x t ) (2) h_t = g(h_t-1,x_t) \\tag 2 ht=g(ht1,xt)(2)

最后,编码器通过特定的函数 q q q,将所有时间步的隐藏状态转换为上下文向量 c c c
c = q ( h 1 , ⋯   , h t ) (3) c = q(h_1,\\cdots,h_t) \\tag 3 c=q(h1,,ht)(3)
这里实际上是简单地选择 q ( h 1 , ⋯   , h t ) = h t q(h_1,\\cdots,h_t) = h_t q(h1,,ht)=ht,上下文变量仅仅是输入序列最后时间步的隐状态 h t h_t ht

而解码器接受 c c c作为输入,用于初始化解码器的第一个隐藏状态。即, 第一个解码器RNN单元使用 c c c作为初始隐藏状态 h 0 d h_0^d h0d,同时结合本身的输入自回归地生成一系列输出,一次输出一个元素,知道输出了结束符或者达到最大长度限制。每个隐藏状态以前一隐藏状态和前一隐藏状态生成的输出作为输入(条件):
h t d = g ( y ^ t − 1 , h t − 1 d ) (4) h_t^d = g(\\hat y_t-1, h_t-1^d) \\tag 4 htd=g(y^t1,ht1d)(4)

但是,这种方法有一个弱点是,随着输出序列的生成,上下文向量 c c c的影响将逐渐减弱。一种常用的解决方法是让解码过程的每个时刻都能看到上下文向量 c c c
h t d = g ( y ^ t − 1 , h t − 1 d , c ) (5) h_t^d = g(\\hat y_t-1, h_t-1^d , c) \\tag 5 htd=g(y^t1,ht1d,c)(5)
现在,我们解码器的完整公式,每个解码时间步都可看到上下文。 g g g以某种程度上代表RNN,从零实现深度学习框架收藏

...了这一项工作,看着通过我们自己的框架实现的RNN、seq2seq、BERT等技术时,一种自豪感油然而生。同时在这个过程中,我们会对其他的技术细节有深入的理解。对于我们使用、调试现有的自动求导库,如PyTorch都非... 查看详情

对比学习:《深度学习之pytorch》《pytorch深度学习实战》+代码

...PyTorch》,可以从机器学习和深度学习的基础理论入手,从零开始学习PyTorch,了解PyTorch基础,以及如何 查看详情

从零实现深度学习框架——学习率调整策略介绍

...就不能理解”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽量不使用外部完备... 查看详情

深度学习理论与实战pytorch实现

...阶)09.毕业项目 下载地址:深度学习理论与实战PyTorch实现 查看详情

keras深度学习实战(15)——从零开始实现yolo目标检测(代码片段)

Keras深度学习实战(15)——从零开始实现YOLO目标检测0.前言1.YOLO目标检测模型1.1锚框(anchorboxes)1.2YOLO目标检测模型原理2.从零开始实现YOLO目标检测2.1加载数据集2.2计算锚框尺寸2.3创建训练数据集2.4实现YOLO目标检测模型2.5... 查看详情

入门实战《深度学习技术图像处理入门》+《视觉slam十四讲从理论到实践》

...,逐步阐述深度学习图像处理技术的基本原理以及简单的实现。 学习理论后做实验,使用卷积神经网络进行端到端学习,构建深度卷积神经网络,使用循环神经网络改进模型,评估模型,测试模型。最关键的是可以将模型运... 查看详情

从零实现深度学习框架——计算图运算补充

...能理解”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽量... 查看详情

机器学习深度学习的理论与实战入门建议整理

...自底向上的学,也就是先从理论和数学开始,然后是算法实现,最后再通过一些项目去解决生活中的实际问题;有的人则可能适合自顶向下的学,也就是在弄清楚什么是机器学习及为什么学机器学习后,先确定一个系统性的用机... 查看详情

keras深度学习实战(23)——dcgan详解与实现(代码片段)

...AN生成手写数字图像2.使用DCGAN生成面部图像2.1模型分析2.2从零开始实现DCGAN生成面部图像小结系列链接0.前言在生成对抗网络(GenerativeAdversarialNetworks,GAN)一节中,我们使用原始GAN生成了数字图片。从之前的相关学习中,我们已经知... 查看详情

keras深度学习实战(23)——dcgan详解与实现(代码片段)

...AN生成手写数字图像2.使用DCGAN生成面部图像2.1模型分析2.2从零开始实现DCGAN生成面部图像小结系列链接0.前言在生成对抗网络(GenerativeAdversarialNetworks,GAN)一节中,我们使用原始GAN生成了数字图片。从之前的相关学习中, 查看详情

第3章神经网络《深度学习入门基于python的理论与实现》

第3章神经网络《深度学习入门基于Python的理论与实现》3.1从感知机到神经网络3.2激活函数3.1从感知机到神经网络 查看详情

免费的中文深度学习全书:《深度学习理论与实战:提高篇》

在线阅读:深度学习理论与实战:提高篇序言16年9月的时候我在CSDN发了一些深度学习的文章,主要是面向没有太多经验的开发者。达文读了后觉得我的文章比较通俗易懂,邀请我写一本书,当时头脑一热就答应下来。虽然现在... 查看详情

javaspi06-自己从零手写实现spi框架

...bo实现源码解析spi05-dubboadaptiveextension自适应拓展spi06-自己从零手写实现SPI框架spi07-自动生成SPI配置文件实现方式回顾学习了java的SPI和dubbo的SPI实现之后,希望实现一个属于自己的SPI框架 查看详情

序列到序列学习seq2seq束搜索beamsearch动手学深度学习v2

1.序列到序列学习seq2seq2.代码实现3.束搜索beamsearch4.Q&A现在seq2seq都用transformer了。但是过段时间,有可能又会发现可能RNN/LSTM会更好。深度神经网络是一波又一波的。参考https://www.bilibili.com/video/BV16g411L7FG?p=1 查看详情

阅读书单2020

...实践原理Maven实战Grale实战Spring实战(第四版)Spring源码深度解析(第2版)从Paxos到ZooKeeper分布式一致性原理实战MySQL技术内幕InnoDB存储引擎第2版MyBatis从入门到精通MongoDB实战(第二版)应用密码学协议、算法与C源程序深入浅出密码... 查看详情

从零开始实现一个深度学习框架|激活函数,损失函数与卷积层(代码片段)

往期回顾super(Sigmoid,self).__init__()x=/(+np.exp(-x))xp=self.forward(self.storage[gradient=p*(-p)accumulated_gradient*gradientsuper(Tanh,self).__init__()x=/(+np.exp(*x))-xp=self.forward(self.storage[grad 查看详情

《动手学深度学习》线性回归从零开始(linear-regression-scratch)(代码片段)

线性回归的从零开始实现前言1.生成数据集2.读取数据3.初始化模型参数4.定义模型5.定义损失函数6.定义优化算法7.训练模型8.小结前言在了解了线性回归的背景知识之后,现在我们可以动手实现它了。尽管强大的深度学习框架... 查看详情

《动手学深度学习》线性回归从零开始(linear-regression-scratch)(代码片段)

线性回归的从零开始实现前言1.生成数据集2.读取数据3.初始化模型参数4.定义模型5.定义损失函数6.定义优化算法7.训练模型8.小结前言在了解了线性回归的背景知识之后,现在我们可以动手实现它了。尽管强大的深度学习框架... 查看详情