2021年深度学习面试题汇总

Posted 沉迷单车的追风少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021年深度学习面试题汇总相关的知识,希望对你有一定的参考价值。

一,滤波器与卷积核

在只有一个通道的情况下,“卷积核”(“kernel”)就相当于滤波器(“filter”),这两个概念是可以互换的。一个 “Kernel” 更倾向于是 2D 的权重矩阵。而 “filter” 则是指多个 kernel 堆叠的 3D 结构。如果是一个 2Dfilter,那么两者就是一样的。但是一个3D filter,在大多数深度学习的卷积中,它是包含 kernel 的。每个卷积核都是独一无二的,主要在于强调输入通道的不同方面

二,卷积层和池化输出大小计算

不管是 TensorFlowKerasCaffe 还是 Pytorch,其卷积层和池化层的参数默认值可能有所不同,但是最终的卷积输出大小计算公式是一样的。

2.1,CNN 中术语解释

卷积层主要参数有下面这么几个:

  • 卷积核 Kernal 大小(在 Tensorflow/keras 框架中也称为filter);
  • 填充 Padding
  • 滑动步长 Stride
  • 输出通道数 Channels

2.2,卷积输出大小计算(简化型)

1,在 Pytorch 框架中,图片(feature map)经卷积 Conv2D输出大小计算公式如下: ⌊ N = W − F + 2 P S + 1 ⌋ \\left \\lfloor N = \\frac{W-F+2P}{S}+1 \\right \\rfloor N=SWF+2P+1,其中 ⌊ ⌋ \\lfloor \\rfloor 是向下取整符号,用于结果不是整数时进行向下取整(PytorchConv2d 卷积函数的默认参数 ceil_mode = False,即默认向下取整, dilation = 1)。

  • 输入图片大小 W×W(默认输入尺寸为正方形)
  • Filter 大小 F×F
  • 步长 S
  • padding的像素数 P
  • 输出特征图大小 N×N

2,特征图经反卷积(也叫转置卷积) keras-Conv2DTransposepytorch-ConvTranspose2d) 后得到的特征图大小计算方式: o u t = ( i n − 1 ) ∗ s − 2 p + k out = (in - 1) *s -2p + k out=(in1)s2p+k,还有另外一个写法: W = ( N − 1 ) ∗ S − 2 P + F W = (N - 1)*S - 2P + F W=(N1)S2P+F,可由卷积输出大小计算公式反推得到。 i n in in 是输入大小, k k k 是卷积核大小, s s s 是滑动步长, padding 的像素数 p p p o u t out out 是输出大小。

反卷积也称为转置卷积,一般主要用来还原 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"),池化得到的特征图大小计算方式: N = ( W − F ) / S + 1 N=(W-F)/S+1 N=(WF)/S+1,这里公式表示的是除法结果向下取整再加 1

总结:对于Pytorchtensorflow 的卷积和池化函数,卷积函数 padding 参数值默认为 0/"valid"(即不填充),但在实际设计的卷积神经网络中,卷积层一般会填充像素(same),池化层一般不填充像素(valid),输出 shape 计算是向下取整。注意:当 stride1 的时候,kernel3padding1 或者 kernel5padding2,这两种情况可直接得出卷积前后特征图尺寸不变。

注意不同的深度学习框架,卷积/池化函数的输出 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)

四,Pytorch 、Keras 的池化层函数理解

注意:对于 Pytorch、Keras 的卷积层和池化层函数,其 padding 参数值都默认为不填充像素,默认值为 0valid

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 计算同理):

⌊ W i n + 2 ∗ padding [ 0 ] − dilation [ 0 ] × ( kernel_size [ 0 ] − 1 ) − 1 stride[0] + 1 ⌋ \\left\\lfloor \\frac{W_{in} + 2 * \\text{padding}[0] - \\text{dilation}[0] \\times (\\text{kernel\\_size}[0] - 1) - 1}{\\text{stride[0]}} + 1 \\right\\rfloor stride[0]Win+2padding[0]dilation[0]×(kernel_size[0]1)1+1

主要参数解释

  • 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:池化层输出的特征图大小为: N = ( W − F ) / S + 1 N=(W-F)/S+1 N=(WF)/S+1这里表示的是向下取整再加 1
  • padding = same: 池化层输出的特征图大小为 N = W / S N = W/S N=W/S这里表示向上取整

主要参数解释:

  • 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 同理):

⌊ W i n + 2 × padding [ 0 ] − dilation [ 0 ] × ( kernel_size [ 0 ] − 1 ) − 1 stride [ 0 ] + 1 ⌋ \\left\\lfloor \\frac{W_{in} + 2 \\times \\text{padding}[0] - \\text{dilation}[0] \\times (\\text{kernel\\_size}[0] - 1) - 1}{\\text{stride}[0]} + 1\\right\\rfloor stride[0]Win+2×padding[0]dilation[0]×(kernel_size[0]1)1+1

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:同样的参数值被应用与 heightwidth 两个维度。
  • a tuple of two ints:第一个 int 值应用于 height 维度,第二个 int 值应用于 width 维度,也就是说卷积输出后的 heightwidth 值是不同的,要分别计算。

主要参数解释:

  • 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) 表示 128x128RGB 图像,在 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,总结

PytorchConv2d 函数不要求提供 输入数据的大小 (H,W),但是要提供输入深度,KerasConv2d 函数第一层要求提供 input_shape 参数 (H,W, C),其他层不需要。

六,softmax 回归

分类问题中,直接使用输出层的输出有两个问题: