【知识点】长文超详讲解深度学习中你总是掌握不牢的若干知识点

您所在的位置:网站首页 基础知识掌握不牢怎么改进 【知识点】长文超详讲解深度学习中你总是掌握不牢的若干知识点

【知识点】长文超详讲解深度学习中你总是掌握不牢的若干知识点

#【知识点】长文超详讲解深度学习中你总是掌握不牢的若干知识点| 来源: 网络整理| 查看: 265

关注“深度学习自然语言处理”,一起学习一起冲鸭!

设为星标,第一时间获取更多干货

作者:云不见

链接:https://blog.csdn.net/Walk_OnTheRoad/article/details/108186355

编辑:王萌 澳门城市大学(深度学习冲鸭公众号)

此笔记是基于《深度学习入门》这本书的重点知识汇总。

连载目录(点击进链接):

豆瓣9.4!《深度学习入门》笔记总结,带你从感知机入门深度学习!(连载)

豆瓣9.4!《深度学习入门:基于Python的理论与实现》学习笔记(2)

手磕实现 CNN卷积神经网络!- 《深度学习入门:基于Python的理论与实现》系列之三

目录:

一、参数的更新

    SGD:

    1、Momentum

    2、AdaGrad

    3、Adam

    使用哪种更新方法呢?

    基于MNIST数据集的更新方法的比较

二、权重的初始值

    隐藏层的激活值的分布

    ReLU的权重初始值

    基于MNIST数据集的权重初始值的比较

三、Batch Normalization

    1、Batch Normalization的算法

    2、Batch Normalization的评估

四、正则化

五、超参数的验证

六、小结

总结

本文重点知识点:

寻找最优权重参数的最优化方法、权重参数的初始值、超参数的设定方法等。

应对过拟合,使用权值衰减、Dropout等正则化方法,并进行实现。

Batch Normalization方法

目的:

高效地进行神经网络(深度学习)的学习,提高识别精度。

如有细节处没有写到的,请继续精读《深度学习入门:基于Python的理论与实现》,对小白来说真的是非常好的深度学习的入门书籍,通俗易懂。(书中的例子主要是基于CV的)

一、参数的更新

神经网络的学习的目的:

找到使Loss函数的值尽可能小的参数。

即最优化:寻找最优参数的问题

为了找到最优参数 ——> 梯度下降法

  SGD:

SGD:随机梯度下降法(stochastic gradient descent)

定义:

使用参数的梯度,沿梯度方向更新参数,并重复这个步骤多次,从而逐渐靠近最优参数。

式(6.1)为SGD更新公式:

SGD的策略:

朝着当前所在位置的坡度最大的方向前进。也就是每看一个example就更新,比GD更快。

SGD缺点:

在解决某些问题时可能没有效率

SGD呈“之”字形移动。这是一个相当低效的路径。

如果函数的形状非均向(anisotropic),比如呈延伸状,就会非常低效。

SGD低效的根本原因是,梯度的方向并没有指向最小值的方向。(所以李宏毅GD1中说要Feature Scaling特征缩放一下,就可以对着圆心更新,效率高)

其它更优于SGD的方法:

Momentum:参照小球在碗中滚动的物理规则进行移动

AdaGrad:为参数的每个元素适当地调整更新步伐。

Adam:将上述两个方法融合在一起

  1、Momentum

式(6.3/4)为Momentum更新公式:

新出现了一个变量v,对应物理上的速度。

式(6.3)表示了物体在梯度方向上受力;αv这一项:在物体不受任何力时,该项承担使物体逐渐减速的任务(α设定为0.9之类的值),对应物理上的地面摩擦或空气阻力。

Momentum方法就像是小球在碗中滚动。

优点:

和SGD相比,“之”字形的“程度”减轻了。

可以更快地朝x轴方向靠近,减弱“之”字形的变动程度。

Momentum的代码实现(源代码在 common/optimizer.py中)

