一、神经网络计算
1.1人工智能三学派
人工智能:让机器具有人的思维意识
三学派:行为主义(平衡行走)、符号主义(理性思维)、连接主义(感性思维)
连接主义: 准备数据
搭建网络
优化参数
应用网络
1.2神经网络设计过程
鸢尾花分类:具有四种特征,三种类型
搭建网络:Y = X * W + b
(1*3) (1*4) (4*3) (1*3)
X:是输入维数,每列是每个特征的特征值
W:是权重,每行为每个特征值对每种类型的权重
b:为偏移量
Y:输出维度,每列为每种类型的概率
损失函数:表示预测值和真实值差距
目的:找一组w,b使得损失函数最小
梯度下降:沿损失函数梯度下降的方法
反向传播:从后向前逐层求损失函数偏导更新参数
1.3张量生成
张量:从0阶到n阶的数组(0阶是标量,1阶是列表)
1.4TF2常用函数1
1.5TF常用函数2
1.6鸢尾花数据集读入
数据集:Iris包括四个输入特征,三种标签,共150组
1.7鸢尾花分类实现
import tensorflow as tf from sklearn import datasets from matplotlib import pyplot as plt import numpy as np x_data = datasets.load_iris().data y_data = datasets.load_iris().target np.random.seed(116) np.random.shuffle(x_data) np.random.seed(116) np.random.shuffle(y_data) tf.random.set_seed(116) x_train=x_data[:-30] y_train=y_data[:-30] x_test=x_data[-30:] y_test=y_data[-30:] train_db=tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32) test_db=tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32) w1=tf.Variable(tf.random.truncated_normal([4,3],stddev=0.1,seed=1,dtype=tf.float64)) b1=tf.Variable(tf.random.truncated_normal([3],stddev=0.1,seed=1,dtype=tf.float64)) Ir=0.1 train_loss_results=[] test_acc=[] epoch=100 loss_all=0 for epoch in range(epoch): for step,(x_train,y_train) in enumerate(train_db): with tf.GradientTape() as tape: y=tf.matmul(x_train,w1)+b1 y=tf.nn.softmax(y) y_=tf.one_hot(y_train,depth=3) y_ = tf.cast(y_, tf.float64) loss=tf.reduce_mean(tf.square(y_-y)) loss_all+=loss.numpy() grads=tape.gradient(loss,[w1,b1]) w1.assign_sub(Ir*grads[0]) b1.assign_sub(Ir*grads[1]) print("Epoch{},loss{}".format(epoch,loss_all/4)) train_loss_results.append(loss_all/4) loss_all=0 total_correct,total_number=0,0 for x_test,y_test in test_db: y=tf.matmul(x_test,w1)+b1 y=tf.nn.softmax(y) pred=tf.argmax(y,axis=1) pred=tf.cast(pred,dtype=y_test.dtype) correct=tf.cast(tf.equal(pred,y_test),dtype=tf.int32) correct=tf.reduce_sum(correct) total_correct+=int(correct) total_number+=int(x_test.shape[0]) acc=total_correct/total_number test_acc.append(acc) print("Test Accuracy:{}".format(acc)) plt.title("Loss Function") plt.plot(train_loss_results) plt.xlabel("Epoch") plt.ylabel("Loss") plt.show()二、神经网络优化
2.1储备知识
梯度:表示为一个向量,每个分量是函数对每个变量的偏导。方向是函数值增加最快的方向。
一元函数中梯度就是导数,二元及以上就是对各个变量的偏导组成的向量。
同时梯度的每个分量也表示变化率,如多元函数代入具体点后得到(1,-2)这个梯度,含义是沿x轴正方向走一个单位,函数值增加1,沿y轴负方向走一个单位,函数值增加2。 所以(1,-2)所指的是向x轴正方向走1,向y轴负方向走2。最终合成的方向才是梯度的方向
梯度下降:参数更新的方式,自更新方式为减去梯度乘学习率,让损失函数更快减小
如果导数大于0,说明增大参数会让函数增大,所以我们减去导数让参数减小
如果导数小于0,说明增大参数会让函数减小,所以我们减去导数让参数增大
学习率:
激活函数:为神经网络引入非线性,没有激活函数,再深的神经网络都无法拟合复杂的规律。
首先激活函数要是非线性的,其次不能过于复杂,否则在较深的模型前向传播时消耗算力,值域不要过大,可能会数据爆炸,梯度不要过大,反向传播梯度爆炸。同时激活函数最好具备可微性(几乎处处可导),满足反向传播梯度下降的求导需求,才能完成权重 w、偏置 b 的参数更新;输出数值范围也要合理:避免输出无限制疯狂增大,防止梯度消失、梯度爆炸问题。理想情况下最好具备单调性,单层网络损失函数为凸函数,优化更容易收敛。
sigmoid激活函数:优点:具有单调性,能保持输入输出的大小关系一致性。函数范围在0-1符合概率范围,适合二分类任务。缺点:梯度取值范围在0-0.25,在大模型中容易造成梯度消失。
且不靠近0的部分梯度饱和(趋于零),那么w=w-'梯度',会导致参数不更新或更新极慢。
指数计算会消耗算力。
另外sigmoid的输出是全大于0的,因此会导致同一个神经元上的不同参数更新时只能同增或同减,减慢收敛速率。
是损失对这个神经元输出求的偏导。再乘
对wi的偏导等于xi,就是损失对wi的偏导。已知xi为上一层通过sigmoid的输出一定为正,而同一神经元
相同,所以同一神经元的所有wi只能同时蹭大或减少。
会导致本来一增大一减小可以走绿色直线快速收敛,现在只能走z字型线段。
tanh激活函数:是对sigmoid的改进,输出值在-1~1,解决了z字型收敛慢问题。梯度在0-1,改善了梯度消失问题,但两端仍存在梯度饱和,梯度消失仍然存在。另外函数幂运算过于复杂消耗算力。
relu函数:优点:函数简单,计算快。解决了正半轴的梯度消失问题。收敛速度比sigmoid,tanh快。缺点:函数输出都为非负值,限制了收敛速度。当神经元对函数输入小于零时,该神经元的参数将停止更新。为防止出现大量神经元死亡,可以尝试多次初始化,避免过多负数送入relu函数。学习率同时设小,避免参数变化过大导致大量神经元输出变负。
relu同样输出是非负的,会造成锯齿状路径,需要迭代更多次才能收敛
稀疏激活性,有观点认为令部分神经元死亡简化掉过拟合部分是优点。
leaky relu:relu的改善版本,解决relu输入为负梯度消失的问题。
模型训练:
前向传播
损失函数
反向传播
2.2复杂度 学习率
2.3激活函数
首选relu因为效果普遍更好,
学习率设置较小值为了不让参数跨度太大导致神经元输出跨度太大,变成负输出会导致神经元死亡。
输入特征标准化,能统一不同特征的尺度,防止
最后参数初始化是为了让参数有正有负,并且控制参数变化幅度,避免各个神经元输出的变化幅度过大导致进入激活函数的饱和区,梯度消失,而导致收敛过慢
2.4损失函数
一般用于回归任务(预测连续的实数,结果可以是任意大小的数字。)
平方的作用:可以放大误差,原本误差是2,可以变成4。还可以防止正负抵消,如果一个批次的误差有正负四,防止抵消。用绝对值正负两边的梯度会变成定值,不利于找最低点。
自定义损失可以根据自己的需求,为不同情况加上权重。
一般用于分类任务(输出为向量,每个分量是每种可能的概率),真实标签是一个一个分量为1,其余为0的向量。
公式中只剩y-为1的那一项,-lny
y越小,-lny越大,交叉熵损失函数越大,效果越差。
2.5缓解过拟合
增加特征项和参数,让网络学到更多的更复杂的特征
减小正则化参数,减小了对大参数的惩罚, w增大后,可以增强参数(自变量x)变化对函数值的影响,让模型更敏锐,学到更多细节。从而缓解欠拟合。
过拟合可能是数据本身有问题导致的,可以数据清洗去除错误标签,剔除离群异常样本,去除重复样本缓解过拟合。
增大训练集:如果训练数据很少: 真实规律 + 少量样本自带的随机噪声,混在一起。模型分不清哪个是真规律、哪个是噪声,大量数据放一起,噪声会互相抵消;真正的底层规律会反复大量出现。
采用正则化惩罚过大的参数,w减小后,缩小w之间的差距,可以减弱个别输入特征变化对函数值的影响,使函数不容易突变,并学习到大多数特征所具有的规律。
增大正则化系数是在正则化的基础上,加大了对过大参数的惩罚
均方误差加入L2正则化代码
2.6优化器
优化器:接收参数w,b。反向传播更新w,b,使得loss减小
随机梯度下降(SGD):
BGD和MBGD优化时,要先求每个的损失然后然后求平均。用平均梯度去更新参数,SGD则省去求平均这一步。
缺点补充:1.在平坦区域梯度小,更新慢。
2.学习率固定,可能在最优值附近左右横跳。
3.非凸函数只能找到局部最优点
4.不能适应复杂地形,遇到断崖剃度猛增错过最优值
SGDM:参数更新不仅由梯度决定,也与之前的梯度有关
α,β为超参数,a为模型参数w,m为动量且初始为0。
优点:1.缓坡区域梯度小,参数更新还收之前梯度影响,收敛快
2.遇到小坑能冲出去找到全局最优
3.在最优点附近左右震荡时,前一刻梯度与后一刻异号,会使下次更新幅度减少,进而摆脱震荡。
4.同样在跳崖问题,因为削弱了当前梯度对更新参数的影响,所以应对复杂地形表现更好。
AdaGrad:
g是损失函数对参数a的梯度,v是所有梯度的平方和,α为学习率。
AdaGrad可以随参数更新次数,减小学习率,帮助更快收敛。并使每个参数具有独立的学习率,
在遭遇梯度极小的缓坡,把梯度g乘到分子上会增大参数的更新幅度,加快收敛,但分母无限的累加会将学习率带到接近于0,故不适合大量的迭代。
类似的,在前期进入局部最小值点,能依靠把梯度g乘到分子上会增大参数的更新幅度,脱离小坑。但后期由于分子过大,遇到小坑会乏力。
跳崖问题,虽然梯度g很大,但因为学习率存在一个累加梯度的分母,故有一定缓解。
RMSProp
与AdaGrad相比,把权重平方和换成了上一刻动量与此刻的加权和。它的特点也是动态改变学习率,且仅与上一刻和此刻有关,不会造成AdaGrad学习率一直减小。
另外他还有AdaGrad优点
Adam
刚开始的几步,把大部分权重给了v和m,而v0,m0初始为0,使得初始的v,m太小了,偏差修正是为了放大这几步。
缝合了动量的m和RMSProp的v
优点:缓坡时,v会减小,m增大,度过缓坡
局部最小区域同上
复杂地形悬崖,m会被抑制增长,v会一定程度增大
最优值点附近横跳,m会反复改变方向抵消进而减小
adam是一个有效的缓冲,保护参数更新不受突然出现的特殊梯度影响,更新幅度减小时,它会往大了拉,增大时会往小了拽。
三、神经网络八股
3.1搭建网络八股sequential
概述:import(导入模块)->train,test(加载、划分数据集)->sequntial/class(搭建网络)->compile(设置训练方法)->fit(训练模型)
sequential:搭建网络结构
compile:配置网络的训练方法。
fit:执行训练过程。validation_data和validation_split只用填一个
summary:打印网络结构和参数统计
以鸢尾花为例依次调用以上函数
3.2搭建网络八股class
把网络搭建在call函数里面能实现更复杂的网络,应用时只需要创建出对象,fit函数会自动调用call
3.3MNIST数据集
3.4fishion数据集
四、网络八股拓展
4.1搭建网络八股总览
引入模块-》导入、加载数据集-》数据增强-》搭建网络-》设置训练方法-》训练-》可视化-》记录参数-》预测实物
工能扩展
4.2自制数据集
train_path: 所有图像所在文件夹路径
train_txt: 所有图像标签所在txt文件路径,文本格式是每行前部分是图片名,后部分是标签,中间用空格隔开。
x_train_savepath: 将图像转换为数字特征的存储地址,形状为(图像数*28^2),每行是一幅图像像素的拉直。这个是用save函数去保存的。
y_train_savepath: 仅包含标签一维列表,(样本数,),由save函数生成。
首先判断由save函数生成的四个文件(用于训练和测试的数字特征以及标签)是否存在,若存在加载这四个数据集,并把数字特征集的形状修改回(样本数*28*28),然后按照之前的顺序,搭建网络,选择优化方式,用fit训练即可。否则需要借助新函数生成这四个数据集。
新函数如上,输入参数是图片文件夹所在的路径和标签txt的路径。它用图像文件夹路径加图像名得到每个图像的路径并归一化。返回的x(样本数,28*28),y(样本数)
4.3数据增强
前面一大串设置数据增强器image_gen_train,后调用它的fit函数对训练集增强,注意在增强之前要把训练集改成四维。
增强后的数据集在调用model.fit时也要又所在更新,(把x_train,y_train,batch_size调用flow函数写入fit中)
4.4断点续训
用于保存模型训练过的参数,并可以读取,继续训练
先判断保存参数的地址上的文件是否存在,是就直接读取,否则设置cp_callback函数,并在fit中增加callbacks参数保存。
4.5参数提取
首先通过set_printoptions()设置输出不省略数字
在训练完成后,print(model.trainable_variables)就能输出完整的参数矩阵了
后面是将权重记录到txt中,每个v是模型每层的w或b,
存储格式:名字(哪一层的w或b)
形状
参数矩阵
4.6 acc&&loss可视化
history中记录了训练集和测试集的损失和准确率
subplot,设置一行两列的画布,最后一维表示当前代码画在第几列
2.7给图识物
用前向传播predict函数预测结果
复现网络,并加载训练好的参数
根据你输入的图像数量prenum,输入相应个数的地址,大小变成28*28,重构尺寸用ANTIALLAS函数,并转为灰度图
因为训练是黑底白字,现在预测是白底黑字,所以做一个预处理,接着归一化。第三句是在增加了一个维度表示样本数,(1)因为predict接受三维矩阵。
,
五、卷积神经网络
5.1卷积计算过程
每层网络之间都用全连接,会有大量的参数,(每层参数个数=前层神经元个数*后层神经元个数+后层神经元个数)。因此引入卷积,先提取局部特征,再进入全连接层。
对于RGB三通道图像,我们的的卷积核也是三维的(三个二维),输出是三个二维卷积核与对应重合元素相乘全部相加,最终输出的是二维的。
5.2感受野
例如,如图,原图为5*5,卷积核为5*5时输出一个像素点,那么这个像素点的感受野是5*5
5*5的原图经过一个3*3卷积核后会变成3*3,再用第二个3*3后会变成1*1。那么两种方法哪种计算量小呢?
一,(x-2)*(x-2)*9+(x-4)*(x-4)*9
二,(x-4)*(x-4)*25
5.3全零填充
为了让输出图像的像素和输入图像尺度相同,我们在边缘填充0的行为是全零填充。
黄色部分是是否使用全零填充,输出尺寸的计算公式,下图为例子
5.4tf描述卷积层
实例
5.5批标准化
神经网络对0附近的特征效果比较好,数据初始标准化后随着往深层网络的迭代,输入到更深层的特征可能会偏离均值为0,方差为一的标准正态分布。因此在卷积层后面加入批标准化,如图每个输出特征要减去对应卷积核处理数据的均值,除对应方差。
解释一下为什么网络对0附近的特征效果好,因为我们特征的输出是要经过激活函数,例如tanh函数,远离0的部分全部为正负一,模型对输出同为一的特征,感受不到区别,学不到东西。而在0附近,通过激活函数,不同的特征会有区别。模型就能感知到差异。
但是简单的标准化公式又太绝对的把特征限制在了激活函数的线性部分,损失了我们最初引入激活函数的目的,非线性性,因此我们又加了两个参数,去对归一化的特征的胖瘦和位置做一些修改
初始标准化后分布为虚线
人话:又怕特征太偏,又怕太正
批标准化层BN位于卷积层和激活函数之间
代码示例
5.6池化
如图分为最大池化和平均池化,最大池化区每个块里的最大值,平均池化取平均值。最大池化取了每个区域的最大(最重要)信息,最后的输出强调的是边缘轮廓,纹理(边缘纹理处的像素点都是由浅变深或者由深变浅)。而平均池化提取的平均信息,提取的是让图像的整体更平均的背景。
池化可以减少数据特征防止过拟合,减少计算量,增加网络性能。
还具有平移不变形性。如下图,卷积对输入的位置很敏感,导致相似的特征,由于位置不同,得到不同的输出。而我们识别图片最重要在于判断特征是否存在,特征的位置判断可以适当放宽。因此加入池化
如上,加入策划后相比之前在左边多了一列1,也就是说,初始图的1向右移动一位后,输出的第二列仍是1。这就是池化的平移不变性。
以上为tensorflow提供的池化函数
5.7dropout
dropout也算一种正则化,减少模型复杂度,防止过拟合
5.8卷积神经网络
卷积就是卷积+批标准化+激活+池化+dropout
5.9cifar10数据集
plt.imshow()将数字矩阵转换为图像
plt.show()输出图像
5.10卷积神经网络搭建示例
先是六个5*5的卷积核和两个2*2池化,接着是两个分别有128和10个神经元的全连接
用class搭建网络如上
完整网络如上,接下来逐层分块讲解
引入模块并导入数据集
搭建网络
设置模型训练方法,判断是否存在已训练的参数可以加载,设置保存参数的对象,训练模型,可视化模型,保存模型训练参数
可视化训练集和测试集的准确率和损失
5.11LeNet
先用卷积层学习局部特征,再用池化层降低敏感度,最后全连接将学到的特征转换到10维类别空间。用卷积核实现了参数共享,减少网络参数。
5.12AlexNet
相较于LeNet,加入dropout,激活函数由sigmoid变为relu,池化由平均池化变为最大池化
5.13VGGNet
引入VGG块(若干3*3卷积+一个池化),重复若干次,加三个全连接,变成更大更深AlexNet。引入小尺寸的卷积核减小计算量。
5.14InceptionNet
池化层只能改变长宽尺寸而不能改变通道数
对于1*1卷积,不会改变图像的长宽尺寸,可以通过1*1卷积核的个数改变通道数。
InceptionNet的特点在引入了Inception块,从不同的感受野去学习图像的特征,最后对输出做一个通道数上的叠加。同时他也更大更深。在每层应用不同尺寸的卷积核,提升感知能力。使用批标准化,缓解梯度消失。
C:卷积层;B:批量标准化;A:激活函数;P:池化;D:dropout
代码实现如下
封装一个类,将连续的卷积,批标准化,激活函数封装成一条语句
inception块类,c1,c2,c3,c4分别对应四个通道。
类内call函数,执行网络。
5.15ResNet
研究发现,大量一味增加网络层数,会让模型退化(效果变差),即深层网络很难把前面层学到的信息完整传送到后面,多层反复卷积,原始信息慢慢丢失,越学越差。层间跳连,引入前方信息,缓解模型退化
跳连:另外有一条跳连的捷径,直接把最开始的原始输入,不加修改,直接加到卷积输出上面。
“引入前方信息”:就是把前面没经过卷积处理的原始信号,直接绕路送到后面层,不让信息被多层卷积 “磨没”。
ResNet引入ResNet块,不同于InceptionNet堆叠通道数,ResNet选择生成多个相同尺寸通道的特征图简单一一对应相加。如下一般ResNet块有两种情况,经过卷积后通道数改变了或者没改变。第一种情况想要原始特征图和卷积后的特征图相加就要用1*1卷积核改变原始特征图的通道再相加,如虚线;通道数没改变的情况直接相加即可,是实线的情况。
下图设计类封装了这两种情况,在初始化类的时候,通过传入参数residual_path为true或false去设置是否增加对原始特征做1*1卷积的分路(红色部分)。以下代码一次只能生成一个小的黄色块部分。
如下为ResNet18,包括1个卷积+8ResNet块+1全连接
网络搭建如下
紫色部分搭建最前面的卷积,根据上图模块的规律,第一个模块不用1*1卷积,后面模块每个都只是第一个需要1*1卷积,黄色部分根据这个规律,调用前面的模块类生成八个模块。后面部分加上全局池化和全连接。
5.16经典神经网络小结
六、循环神经网络
6.1-6.2循环核
循环神经网络有三个待训练参数w,每个时刻t的输入是x,乘对应权重送到h,此外h还要接收上一时刻h送来的值*权重。最后加上偏置通过激活函数作为送往输出层和下一时刻h的特征。
而t时刻的输出就是t时刻的h输出*权重+偏置经激活函数
提取到的时间特征再送到全连接网络中。
优点:卷积神经网络的输入往往是定长的,而RNN可以解决不定长输入的问题,每次输入一个token ,就是把长句子切成一小块一小块,循环的调用同一个循环体,也就是他们的参数都是一样的
6.3循环计算层
根据需要,可以每层可以设置多个h(设置多个记忆体),一个h那么h的输出是1*1的,两个h输出是1*2的。
6.4tensorflow表述循环层
每个循环核输出ht
只有最后输出ht
输入样本本的维度必须是三维,如下
- 样本数 = 2:一共有 2 条独立数据。
- 样本 1:
0.4,1.7,0.6 - 样本 2:
0.7,0.9,1.6
- 样本 1:
- 时间步数 = 1:每次输入输入一整个样本
0.4,1.7,0.6或0.7,0.9,1.6,因此一步就得到了一个样本的结果,步数为1 - 特征数 = 3:每步输入1个样本,而一个样本有三个特征(三个数),因此一步输入特征数是三。
再如第二个例子,它是把一个样本拆成四部分,每部分两个特征来输入的。因此第一维度样本数为一,循环核时间步数要四步才完成一个样本的输出故为四,每一步又输入两个数字,即两个特征。
6.5循环计算过程(未按时间步展开,输入一个立即得到一个输出)
先将问题中的字母用数字编码
初始化参数矩阵,输入b
更新ht
更新yt
6.6字母预测示例(未按时间步展开)
我们训练RNN,使得输入前面的字母,输出后面的字母a,b,c,d,e,输入e时输出a
导入库,自制数据集,将a,b,c,d,e编码0,1,2,3,4,再变成独热编码
输入特征为字母的独热编码,标签为对应下一个字母对应的数字
打乱数据就循序,将输入特征变为规定的维度(样本数,一个样本分几次输入,每次输入特征数)
构建模型,有三个记忆体,同一时刻三个记忆体不传输特征,t时刻三个记忆体会和上一时刻三个记忆体全连接传输。最后时刻的三个记忆体和五个神经元全连接。
设置模型训练方法
尝试加载参数,训练,打印模型
保存参数,acc,loss可视化
做预测,prenum为预测次数,接着将输入字母转为独热编码输入预测、
6.7循环计算过程2
拿训练好的参数,演示在四个时间步输入后,仅在最后输出预测的计算过程
6.8字母预测(多步输入版)
导入模块,自制数据集,如特征abcd标签是e
随机化打乱顺序
更改训练集维度,搭建网络,设置训练方法
载入参数,训练模型
保存参数,可视化acc,loss
对输入做预测,predict加【】是因为predict函数是设计可以一次性预测多个,老师为了展示方便选择一次预测一个,只想预测一个则必须构造一个列表,将唯一数据放进去,这样predict函数用for遍历的时候才不会出问题
6.9embedding
独热码问题映射之间没有关联性:
embedding编码不仅降低了编码所需的维度,也增加了相关性。
(样本数量100个,用几维编码)形成词汇表大小*编码长度个参数,进行训练。训练完成,做预测时输入一个编号为i的样本,网络会取当前参数的第i行为该样本编码进入下一层
6.10加入embedding层的网络预测实现
导入块,给特征编号,制作训练集和标签,乱序,设置为embedding需要的输入形状
搭建网络,第一层为embedding,设置训练方法,载入参数,训练
保存参数,可视化loss,acc
对输入预测,主要就是设置一下输入的形状
6.11用带embedding层网络预测多时间步输入问题示例
问题:输入前四个字母,输出第五个字母
注意embedding函数第一维是词库数26,不是送入样本数22
主要predict由于可以执行对多个输入的预测,所以输入是2维列表,alphabet是一维,因此要再加一层括号【】
6.13LSTM
对于多步态的序列,RNN很难保留原始输入的记忆,并且随着层数增加,后时刻受最初时刻输入的影响也越来越小。反向向传播时,循环过多也容易梯度消失或爆炸,因此引入LSTM。
每时刻输入的上时刻记忆c对位乘遗忘门得到剩下的记忆,再加上输入门乘候选态得到此时刻的记忆。上一刻记忆只与遗忘门进行了简单的乘法。
他为下一时刻多提供了上一时刻记忆的一个特征,并且无需经过复杂的线性变换(矩阵乘)和非线性变换(激活函数),因此能保留的上一时刻信息的限度更大。
对多步态的序列,模型可以学习到一个接近1的遗忘门,最大程度保留原始时刻的信息。反向传播求导时,Ct对Ct-1的导数就是遗忘门,如果遗忘门接近1,多次连乘也不会出现梯度消失。如果遗忘门接近0,那么说明更早的记忆本就无用,不会影响损失,不必更新。
但输出h中仍存在RNN中的问题
6.14GRU
LSTM参数多,复杂,容易过拟合。我们简化模型引入GRU
r重置门
z更新门
三种结构缺点:只能串行计算速度慢,梯度传播仍会消失例如
反向传播,要链式法则乘zt,仍会梯度消失。最后就是再长的序列信息最后都被存储到一个定长的向量里,存多了肯定要被压缩模糊之前的信息。想表示早期的信息要一步步倒推回去。