大厂必考深度学习算法面试题(一)
【摘要】 内容包含深度学习算法常见的面试题。在只有一个通道的情况下,“卷积核”(“kernel”)就相当于滤波器(“filter”),这两个概念是可以互换的。一个 “Kernel” 更倾向于是 2D 的权重矩阵。而 “filter” 则是指多个 kernel 堆叠的 3D 结构。如果是一个 2D 的 filter,那么两者就是一样的。
一,滤波器与卷积核
在只有一个通道的情况下,“卷积核”(“kernel”
)就相当于滤波器(“filter”
),这两个概念是可以互换的。一个 “Kernel”
更倾向于是 2D
的权重矩阵。而 “filter”
则是指多个 kernel
堆叠的 3D
结构。如果是一个 2D
的 filter
,那么两者就是一样的。但是一个3D
filter
,在大多数深度学习的卷积中,它是包含 kernel
的。每个卷积核都是独一无二的,主要在于强调输入通道的不同方面。
二,卷积层和池化输出大小计算
不管是
TensorFlow
、Keras
、Caffe
还是Pytorch
,其卷积层和池化层的参数默认值可能有所不同,但是最终的卷积输出大小计算公式是一样的。
2.1,CNN 中术语解释
卷积层主要参数有下面这么几个:
- 卷积核
Kernal
大小(在Tensorflow/keras
框架中也称为filter
); - 填充
Padding
; - 滑动步长
Stride
; - 输出通道数
Channels
。
2.2,卷积输出大小计算(简化型)
1,在 Pytorch
框架中,图片(feature map
)经卷积 Conv2D
后输出大小计算公式如下:
,其中
是向下取整符号,用于结果不是整数时进行向下取整(Pytorch
的 Conv2d
卷积函数的默认参数 ceil_mode = False
,即默认向下取整, dilation = 1
)。
- 输入图片大小
W×W
(默认输入尺寸为正方形) Filter
大小F×F
- 步长
S
- padding的像素数
P
- 输出特征图大小
N×N
2,特征图经反卷积(也叫转置卷积) keras-Conv2DTranspose
(pytorch-ConvTranspose2d
) 后得到的特征图大小计算方式:
,还有另外一个写法:
,可由卷积输出大小计算公式反推得到。
是输入大小,
是卷积核大小,
是滑动步长, padding
的像素数
,
是输出大小。
反卷积也称为转置卷积,一般主要用来还原 feature map
的尺寸大小,在 cnn
可视化,fcn
中达到 pixel classification
,以及 gan
中从特征生成图像都需要用到反卷积的操作。反卷积输出结果计算实例。例如,输入:2x2
, 卷积核大小:4x4
, 滑动步长:3
,填充像素为 0
, 输出:7x7
,其计算过程就是, (2 - 1) * 3 + 4 = 7
。
3,池化层如果设置为不填充像素(对于 Pytorch
,设置参数padding = 0
,对于 Keras/TensorFlow
,设置参数padding="valid"
),池化得到的特征图大小计算方式:
,这里公式表示的是除法结果向下取整再加 1
。
总结:对于Pytorch
和 tensorflow
的卷积和池化函数,卷积函数 padding
参数值默认为 0/"valid"
(即不填充),但在实际设计的卷积神经网络中,卷积层一般会填充像素(same
),池化层一般不填充像素(valid
),输出 shape
计算是向下取整。注意:当 stride
为 1
的时候,kernel
为 3
、padding
为 1
或者 kernel
为 5
、padding
为 2
,这两种情况可直接得出卷积前后特征图尺寸不变。
注意不同的深度学习框架,卷积/池化函数的输出
shape
计算会有和上述公式有所不同,我给出的公式是简化版,适合面试题计算,实际框架的计算比这复杂,因为参数更多。
2.3,理解边界效应与填充 padding
如果希望输出特征图的空间维度Keras/TensorFlow
设置卷积层的过程中可以设置 padding
参数值为 “valid” 或 “same”
。“valid”
代表只进行有效的卷积,对边界数据不处理。“same” 代表 TensorFlow
会自动对原图像进行补零(表示卷积核可以停留在图像边缘),也就是自动设置 padding
值让输出与输入形状相同。
参考资料
三,深度学习框架的张量形状格式
-
图像张量的形状有两种约定,通道在前(
channel-first
)和通道在后(channel-last
)的约定,常用深度学习框架使用的数据张量形状总结如下:Pytorch/Caffe
: (N, C, H, W
);TensorFlow/Keras
: (N, H, W, C
)。
-
举例理解就是
Pytorch
的卷积层和池化层的输入shape
格式为(N, C, H, W)
,Keras
的卷积层和池化层的输入shape
格式为(N, H, W, C)
。
值得注意的是 OpenCV
读取图像后返回的矩阵 shape
的格式是 (H, W, C)
格式。当 OpenCV 读取的图像为彩色图像时,返回的多通道的 BGR 格式的矩阵(HWC
),在内存中的存储如下图:
四,Pytorch 、Keras 的池化层函数理解
注意:对于
Pytorch、Keras
的卷积层和池化层函数,其padding
参数值都默认为不填充像素,默认值为0
和valid
。
4.1,torch.nn.MaxPool2d
class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
二维池化层,默认输入的尺度是(N, C_in,H,W)
,输出尺度(N,C_out,H_out,W_out)
。池化层输出尺度的 Width 默认计算公式如下(ceil_mode= True
时是向上取整,Height
计算同理):
主要参数解释:
kernel_size
(int or tuple
):max pooling
的窗口大小。stride
(int or tuple
,optional):
max pooling的窗口移动的步长。默认值是
kernel_size`。padding
(int or tuple
,optional
):默认值为0
,即不填充像素。输入的每一条边补充0
的层数。dilation
:滑动窗中各元素之间的距离。ceil_mode
:默认值为False
,即上述公式默认向下取整,如果设为True
,计算输出信号大小的时候,公式会使用向上取整。
Pytorch
中池化层默认ceil mode = false
,而Caffe
只实现了ceil mode= true
的计算方式。
示例代码:
import torch
import torch.nn as nn
import torch.autograd as autograd
# 大小为3,步幅为2的正方形窗口池
m = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
# pool of non-square window
input = autograd.Variable(torch.randn(20, 16, 50, 32))
output = m(input)
print(output.shape) # torch.Size([20, 16, 25, 16])
4.2,keras.layers.MaxPooling2D
keras.layers.MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)
对于 2D
空间数据的最大池化。默认输入尺寸是 (batch_size, rows, cols, channels)/(N, H, W, C_in)
的 4D
张量,默认输出尺寸是 (batch_size, pooled_rows, pooled_cols, channels)
的 4D
张量。
padding = valid
:池化层输出的特征图大小为: ,这里表示的是向下取整再加 1。padding = same
: 池化层输出的特征图大小为 ,这里表示向上取整。
主要参数解释:
pool_size
: 整数,或者2
个整数表示的元组, 沿(垂直,水平)方向缩小比例的因数。(2,2
)会把输入张量的两个维度都缩小一半。 如果只使用一个整数,那么两个维度都会使用同样的窗口长度。strides
: 整数,2
个整数表示的元组,或者是None
。 表示步长值。 如果是None
,那么默认值是pool_size
。padding
:"valid"
或者"same"
(区分大小写)。data_format
: 字符串,channels_last
(默认)或channels_first
之一。 表示输入各维度的顺序。channels_last
代表尺寸是(batch, height, width, channels)
的输入张量, 而channels_first
代表尺寸是(batch, channels, height, width)
的输入张量。 默认值根据Keras
配置文件~/.keras/keras.json
中的image_data_format
值来设置。如果还没有设置过,那么默认值就是"channels_last"
。
五,Pytorch 和 Keras 的卷积层函数理解
5.1,torch.nn.Conv2d
class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
二维卷积层, 输入的尺度是(N, C_in, H, W)
,输出尺度(N,C_out,H_out,W_out)
。卷积层输出尺度的 Weight
计算公式如下(Height
同理):
Pytorch/Caffe
框架输入输出数据的尺寸都是 ((N, C, H, W)
),常规卷积的卷积核权重shape
都为(C_out, C_in, kernel_height, kernel_width
),常规卷积是这样,但是分组卷积的卷积核权重shape
为(C_out, C_in/g, kernel_height, kernel_width
)和DW
卷积的卷积核 权重shape
为(C_in, 1, kernel_height, kernel_width
)。
kernel_size
, stride
, padding
, dilation
参数可以是以下两种形式( Maxpool2D
也一样):
a single int
:同样的参数值被应用与height
和width
两个维度。a tuple of two ints
:第一个int
值应用于height
维度,第二个int
值应用于width
维度,也就是说卷积输出后的height
和width
值是不同的,要分别计算。
主要参数解释:
in_channels
(int
) – 输入信号的通道。out_channels
(int
) – 卷积产生的通道。kerner_size
(int or tuple
) - 卷积核的尺寸。stride
(int or tuple
,optional
) - 卷积步长,默认值为1
。padding
(int or tuple
,optional
) - 输入的每一条边补充0
的层数,默认不填充。dilation
(int or tuple
,optional
) – 卷积核元素之间的间距,默认取值1
。groups
(int
,optional
) – 从输入通道到输出通道的阻塞连接数。bias
(bool
,optional
) - 如果bias=True
,添加偏置。
示例代码:
###### Pytorch卷积层输出大小验证
import torch
import torch.nn as nn
import torch.autograd as autograd
# With square kernels and equal stride
# output_shape: height = (50-3)/2+1 = 24.5,卷积向下取整,所以 height=24.
m = nn.Conv2d(16, 33, 3, stride=2)
# # non-square kernels and unequal stride and with padding
# m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2)) # 输出shape: torch.Size([20, 33, 28, 100])
# # non-square kernels and unequal stride and with padding and dilation
# m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1)) # 输出shape: torch.Size([20, 33, 26, 100])
input = autograd.Variable(torch.randn(20, 16, 50, 100))
output = m(input)
print(output.shape) # 输出shape: torch.Size([20, 16, 24, 49])
5.2,keras.layers.Conv2D
keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
2D
卷积层 (例如对图像的空间卷积)。输入输出尺寸格式要求和池化层函数一样。输入尺寸:(N, H, W, C)
,卷积核尺寸:(K, K, C_in, C_out
)。
当使用该层作为模型第一层时,需要提供 input_shape
参数(整数元组,不包含 batch
轴),例如,input_shape=(128, 128, 3)
表示 128x128
的 RGB
图像,在 data_format="channels_last"
时。
主要参数解释:
filters
: 整数,输出空间的维度 (即卷积中滤波器的输出数量)。kernel_size
: 一个整数,或者2
个整数表示的元组或列表,指明2D
卷积窗口的宽度和高度。 可以是一个整数,为所有空间维度指定相同的值。strides
: 一个整数,或者2
个整数表示的元组或列表,指明卷积核模板沿宽度和高度方向的移动步长。 可以是一个整数,为所有空间维度指定相同的值。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容,默认取值 1,即代表会不遗漏的滑过输入图片(Feature Map
)的每一个点。padding
:"valid"
或"same"
(大小写敏感),默认valid
,这里的"same"
代表给边界加上Padding
让卷积的输出和输入保持同样("same"
)的尺寸(即填充像素)。data_format
: 字符串,channels_last (默认)
或channels_first
之一,表示输入中维度的顺序。channels_last
对应输入尺寸为(batch_size, height, width, channels)
, channels_first 对应输入尺寸为(batch_size, channels, height, width)
。 它默认为从Keras
配置文件~/.keras/keras.json
中 找到的image_data_format
值。 如果你从未设置它,将使用channels_last
。dilation_rate
: 一个整数或2
个整数的元组或列表, 指定膨胀卷积(空洞卷积dilated convolution
)的膨胀率。 可以是一个整数,为所有空间维度指定相同的值。 当前,指定任何 dilation_rate 值 != 1 与 指定 stride 值 != 1 两者不兼容。
5.3,总结
Pytorch
的 Conv2d
函数不要求提供 输入数据的大小 (H,W)
,但是要提供输入深度,Keras
的 Conv2d
函数第一层要求提供 input_shape
参数 (H,W, C)
,其他层不需要。
六,softmax 回归
分类问题中,直接使用输出层的输出有两个问题:
- 神经网络输出层的输出值的范围不确定,我们难以直观上判断这些值的意义
- 由于真实标签是离散值,这些离散值与不确定范围的输出值之间的误差难以衡量
softmax
回归解决了以上两个问题,它将输出值变换为值为正且和为 1 的概率分布,公式如下:
七,交叉熵损失函数
交叉熵刻画了两个概率分布之间的距离,它是分类问题中使用比较广泛的一种损失函数,交叉熵一般会与 softmax
回归一起使用,公式如下:
- ——代表正确答案;
- ——代表预测值;
- ——类别的数量;
-
——指示变量(
0
或1
),如果该类别和样本的类别相同就是1
,否则是0
; - ——对于观测样本属于类别 的预测概率。
7.1,为什么交叉熵可以用作代价函数
从数学上来理解就是,为了让学到的模型分布更接近真实数据的分布,我们需要最小化模型数据分布与训练数据之间的 KL 散度
,而因为训练数据的分布是固定的,因此最小化 KL 散度
等价于最小化交叉熵,而且交叉熵计算更简单,所以机器/深度学习中常用交叉熵 cross-entroy
作为分类问题的损失函数。
7.2,优化算法理解
Adam
、AdaGrad
、RMSProp
优化算法具有自适应性。
八,感受野理解
感受野理解(Receptive Field
)是指后一层神经元在前一层神经元的感受空间,也可以定义为卷积神经网络中每层的特征图(Feature Map
)上的像素点在原始图像中映射的区域大小,即如下图所示:
注意:感受野在 CNN
中是呈指数级增加的。小卷积核(如 3*3
)通过多层叠加可取得与大卷积核(如 7*7
)同等规模的感受野,此外采用小卷积核有两个优势:
- 小卷积核需多层叠加,加深了网络深度进而增强了网络容量(
model capacity
)和复杂度(model complexity
)。 - 增强了网络容量的同时减少了参数个数。
8.1,感受野大小计算
计算感受野时,我们需要知道:
- 第一层卷积层的输出特征图像素的感受野的大小等于滤波器的大小;
- 深层卷积层的感受野大小和它之前所有层的滤波器大小和步长有关系;
- 计算感受野大小时,忽略了图像边缘的影响。
感受野的计算方式有两种:自底向上和自顶向下(top to down
),这里只讲解后者。正常卷积(且不带 padding
)感受野计算公式如下:
其中
表示第 i
层对第 j
层的局部感受野,所以这个公式是从上层向下层计算感受野的。仔细看这个公式会发现和反卷积输出大小计算公式一模一样,实际上感受野计算公式就是 feature_map
计算公式的反向推导。
以下 Python
代码可以实现计算 Alexnet zf-5
和 VGG16
网络每层输出 feature map
的感受野大小,卷积核大小和输入图像尺寸默认定义好了,代码如下:
# !/usr/bin/env python
# [filter size, stride, padding]
net_struct = {'alexnet': {'net':[[11,4,0],[3,2,0],[5,1,2],[3,2,0],[3,1,1],[3,1,1],[3,1,1],[3,2,0]],
'name':['conv1','pool1','conv2','pool2','conv3','conv4','conv5','pool5']},
'vgg16': {'net':[[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[3,1,1],
[2,2,0],[3,1,1],[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[3,1,1],[2,2,0]],
'name':['conv1_1','conv1_2','pool1','conv2_1','conv2_2','pool2','conv3_1','conv3_2',
'conv3_3', 'pool3','conv4_1','conv4_2','conv4_3','pool4','conv5_1','conv5_2','conv5_3','pool5']},
'zf-5':{'net': [[7,2,3],[3,2,1],[5,2,2],[3,2,1],[3,1,1],[3,1,1],[3,1,1]],
'name': ['conv1','pool1','conv2','pool2','conv3','conv4','conv5']}}
def outFromIn(isz, net, layernum):
"""
计算feature map大小
"""
totstride = 1
insize = isz
# for layer in range(layernum):
fsize, stride, pad = net[layernum]
outsize = (insize - fsize + 2*pad) / stride + 1
insize = outsize
totstride = totstride * stride
return outsize, totstride
def inFromOut(net, layernum):
"""
计算感受野receptive file大小
"""
RF = 1
for layer in reversed(range(layernum)): # reversed 函数返回一个反向的迭代器
fsize, stride, pad = net[layer]
RF = ((RF -1)* stride) + fsize
return RF
if __name__ == '__main__':
imsize = 224
feature_size = imsize
print ("layer output sizes given image = %dx%d" % (imsize, imsize))
for net in net_struct.keys():
feature_size = imsize
print ('************net structrue name is %s**************'% net)
for i in range(len(net_struct[net]['net'])):
feature_size, stride = outFromIn(feature_size, net_struct[net]['net'], i)
rf = inFromOut(net_struct[net]['net'], i+1)
print ("Layer Name = %s, Output size = %3d, Stride = % 3d, RF size = %3d" % (net_struct[net]['name'][i], feature_size, stride, rf))
程序输出结果如下:
layer output sizes given image = 224x224
************net structrue name is alexnet**************
Layer Name = conv1, Output size = 54, Stride = 4, RF size = 11
Layer Name = pool1, Output size = 26, Stride = 2, RF size = 19
Layer Name = conv2, Output size = 26, Stride = 1, RF size = 51
Layer Name = pool2, Output size = 12, Stride = 2, RF size = 67
Layer Name = conv3, Output size = 12, Stride = 1, RF size = 99
Layer Name = conv4, Output size = 12, Stride = 1, RF size = 131
Layer Name = conv5, Output size = 12, Stride = 1, RF size = 163
Layer Name = pool5, Output size = 5, Stride = 2, RF size = 195
************net structrue name is vgg16**************
Layer Name = conv1_1, Output size = 224, Stride = 1, RF size = 3
Layer Name = conv1_2, Output size = 224, Stride = 1, RF size = 5
Layer Name = pool1, Output size = 112, Stride = 2, RF size = 6
Layer Name = conv2_1, Output size = 112, Stride = 1, RF size = 10
Layer Name = conv2_2, Output size = 112, Stride = 1, RF size = 14
Layer Name = pool2, Output size = 56, Stride = 2, RF size = 16
Layer Name = conv3_1, Output size = 56, Stride = 1, RF size = 24
Layer Name = conv3_2, Output size = 56, Stride = 1, RF size = 32
Layer Name = conv3_3, Output size = 56, Stride = 1, RF size = 40
Layer Name = pool3, Output size = 28, Stride = 2, RF size = 44
Layer Name = conv4_1, Output size = 28, Stride = 1, RF size = 60
Layer Name = conv4_2, Output size = 28, Stride = 1, RF size = 76
Layer Name = conv4_3, Output size = 28, Stride = 1, RF size = 92
Layer Name = pool4, Output size = 14, Stride = 2, RF size = 100
Layer Name = conv5_1, Output size = 14, Stride = 1, RF size = 132
Layer Name = conv5_2, Output size = 14, Stride = 1, RF size = 164
Layer Name = conv5_3, Output size = 14, Stride = 1, RF size = 196
Layer Name = pool5, Output size = 7, Stride = 2, RF size = 212
************net structrue name is zf-5**************
Layer Name = conv1, Output size = 112, Stride = 2, RF size = 7
Layer Name = pool1, Output size = 56, Stride = 2, RF size = 11
Layer Name = conv2, Output size = 28, Stride = 2, RF size = 27
Layer Name = pool2, Output size = 14, Stride = 2, RF size = 43
Layer Name = conv3, Output size = 14, Stride = 1, RF size = 75
Layer Name = conv4, Output size = 14, Stride = 1, RF size = 107
Layer Name = conv5, Output size = 14, Stride = 1, RF size = 139
九,卷积和池化操作的作用
卷积核池化的定义核过程理解是不难的,但是其作用却没有一个标准的答案,我在网上看了众多博客和魏秀参博士的书籍,总结了以下答案。
卷积层和池化层的理解可参考魏秀参的《解析卷积神经网络》书籍,卷积(convolution
)操作的作用如下:
局部感知,参数共享
的特点大大降低了网络参数,保证了网络的稀疏性。- 通过卷积核的组合以及随着网络后续操作的进行,卷积操作可获取图像不同区域的不同类型特征;模型靠近底部的层提取的是局部的、高度通用的特征图,而更靠近顶部的层提取的是更加抽象的语义特征。
池化/汇合(pooling
)操作作用如下:
- 特征不变性(feature invariant)。汇合操作使模型更关注是否存在某些特征而不是特征具体的位置可看作是一种很强的先验,使特征学习包含某种程度自由度,能容忍一些特征微小的位移。
- 特征降维。由于汇合操作的降采样作用,汇合结果中的一个元素对应于原输入数据的一个子区域(sub-region),因此汇合相当于在空间范围内做了维度约减(spatially dimension reduction),从而使模型可以抽取更广范围的特征。同时减小了下一层输入大小,进而减小计算量和参数个数。
- 在一定程度上能防止过拟合(overfitting),更方便优化。
参考资料
魏秀参-《解析卷积神经网络》
十,卷积层与全连接层的区别
- 卷积层学习到的是局部模式(对于图像,学到的就是在输入图像的二维小窗口中发现的模式)
- 全连接层学习到的是全局模式(全局模式就算设计所有像素)
十一,CNN 权值共享问题
首先权值共享就是滤波器共享,滤波器的参数是固定的,即是用相同的滤波器去扫一遍图像,提取一次特征特征,得到feature map。在卷积网络中,学好了一个滤波器,就相当于掌握了一种特征,这个滤波器在图像中滑动,进行特征提取,然后所有进行这样操作的区域都会被采集到这种特征,就好比上面的水平线。
十二,CNN 结构特点
典型的用于分类的CNN主要由卷积层+激活函数+池化层组成,最后用全连接层输出。卷积层负责提取图像中的局部特征;池化层用来大幅降低参数量级(降维);全连接层类似传统神经网络的部分,用来输出想要的结果。
CNN
具有局部连接、权值共享、池化操作(简单说就是下采样)和多层次结构的特点。
- 局部连接使网络可以提取数据的局部特征。
- 权值共享大大降低了网络的训练难度,一个Filter只提取一个特征,在整个图片(或者语音/文本) 中进行卷积。
- 池化操作与多层次结构一起,实现了数据的降维,将低层次的局部特征组合成为较高层次的特征,从而对整个图片进行表示。
- 卷积神经网络学到的模式具有平移不变性(
translation invariant
),且可以学到模式的空间层次结构。
Reference
十三,深度特征的层次性
卷积操作可获取图像区域不同类型特征,而汇合等操作可对这些特征进行融合和抽象,随着若干卷积、汇合等操作的堆叠,各层得到的深度特征逐渐从泛化特征(如边缘、纹理等)过渡到高层语义表示(躯干、头部等模式)。
十四,什么样的数据集不适合深度学习
- 数据集太小,数据样本不足时,深度学习相对其它机器学习算法,没有明显优势。
- 数据集没有局部相关特性,目前深度学习表现比较好的领域主要是图像/语音/自然语言处理等领域,这些领域的一个共性是局部相关性。图像中像素组成物体,语音信号中音位组合成单词,文本数据中单词组合成句子,这些特征元素的组合一旦被打乱,表示的含义同时也被改变。对于没有这样的局部相关性的数据集,不适于使用深度学习算法进行处理。举个例子:预测一个人的健康状况,相关的参数会有年龄、职业、收入、家庭状况等各种元素,将这些元素打乱,并不会影响相关的结果。
十五,什么造成梯度消失问题
- 神经网络的训练中,通过改变神经元的权重,使网络的输出值尽可能逼近标签以降低误差值,训练普遍使用BP算法,核心思想是,计算出输出与标签间的损失函数值,然后计算其相对于每个神经元的梯度,进行权值的迭代。
- 梯度消失会造成权值更新缓慢,模型训练难度增加。造成梯度消失的一个原因是,许多激活函数将输出值挤压在很小的区间内,在激活函数两端较大范围的定义域内梯度为0,造成学习停止。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)