class Momentum: def __init__(self, lr=0.01, momentum=0.9): # momentum = α,设定为0.9 self.lr = lr self.momentum = momentum self.v = None # 初始化时,v中什么都不保存 # 第一次调用 update()时,v会以字典型变量的形式保存与参数结构相同的数据 def update(self, params, grads): if self.v is None: self.v = {} # 变量v 保存物体的速度 for key, val in params.items(): # params.items()为参数权重W self.v[key] = np.zeros_like(val) # v会以字典的形式保存与参数W结构相同的数据 for key in params.keys(): self.v[key] = self.momentum*self.v[key] - self.lr*grads[key] # 式(6.3) params[key] += self.v[key] # 式(6.4) W = W + v

  2、AdaGrad

关于学习率的技巧:

学习率衰减(learning rate decay):

即随着学习的进行,使学习率逐渐减小。一开始“多”学,然后逐渐“少”学的方法,在神经网络的学习中经常被使用。

AdaGrad进一步发展了这个想法,针对“一个一个”的参数,赋予其“定制”的值。

式(6.5/6)为Adagrad更新公式:

变量h ——> 保存以前的所有梯度值的平方和

在更新参数时,通过除以 ,就可以调整学习的尺度(lr)。

参数的元素中变动较大(被大幅更新)的元素的学习率将变小。

即可以按参数的元素进行学习率衰减,使变动大的参数的学习率逐渐减小。

AdaGrad优点:

函数的取值高效地向着最小值移动

刚开始变动较大,但是后面会根据这个较大的变动按比例进行调整,减小更新的步伐。

因此,y轴方向上的更新程度被减弱,“之”字形的变动程度有所衰减。

学习越深入,更新的幅度就越小。如果无止境地学习,更新量就会变为 0,完全不再更新。为了改善这个问题,可以使用 RMSProp [7] 方法。

逐渐地遗忘过去的梯度,在做加法运算时将新梯度的信息更多地反映出来。

即指数移动平均:呈指数函数式地减小过去的梯度的尺度。

用python实现 AdaGrad,(源 代 码 在common/optimizer.py中)

class AdaGrad: def __init__(self, lr=0.01): self.lr = lr self.h = None # 第一次调用 update()时,h会以字典的形式保存与参数结构相同的数据 def update(self, params, grads): if self.h is None: self.h = {} for key, val in params.items(): self.h[key] = np.zeros_like(val) # h会以字典的形式保存与参数结构相同的数据 for key in params.keys(): self.h[key] += grads[key] * grads[key] params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7) # 防止除数为0

  3、Adam

Adam优点:

通过组合前面两个方法的优点:

有望实现参数空间的高效搜索。

进行超参数的“偏置校正”

也像Momentun一样,像小球在碗中滚动。但是,Adam的小球左右摇晃的程度有所减轻。因为学习的更新程度被适当地调整了(Adagrad)。

Adam会设置3个超参数。

一个是学习率(论文中以α出现),

另外两个是一次momentum系数β1和二次momentum系数β2。

根据论文,标准的设定值是β1为0.9,β2 为0.999。设置了这些值后,大多数情况下都能顺利运行。

用python实现 Adam,(源 代 码 在common/optimizer.py中)

class Adam: """Adam (http://arxiv.org/abs/1412.6980v8)""" def __init__(self, lr=0.001, beta1=0.9, beta2=0.999): # 一次momentum系数β1和二次momentum系数β2 self.lr = lr self.beta1 = beta1 self.beta2 = beta2 self.iter = 0 self.m = None self.v = None def update(self, params, grads): if self.m is None: self.m, self.v = {}, {} for key, val in params.items(): self.m[key] = np.zeros_like(val) self.v[key] = np.zeros_like(val) self.iter += 1 lr_t = self.lr * np.sqrt(1.0 - self.beta2**self.iter) / (1.0 - self.beta1**self.iter) for key in params.keys(): #self.m[key] = self.beta1*self.m[key] + (1-self.beta1)*grads[key] #self.v[key] = self.beta2*self.v[key] + (1-self.beta2)*(grads[key]**2) self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key]) self.v[key] += (1 - self.beta2) * (grads[key]**2 - self.v[key]) params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7) #unbias_m += (1 - self.beta1) * (grads[key] - self.m[key]) # correct bias #unbisa_b += (1 - self.beta2) * (grads[key]*grads[key] - self.v[key]) # correct bias #params[key] += self.lr * unbias_m / (np.sqrt(unbisa_b) + 1e-7)

  使用哪种更新方法呢?

比较一下这4种方法(源代码在 ch06/optimizer_compare_naive.py中)。

根据使用的方法不同,参数更新的路径也不同。

只看这个图的话,AdaGrad似乎是最好的,但

其实结果会根据要解决的问题而变。

超参数(学习率等)的设定值不同,结果也会发生变化。

这4种方法各有各的特点,各有擅长和不擅长(就像人一样,你能存粹的比较两个人谁好谁坏嘛)。

很多研究中至今仍在使用SGD。最近,很多研究人员都喜欢用Adam。本书将主要使用SGD或者Adam。

  基于MNIST数据集的更新方法的比较

以手写数字识 别为例,比较SGD、Momentum、AdaGrad、Adam这4种更新方法(源代码在 ch06/optimizer_compare_mnist.py中)。

这个实验以一个5层神经网络为对象,其中每层有100个神经元。激活函数使用的是ReLU。

结论:

与SGD相比,其他3种方法学习得更快,AdaGrad的学习进行得稍微快一点。

不过实验结果会随学习率lr等超参数、神经网络的结构(几层深等)的不同而发生变化。

一般而言,与SGD相比,其他3种方法可以学习得更快,最终的识别精度也更高。

二、权重的初始值

接下来将介绍:

设定什么样的权重初始值(关系到神经网络的学习能否成功)

介绍权重初始值的推荐值:Xavier初始值

通过实验确认神经网络的学习是否会快速进行

为什么要设置权重初始值?

这关系到神经网络的学习能否成功进行下去。

权值衰减(weight decay):

如果想减小权重的值,一开始就将初始值设为较小的值最好。

实际上,我们会 设置 标准差(weitght_int_std)为0.01的高斯分布作为权值W的随机初始值。如下:

W = 0.01 * np.random.randn(10, 100) W = weitght_int_std * np.random.randn(10, 100)

为什么不能直接设置初始值为0,这不是最小嘛?

不能设置为0,如果设置为0,直接把输入杀掉了不是吗。

为什么设置为随机初始值呢?

实际上,权重初始值不能设置为一样的值。

因为如果设置成一样的权重值,在误差反向传播法中,所有的权重值都会进行相同的更新。并拥有了许多重复的值,这使得神经网络拥有许多不同的权重的意义丧失了。为了防止“权重均一化”,必须随机生成初始值,且不能为0。

  隐藏层的激活值的分布

使用Xavier初始值:如果前一层的节点数为n,则初始值使用标准差为 1/√n 的高斯分布进行初始化。

为什么使用Xavier初始值?

为了使各层的激活值呈现出具有相同广度的分布。

因为通过在各层间传递多样性(具有广度)的数据,神经网络可以进行高效的学习。

反过来,如果传递的是有所偏向的数据,就会出现梯度消失或者“广度受限”的问题,导致学习可能无法顺利进行。

权重标准差为1的高斯分布,各层的激活值呈偏向0和1的分布。 sigmoid函数是S型函数,靠近0和靠近1的地方,它的导数逐渐接近0。导致梯度消失。如下图所示:(该实验的源代码在 ch06/weight_init_activation_histogram.py中)

权重初始值:标准差为0.01的高斯分布,各层的激活值的分布集中在0.5附近,不会发生梯度消失,但是广度不够。因为如果有多个神经元都输出几乎相同的值,那它们就没有存在的意义了。如下图所示:

所以使用Xavier初始值, 各层的激活值呈现出具有广度的分布。

如下图所示,权重初始值为:Xavier初始值;激活函数为Sigmoid:

改善稍微歪斜的分布:

激活函数用tanh函数(双曲线函数)代替 sigmoid函数。 如下图所示:

众所周知,用作激活函数的函数最好具有关于原点对称的性质。

而tanh函数就是关于原点对称的S型函数。

  ReLU的权重初始值

He 初始值使用标准差为 √(2/n) 的高斯分布。

(直观上)可以解释为,因为ReLU的负值区域为0,为了使它更有广度,所以需要2倍的系数。

总结:

激活函数/权重初始值sigmoidtanhReLUXavier初始值✔✔He初始值✔

当激活函数使用ReLU时,权重初始值使用He初始值;

当激活函数为 sigmoid或 tanh等S型曲线函数时,初始值使用Xavier初始值。

这是目前的最佳实践。

  基于MNIST数据集的权重初始值的比较

采用不同的权重初始值:std = 0.01、Xavier初始值、He初始值进行实验(源代码在 ch06/weight_init_compare.py中)。得到的结果如下图所示:

这个实验神经网络有5层,每层有100个神经元,激活函数使用的是ReLU。

结论:

std = 0.01时完全无法进行学习

权重初始值为Xavier初始值和He初始值时,学习进行得都很顺利。

并且He初始值学习进度更快一些。

综上,在神经网络的学习中,权重初始值非常重要。关系到能否成功得进行学习。

三、Batch Normalization

  1、Batch Normalization的算法

是什么?

批归一化的算法。以进行学习时的mini-batch为单位,按mini-batch进行正规化。就是进行使数据分布的均值为0、方差为1的正规化。

干什么?方法的思路

为了使各层拥有适当的广度,“强制性”地调整激活值的分布。

即调整各层的激活值分布使其拥有适当的广度。

有什么优点?

可以使学习快速进行(可以增大学习率),训练得时候不用等那么久

不那么依赖初始值(对于初始值不那么神经质)

抑制过拟合(降低Dropout等的必要性)

Batch Norm层放在哪里?

通过将这个处理插入到激活函数的前面(或后面),可以减小数据分布的偏向。使数据分布更广。(近几年主要放激活函数后面多一点)

前面说了,Batch Norm,顾名思义,以进行学习时的mini-batch为单位,按mini-batch进行正规化。就是进行使数据分布的均值为0、方差为1的正规化。

用数学式表示的话,如下所示。

数学公式

接着,Batch Norm层会对正规化后的数据进行缩放和平移的变换,公式如下所示:

这个算法是神经网络上的正向传播,下图所示为Batch Norm正向传播的计算图:

Batch Norm的反向传播的推导有些复杂。不过如果使用图6-17的计算图来思考的话,Batch Norm的反向传播或许也能比较轻松地推导出来。Frederik Kratzert 的博客“Understanding the backward pass through Batch Normalization Layer”[13]里有详细说明,感兴趣可以参考一下。

  2、Batch Normalization的评估

实验一:

使用 MNIST 数据集,观察使用Batch Norm层和不使用Batch Norm层时学习效果怎么样(源代码在 ch06/batch_norm_test.py中),结果如图6-18所示。

结论:

使用Batch Norm后,学习进行得更快了。

实验二:

给予不同的初始值,观察学习的效果。下图是权重初始值的标准差为各种不同的值时的学习过程图。

结论:

几乎所有的情况下都是使用Batch Norm时学习进行得更快

不使用Batch Norm的情况下,特别依赖权重初始值,如果选不好,学习将完全无法进行。

综上,通过使用Batch Norm,可以推动学习的进行。

并且,对权重初始值变得健壮(“对初始值健壮”表示不那么依赖初始值)。

四、正则化

什么是正则化?

为什么要正则化?

防止过拟合

发生过拟合的原因,主要有以下两个。

模型拥有大量参数、表现力强。

训练数据少。

抑制过拟合的技巧:

权值衰减:减小权重参数的值。(后续在 中会详细介绍)

Dropout:在学习的过程中随机删除神经元。(模型复杂,只用权值衰减效果没那么好)

正则化项:假设有权重W = (w1, w2, . . . , wn)

L1范数:各个元素的绝对值之和,相当于|w1| + |w2| + . . . + |wn|。

L2范数:各个元素的平方和,再开根号。

L∞范数:也叫Max范数,取各个元素的绝对值中最大的那一个。

怎么正则化?

1、使用权值衰减的方法:

利用正则化项L2范数,将权值衰减加上L2范数:½λW²。

将这个权值衰减的值加到损失函数中,亦能减少损失函数的值(这是神经网络学习的主要目的呀:减少损失函数的值!)

λ是控制正则化强度的超参数。λ越大,对大的权重W抑制越多。

½的目的是将½λW²的求导结果变成λW。

在求权重梯度时,误差反向传播法的结果则要加上正则化项的导数λW。

做实验:故意造成过拟合

实验一:不使用权值衰减

训练数据的识别精度几乎是100%(可想而知,过拟合多严重啦!)

实验二:使用权值衰减,超参数 λ=0.1

2、使用Dropout的方法:

在学习的过程中随机删除神经元的方法。

即训练时,每传递一次数据,就会随机选择要删除的神经元。

测试时,虽然会传递所有的神经元信号,但是对于各个神经元的输出,要乘上训练时的删除比例后再输出。(深度学习框架中不需要这一步,因为训练时进行了恰当的计算)

Dropout的简单实现:

class Dropout: def __init__(self, dropout_ratio=0.5): # dropout_ratio:删除神经元的比例 self.dropout_ratio = dropout_ratio self.mask = None def forward(self, x, train_flg=True): if train_flg: # 随机生成和x形状相同的数组,并和dropout_ratio相比较。>,mask=True;<,mask=False self.mask = np.random.rand(*x.shape) > self.dropout_ratio return x * self.mask # 返回Fasle的地方 x=0,即删除掉了神经元 else: return x * (1.0 - self.dropout_ratio) # 反向传播时的行为和ReLU相同。正向传播传递了神经元,反向传播按原样传递信号;正向传播没有传递神经元,反向传播信号将停在那里。 def backward(self, dout): return dout * self.mask

做实验:

使用MNIST数据集进行验证,以确认Dropout的效果

前提:使用7层网络(每层有100个神经元,激活函数为ReLU)(挺深的网络)

实验一:没有使用Dropout

实验二:使用Dropout

下图为使用Dropout的网络,虽然有效抑制了过拟合,但是识别精度不是很高,这还和别的超参数的设置有关;比如下图dropout_rate=0.2;我再把dropout_rate=0.15做了一次实验。可以看到识别精度有较大改善。(图二)

总结:

通过使用Dropout,训练数据和测试数据的识别精度的差距变小了。

训练数据也没有到达100%的识别精度。

通过使用Dropout,即便是表现力强的网络(深网络),也可以抑制过拟合。

其实还可以通过改进其它超参数的值来抑制过拟合,而且能使网络的识别精度表现更好,继续看

Dropout 类似于 集成学习

集成学习定义:让多个模型单独进行学习,推理时再取多个模型的输出的平均值。

即 有5个结构相同(或类似)的网络,分别进行学习;测试时,以这5个网络的输出的平均值作为答案。

通过集成学习,神经网络的识别精度可提高好几个百分点。

Dropout可以理解为,通过在学习过程中随机删除神经元,形成了不同的模型,从而每一次都让不同的模型进行学习。并且,推理时,通过对神经元的输出乘以删除比例(比如0.5等),可以取得模型的平均值。

所以Dropout相当于用一个网络随机删除神经元后变成了不同的几个网络,再进行学习。也就是集成学习的意思。

五、超参数的验证

本节介绍高效寻找超参数的值的方法:通过实验不断缩小超参数的范围

什么是超参数?(Hyper-Parameter)

比如各层的神经元数量、batch大小、参数更新时的学习率lr或权值衰减weigh decay等。

为什么要设置合适的超参数?

如果超参数没有设置合适的值,模型的性能就会很差。

训练数据用于参数(权重和偏置)的学习;

测试数据用于评估泛化能力;(比较理想的是只用一次测试数据评估,多次的话会导致数据过拟合测试数据)

还需要一笔验证数据(validation data):用于超参数的性能评估。

为什么不能用测试数据去评估超参数,从而选择合适的超参数?

会导致超参数的值被调整为只拟合测试数据。

验证数据哪里来?

如果数据集只有训练数据和测试数据,则需要自己事先从训练数据中抽一笔出来。比如从训练数据中事先分割出20%做验证数据。

而且,分割训练数据前,先打乱了输入数据和监督标签。这是因为数据集的数据可能存在偏向(比如,数据从“0”到“10”按顺序排列等)。

比如对于MNIST数据集,分割训练数据做验证数据的代码如下所示:

(x_train, t_train), (x_test, t_test) = load_mnist() # 载入MNIST数据集 # 打乱训练数据 x_train, t_train = shuffle_dataset(x_train, t_train) # 分割出验证数据 validation_rate = 0.20 # 从训练数据中事先分割出20%做验证数据 validation_num = int(x_train.shape[0] * validation_rate) # x_train.shape[0]表示训练数据的数量(矩阵数据表示有几行) # 比如有100笔训练数据,则validation_num=20 x_val = x_train[:validation_num] t_val = t_train[:validation_num] # x_val,t_val 表示验证数据 x_train = x_train[validation_num:] t_train = t_train[validation_num:] # 其余数据还给训练数据

使用验证数据观察超参数的最优化方法:不断尝试,减小最优超参数的取值范围,最终确定一个值。

超参数的最优化方法的步骤:

设定超参数的大致范围。(以“10 的阶乘”的尺度指定范围)

从设定的超参数范围中随机采样,随机选择一个超参数。(随机采样的搜索方式效果更好)(尽早放弃那些不符合逻辑的超参数)

使用步骤2中随机选择的超参数的值进行学习,通过验证数据评估识别精度(但是要将epoch设置得很小,从而缩短一次评估所需的时间)。

重复步骤2和步骤3(约100次等),根据它们的识别精度的结果,缩小超参数的范围。

反复进行上述操作,不断缩小超参数的范围,在缩小到一定程度时,从该范围中选出一个超参数的值。

如需更精炼的方法,可以使用贝叶斯最优化(Bayesianoptimization)。贝叶斯最优化能够更加严密、高效地进行最优化。详细内容请参考论文“Practical BayesianOptimization of Machine Learning Algorithms”[16]等。

超参数最优化的具体实现案例

使用MNIST数据集进行超参数的最优化。(源代码在 ch06/hyperparameter_optimization.py中。)

这里我们将 对 学习率 lr 和控制权值衰减强度的系数(下文称为“权值衰减系数”)weight decay 这两个超参数 进行优化。

步骤如下:

1. 设定超参数的大致范围:权值衰减系数 weight decay 的初始范围为,学习率 lr 的初始范围为

2. 随机采样,随机选择一个超参数:超参数的随机采样的代码如下所示。

weight_decay = 10 ** np.random.uniform(-8, -4) lr = 10 ** np.random.uniform(-6, -2)

3. 再使用那些值进行学习。之后,多次使用各种超参数的值重复进行学习。(约100次等)

4. 观察合乎逻辑的超参数在哪里。

学习结果图:

取出“Best-1”到“Best-5”中的超参数的值,缩小两个超参数的范围至 学习率lr = 0.001到0.01、权值衰减系数weight decay在10^−8到10^−6之间时,学习可以顺利进行。

Best-1(val acc:0.77) | lr:0.008991967621142708, weight decay:5.425501025852778e-07 Best-2(val acc:0.77) | lr:0.006609255709609137, weight decay:8.124543461085908e-06 Best-3(val acc:0.76) | lr:0.007539029001714733, weight decay:1.2510664720534263e-06 Best-4(val acc:0.74) | lr:0.006670405931523085, weight decay:2.915136844957729e-05 Best-5(val acc:0.66) | lr:0.005631468995380081, weight decay:2.049732949146344e-07

在这个缩小的范围中,继续上述步骤,再缩小范围。最终选择一个范围内的超参数的值。

六、小结

本章我们介绍了神经网络的学习中的几个重要技巧。

参数的更新方法

权重初始值的赋值方法

Batch Normalization

Dropout等。

而且都在最先进的深度学习中被频繁使用。

总结

参数的更新方法,除 了 SGD 之 外,还 有 Momentum、AdaGrad、Adam等方法。(而且后三者往往比SGD效果好)

权重初始值的赋值方法对进行正确的学习非常重要。

作为权重初始值,Xavier初始值(用于Sigmoid和tanh)、He初始值(用于ReLU)等比较有效。

通过使用Batch Normalization,可以加速学习,并且对初始值变得健壮(不那么敏感)。

抑制过拟合的正则化技术有权值衰减、Dropout等。

通过验证数据,进行实验,来逐渐缩小超参数最优值的范围是最终选择超参数的一个有效方法。

注:如有细节处没有写到的,请继续精读《深度学习入门》,对小白来说真的是非常通俗易懂的深度学习入门书籍。(书中的例子主要是基于CV的)

说个正事哈

由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:

(1)点击页面最上方“深度学习自然语言处理”,进入公众号主页。

(2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。

感谢支持,比心

投稿或交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。

方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等。

记得备注呦

推荐两个专辑给大家:

专辑 | 李宏毅人类语言处理2020笔记

专辑 | NLP论文解读

整理不易,还望给个在看!


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3