ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

深度学习神经网络层全解析:从全连接到注意力机制

深度学习神经网络层全解析:从全连接到注意力机制 第一次接触深度学习的人十有八九会被各种“层”搞得一头雾水全连接层、卷积层、池化层、激活函数层、归一化层、Dropout层……打开PyTorch的torch.nn模块几十种层摆在面前根本不知道该先学哪个、什么时候用哪个。其实深度学习的模型搭建本质上就是像搭积木一样把不同的神经网络层按照一定顺序组合起来让数据从输入到输出经过层层加工最后得到我们想要的分类、回归、生成等结果。这篇内容我打算把“常用的神经网络层”一次性讲透。不单讲每个层是干什么的还会把每层背后的数学原理、PyTorch里的具体写法、参数量怎么算、踩坑点在哪里都交代清楚。内容围绕全连接层、激活函数层、卷积层、池化层、归一化层、Dropout层、循环层、注意力层这些最常见的结构展开适合刚入门不知道怎么搭网络的初学者也适合跑得通代码、但对张量shape变化和一票参数细节还似懂非懂的同学。1. 先建立直觉神经网络层到底是什么1.1 神经网络层就是一条“可以训练的流水线”理解层之前先用一个生活场景类比。你开了一家小吃店要做一道招牌菜后厨是一条流水线第一个人负责洗菜切菜第二个人负责腌制调味第三个人负责下锅炒第四个人负责摆盘。每个工位都只干一件事把自己的产出交给下一个工位最终端出来的菜品就是“输入数据”经过一系列加工的产物。神经网络层就是这条流水线上的一个个工位。每个工位接收来自上一层的输出数据对它做一次数学变换再把结果传递给下一层。区别在于流水线工人的手艺是固定的而神经网络层里的“手艺”——也就是权重和偏置是模型在训练中通过损失函数反向传播逐步学出来的。换句话说深度学习的“深度”只是意味着你摆了足够多的工位让数据被变换了很多次每一层都可以理解成在高维空间里对特征做一次重新的组织与表达。很多人容易陷入一个误区觉得自己只要把一堆层拼起来模型就会自动变好。其实每一层都有它存在的理由有的是为了提取特征有的是为了压缩数据有的是为了让训练更稳定。理解“层”的本质不是背API文档而是搞清楚某一个层在流水线上到底扮演什么角色它解决了什么问题又带来了什么副作用。这才是深度学习基本功的核心。1.2 张量shape搞懂层与层之间的“接口协议”层和层之间传递的数据重头戏就是张量。张量的“形状”shape可以理解成工位之间交接货物的包装规格。你从仓库取出的原料是固定尺寸的纸箱切菜工要求纸箱必须是某个尺寸炒菜工又要求另一种尺寸如果环节之间尺寸对不上流水线立刻卡壳。在深度学习中最常见的几种shape约定如下全连接层Linear输入通常是二维张量形状为 [batch_size, features]也就是一批样本每个样本有若干特征。卷积层Conv2d输入是四维张量形状为 [batch_size, channels, height, width]额外多了通道数和二维空间尺寸。循环层LSTM/RNN输入通常是 [batch_size, seq_len, hidden_size] 或 [seq_len, batch_size, hidden_size]多了一个时间步维度。举例来说假设你有一个1000张28×28灰度图片的分类任务输入张量就是 [1000, 1, 28, 28]。如果你想把这组数据丢进全连接层必须先把它拉平成 [1000, 784]。很多新手第一次写代码报错就是报在这个地方全连接层收到了四维输入维度对不上程序直接崩溃。所以我建议每写完一个模型先随手打印每一层的输出shape确认数据流是通的再开始训练。2. 全连接层与激活函数入门必学的第一对组合2.1 全连接层最简单的加权求和偏置变换全连接层的公式非常简单y xW^T b。输入是一批向量x经过一个线性变换矩阵W的转置相乘再加上偏置b得到输出y。为什么要加偏置你可以把它理解为直线方程里的截距。如果没有b所有经过这个层的变换都必须过原点模型表达能力会被严重影响。所以在PyTorch里nn.Linear默认biasTrue一般不需要动它。PyTorch里定义一个全连接层写法是nn.Linear(in_features, out_features)。in_features是输入特征的维度out_features是输出特征的维度。它的参数量怎么算很简单in_features × out_features再加上out_features个偏置。举个例子输入是10个特征输出128个神经元那么参数量就是10 × 128 128 1408。全连接层的应用场景非常广。分类模型最后的分类头几乎都是不带激活函数的全连接层把前面的特征输出映射成类别得分。Transformer结构里的Feed-Forward NetworkFFN本质上也是两个全连接层叠加中间夹一个激活函数。你甚至可以把它理解成一种“特征再组合”的模块让网络学习到更高阶的特征交互。一个常见的问题是很多人会把全连接层叫成“Dense层”其实是一回事。TensorFlow/Keras里叫DensePyTorch里叫LinearMATLAB深度学习工具箱里叫fullyConnectedLayer。不同框架叫法不同背后的数学操作完全一样。如果你在面试或读论文时看到“FC层”“Dense层”“线性层”“稠密层”指的都是这东西。2.2 激活函数非线性是网络表达力的来源为什么全连接层后面一定要接激活函数因为如果整个网络里全是线性变换那么无论堆多少层最终整个网络依然是一次线性变换——把多层矩阵相乘合并起来本质上还是y xW b模型的表达能力上不去。非线性激活函数的作用就是给网络注入“弯曲”的能力让它可以逼近任意复杂的函数关系。实际工程里不同激活函数的取舍差异非常大。我整理了一个对比表方便你快速做选择激活函数公式取值范围优点缺点常见场景Sigmoidσ(x) 1/(1e^{-x})(0, 1)输出可解释为概率梯度饱和严重容易梯度消失输出非零均值二分类输出层Tanhtanh(x)(-1, 1)零均值比Sigmoid好一点依然存在梯度饱和RNN/简单网络ReLUmax(0, x)[0, ∞)计算快缓解梯度消失效果好负区间梯度全为0可能“死神经元”CNN主流默认选择LeakyReLUmax(0.01x, x)(-∞, ∞)负区间保留小梯度缓解死神经元参数需要调不稳定存在死神经元时替代ReLUELUx0时xx≤0时α(e^x-1)(-α, ∞)负区间平滑输出均值接近0指数计算开销略高对噪声敏感的任务GELUx·Φ(x)(-∞, ∞)Transformer常用光滑近似ReLU计算稍复杂BERT、GPT等Transformer结构SiLU/Swishx·σ(x)(-∞, ∞)平滑、效果好近年在视觉模型中流行计算开销高于ReLU新一代CNN/TransformerReLU为什么能成为主流因为它简单计算只有一次max操作而且正区间的梯度恒为1不会像Sigmoid那样在深层传播时把梯度越乘越小。但它有个经典的坑当一个神经元的输入一直落在负区间梯度永远为0参数再也无法更新这个神经元就“死”了。LeakyReLU就是专门为缓解这个问题设计的保留了一个很小的负斜率。代码里组合一个简单分类头通常是这样的import torch.nn as nn model nn.Sequential( nn.Linear(784, 256), nn.ReLU(inplaceTrue), nn.Linear(256, 64), nn.ReLU(inplaceTrue), nn.Linear(64, 10) )我的个人经验是对于第一次做CV任务的模型不要纠结激活函数直接用ReLU稳定又省心。如果训练中check了一下各层输出发现某层输出大量为0才考虑换成LeakyReLU或ELU。另外inplaceTrue可以省一点显存但在需要保留前向中间结果用于特殊操作的场景下要慎用。3. 卷积层与池化层图像任务的核心玩法3.1 卷积层用局部视野和参数共享处理图像图像如果用全连接层处理参数会发生爆炸。一张普通的256×256三通道图片拉平后有196608个特征如果第一层全连接想输出1024个神经元只见参数就达到两亿完全没法训练。卷积层通过两个关键策略解决这个问题局部连接和参数共享。局部连接的意思是每个输出神经元只和输入的一个“小窗口”相连而不是和全图相连这个窗口就是kernel_size常见的是3×3、5×5。参数共享的意思是同一个卷积核在整张图上滑动扫过图里所有位置时用的都是同一套权重。局部连接控制住了参数数量参数共享进一步把所有位置的参数压到极小。PyTorch里Conv2d的关键参数有这些参数含义示例in_channels输入通道数彩色图就是3out_channels输出通道数也是卷积核个数64kernel_size卷积核大小3stride滑动步长1或2padding边缘填充1表示上下左右各补一圈0dilation空洞卷积的膨胀率1是普通卷积groups分组卷积的组数等于in_channels就是深度可分离卷积输出尺寸的计算公式是H_out (H_in 2 * padding - dilation * (kernel_size - 1) - 1) / stride 1W_out同理。举一个计算例子输入[32, 3, 224, 224]经过nn.Conv2d(3, 16, kernel_size3, stride1, padding1)H_out (224 2 - 3 - 1)/1 1 224输出就是[32, 16, 224, 224]尺寸不变但通道数变多。如果stride2、padding1H_out (224 2 - 3 - 1)/2 1 112输出分辨率降了一倍这其实就是很多网络用来做下采样的方式。另外值得单独说的是1×1卷积。它不会改变空间尺寸作用是在通道维度上做线性组合相当于一个跨通道的全连接层。ResNet的Bottleneck结构就用1×1卷积做通道降维再升维大幅减少计算量。MobileNet里的深度可分离卷积也是利用groups参数把普通卷积拆成逐通道卷积和1×1卷积把计算量压缩到极低。3.2 池化层下采样和局部不变性的低成本方案池化层的作用很直白压缩数据、降低分辨率、扩大感受野。最常用的是MaxPool2d和AvgPool2d。MaxPool取窗口里的最大值能保留纹理、边缘等“强响应”特征AvgPool取窗口平均值更多保留整体统计信息。池化层和卷积层一样有kernel_size、stride、padding等参数。它的特点是没有可学习参数纯做下采样计算开销几乎可以忽略同时具备一定的平移不变性——目标在图像里稍微移动几个像素池化结果往往不会大变。不过近几年的趋势是很多新出的网络比如ResNet倾向于用stride2的卷积代替池化下采样因为卷积层可学习理论上能保留更多信息。但这不是说池化没用了在轻量级网络、传统常规CNN里MaxPool仍然非常常用。还有一个变体叫GlobalAvgPooling它把整个特征图压缩成1×1的输出在分类任务中直接接在全连接层之前把特征图从[B, C, H, W]变成[B, C]参数少还能防止过拟合很多经典网络都用这种设计。池化层有一个特别容易被忽略的细节MaxPool在反向传播时只会把梯度回传到前向时取最大值的位置其余位置梯度为0。所以如果你的输入里刚好有几个位置的数值特别大这些位置可能会被反复选中让训练结果偏向于关注某些局部区域。这个现象在特征分布极端的情况下会很明显所以一般建议卷积层后面先接BatchNorm再接激活和池化让数据分布稳定在相对正常的范围。3.3 实操示例用5层CNN跑一个图像分类器我直接给一个可以跑通的基础CNN结构这个结构在CIFAR-10这类小数据集上效果不错也是我当年入门时的第一个完整模型。代码基于PyTorchimport torch import torch.nn as nn class SimpleCNN(nn.Module): def __init__(self, num_classes10): super().__init__() self.features nn.Sequential( nn.Conv2d(3, 32, kernel_size3, padding1), nn.BatchNorm2d(32), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), nn.Conv2d(32, 64, kernel_size3, padding1), nn.BatchNorm2d(64), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), nn.Conv2d(64, 128, kernel_size3, padding1), nn.BatchNorm2d(128), nn.ReLU(inplaceTrue), nn.AdaptiveAvgPool2d((1, 1)) ) self.classifier nn.Linear(128, num_classes) def forward(self, x): x self.features(x) x x.view(x.size(0), -1) return self.classifier(x) model SimpleCNN(num_classes10)以输入[32, 3, 224, 224]为例数据的shape变化是这样的卷积层输出[32, 32, 224, 224]池化后变成[32, 32, 112, 112]再经过一层卷积输出[32, 64, 112, 112]池化变成[32, 64, 56, 56]再经过一层卷积输出[32, 128, 56, 56]池化变成[32, 128, 28, 28]最后AdaptiveAvgPool2d拉成[32, 128, 1, 1]view展平后是[32, 128]分类头输出[32, 10]。训练的时候我的建议是先从50个epoch左右开始优化器用Adam初始学习率设0.001batch size根据显存选32到128之间。训练过程中画一下loss曲线和验证集准确率曲线如果训练loss下降但验证准确率涨不上去多半是过拟合如果训练loss不降先看学习率是不是太大或太小。这就是热词里常说的“epoch”和“损失函数”在实战中的意义——它们不是孤立概念而是判断模型状态最直接的工具。4. 归一化层与丢弃层训练稳定的功臣4.1 BatchNorm训练过程稳定的关键层很多新手在搭建网络时不理解为什么卷积后面总要接一个nn.BatchNorm2d。这个问题其实要回到“数据分布”说起。如果模型每一层的输入分布都在不断变化那网络参数调整就会像追着一个移动靶打收敛特别慢。BatchNorm做的事是对每个通道在batch维度上计算均值和方差然后归一化到均值为0、方差为1的标准分布最后再通过两个可学习参数做缩放和平移。BatchNorm有个特别重要的细节必须记住它在训练和推理阶段的行为不一样。训练时它用当前batch内的统计量做归一化推理时它使用训练阶段累计的运行均值和方法。这就是为什么很多模型代码里会在训练前写model.train()推理前写model.eval()。如果你推理时忘了切模式用训练模式跑测试结果会非常诡异尤其是batch size1的时候BatchNorm几乎等于把输入直接变成不可预测的东西。BatchNorm放在激活函数前面还是后面业界有不同的说法和实践。经验上在卷积网络中更常见的顺序是Conv - BN - ReLU也就是先归一化再激活但BERT等Transformer结构里用的是LayerNorm位置一般放在残差连接之后。对初学者来说先记住“Conv-BN-ReLU”这个组合绝大多数CNN任务都不太会翻车。如果batch size实在太小比如只有2或4BN的统计量会很不稳定。工程上的替代方案是用GroupNorm、InstanceNorm或者LayerNorm。它们在不同维度上做归一化不依赖batch的统计信息小batch训练时会更稳。4.2 Dropout防过拟合的“随机断连”Dropout的思路特别朴素训练时每次前向传播随机把一部分神经元的输出置为0让网络不能依赖某几个特定神经元迫使它学到更鲁棒的特征。推理时所有神经元都参与计算相当于集成了一堆“瘦身版”网络的结果。代码里nn.Dropout(p)的p表示置零的概率。比如p0.5表示每个神经元有50%的概率被置0。一般全连接层多的网络Dropout ratio可以设大一点0.5左右卷积层后面通常设0.2到0.3就行因为卷积层的参数已经通过权值共享控制了规模过拟合风险相对小。Dropout和BatchNorm能不能一起用可以但顺序有讲究。我的习惯是如果网络里已经大量使用BatchNormDropout就不太需要再加了。因为BN本身带有一定的正则化效果两者叠加有时反而会让训练变得不稳定。只有当数据量很小、过拟合明显时才考虑在全连接层前加一个p0.3左右的Dropout。还有一个坑Dropout同样有训练/推理模式差异千万别忘了model.eval()。4.3 训练不稳定的排查心得训练不稳定的原因五花八门但绝大多数情况下逃不出这几个方面。第一是loss不下降这种时候优先怀疑学习率和数据预处理。学习率太小参数每步移动距离过小loss自然磨磨蹭蹭不往下走数据没有归一化数值范围差异太大梯度方向就会被少数大数值样本带偏。第二是loss变成NaN多半是学习率太大导致梯度爆炸或者是数据里混入了无穷值。把学习率调低一个数量级检查数据清洗流程问题基本能解决。第三是训练loss很低但验证集准确率上不去这就是典型的过拟合。我自己调试模型时有个习惯先固定一个较小的学习率比如1e-3跑20个epoch看趋势不去追求精调。如果loss能正常下降说明网络和数据的整体链路是通的再开始调参。如果20个epoch后loss纹丝不动那多半不是参数问题而是网络结构、数据格式、标签对齐等基础问题。很多新手一上来就调学习率调了几天发现是数据标签对错了这种事我见过太多次了。5. 序列层RNN、LSTM与注意力机制5.1 RNN/LSTM/GRU处理序列数据的经典结构前面讲的主要是处理图像和结构化数据的层。面对时间序列、语音、文本这类带有“先后顺序”的数据就需要循环结构出场了。RNN循环神经网络的核心思想是引入一个隐藏状态h_t让网络在每一个时间步都能“记住”前面看过的信息。基本的计算方式是h_t tanh(W_ih * x_t b_ih W_hh * h_{t-1} b_hh)这个公式读起来有点长但意思很简单当前步的隐藏状态由当前输入x_t和上一步的隐藏状态h_{t-1}共同决定。RNN虽然结构简单但有很严重的固有问题随着序列长度增加梯度在反复相乘的过程中要么爆炸要么消失导致它很难建模长距离依赖。LSTM长短期记忆网络就是为解决RNN长程记忆问题提出的。它引入了细胞状态和三个门控机制遗忘门决定要不要丢弃之前的记忆输入门决定哪些新信息要存入记忆输出门决定当前时刻输出什么。通过门控机制LSTM可以把重要信息在细胞状态里一直传递下去。GRU门控循环单元则是LSTM的简化版把三个门合并成两个参数更少很多任务上效果和LSTM差不多。PyTorch里的标准写法是import torch.nn as nn lstm nn.LSTM( input_size64, # 每个时间步输入的特征维度 hidden_size128, # 隐藏状态维度 num_layers2, # LSTM层数 batch_firstTrue # 输入形状为 [batch, seq_len, feature] )LSTM在时间序列预测、语音人声分离、股票波动率估计等场景里应用很广。如果你需要把序列最后一步的隐藏状态作为整体特征再接入全连接层做分类或回归这也是非常标准的做法。不过要提醒一句LSTM在长序列上的训练速度偏慢而且不容易并行化所以现在很多新的序列模型都转向了注意力机制。5.2 自注意力机制并行与长依赖的解决方案自注意力Self-Attention是当前深度学习里影响力最大的机制之一。它解决了RNN的两个痛点一是无法并行——因为每一步都依赖前一步的结果GPU的并行计算优势发挥不出来二是长距离依赖问题——序列太长时信息要经过多个时间步才能传递很容易丢失。自注意力机制的核心是让序列中任意两个位置直接建立联系不经过中间环节。具体来说每个输入向量会生成三个新向量Query查询、Key键、Value值。注意力权重的计算方式是Attention(Q, K, V) softmax(Q * K^T / sqrt(d_k)) * V用一句话概括通过点积计算“我和序列里其他位置的相关程度”然后按相关程度加权汇总所有Value。除以sqrt(d_k)是为了防止点积结果过大导致softmax进到饱和区。多头注意力就是把Q、K、V切成多组让每一组关注不同位置的关系最后再拼接起来大大增强了模型的表达能力。Transformer结构里最核心的组成部分是输入经过Embedding和位置编码进入多头自注意力层然后接FFN前馈网络每个子层外面都有残差连接和LayerNorm。你在热词里看到的“WSA和跨窗口自注意力”结构来自Swin Transformer是一种在图像上做自注意力的高效方式先把图像分成小窗口在窗口内做自注意力WSA再通过移动窗口让信息跨窗口交流SWA这样既降低了计算量又保留了全局信息的传播能力。理解了自注意力的本质后这类结构其实都很好消化。从“层”的角度来看自注意力层是一种比全连接、卷积更灵活的特征交互机制。它不依赖局部窗口不依赖序列顺序可以让任意两个位置直接交互。这也是为什么BERT、GPT、ViT、Swin这些模型能横扫NLP和视觉领域的重要原因。6. 实操工具箱框架选择、环境搭建与常见问题排查6.1 框架选型PyTorch、TensorFlow、Halcon怎么选聊完了层肯定绕不开一个问题用什么框架来实现这些层。现在的主流选择是PyTorch因为它的动态图和Python风格API让调试非常友好学术界几乎成了默认标准《动手学深度学习》最新版也是基于PyTorch的。TensorFlow/Keras在企业生产部署、移动端支持和TensorFlow Serving等场景依然很有市场如果你所在团队的基础设施偏Google生态选TF是合理的。还有些场景比较特殊。比如做工业视觉的人会接触到Halcon这种商业机器视觉工具它的深度学习工具也提供了分类、目标检测、分割等预训练模型和可视化训练界面适合快速验证和工程落地。你搜到的“深度学习matlab”也不是没有道理MATLAB的深度学习工具箱对做信号处理、控制、传统算法的工程师非常友好训练网络时可以不写太多代码靠深度的App界面就能搭出来。框架上手难度典型场景备注PyTorch低学术研究、CV/NLP项目、快速原型动态图调试方便社区资源最丰富TensorFlow/Keras中大规模生产部署、移动端推理生态完善部署工具链成熟MATLAB工具箱低算法验证、信号处理、控制类任务无需深度编程基础适合快速验证Halcon中工业视觉检测、定位、识别偏工程落地训练推理闭环成熟另外提一下“深度强化学习”和“图强化学习”方向。这类任务里常用的层和前面讲的有很大交集但会额外引入策略网络、价值网络、GNN里的图卷积层、图注意力层等。建议先把基础层掌握扎实再往这些方向延伸。6.2 环境与GPU自己搭还是租服务器深度学习训练跑得慢绝大多数瓶颈不是代码写得差而是没有GPU。本地环境配置的基本流程是装好Anaconda创建虚拟环境装适配自己显卡的CUDA和cuDNN再用pip或conda安装PyTorch版本。环境配置这一步最容易出问题的就是CUDA版本、显卡驱动和PyTorch版本的匹配。我的建议是先确认显卡驱动版本再反推CUDA版本不要随便装最新的。如果要跑大规模数据集或者用Swin Transformer这类大模型本地显卡往往扛不住。这时候可以选择云平台或显卡租用服务本质上是按小时租GPU实例跑完就关机成本可控。现在很多云平台会直接提供PyTorch镜像省去了配环境的痛苦。值得留意的是现在国产GPU也在陆续做深度学习的适配比如摩尔线程S80这类产品如果你用的深度学习框架版本比较新可能会遇到算子兼容性问题下单前先查一下官方适配表。边缘端部署是另一个方向。ESP32这类MCU级芯片通常跑不动常规CNN只能通过模型量化、剪枝、蒸馏把模型压缩到几百KB甚至几十KB用TinyML的方式在端侧做推理。更常见的做法是“端云协同”采集端负责数据采集和简单预处理把数据传到服务器上的深度学习模型做推理再把结果返回端侧。想做人声抑制、茶叶嫩芽识别、光谱分析这类应用前期建议都在服务器端验证模型别一上来就指望在端侧跑通。6.3 实战问题排查速查表最后我把一些高频问题整理成速查表基本都是我这些年实操中反复遇到的症状可能原因排查/解决思路训练loss是NaN学习率过大、梯度爆炸、数据含NaN降低学习率检查数据清洗加梯度裁剪loss不下降学习率太小、数据未归一化、标签错误调大学习率检查输入数据范围断点检查标签训练loss低、验证loss高过拟合加数据增强、加Dropout、减小模型、提前停止验证集准确率忽高忽低batch size 太小导致BN不稳定增大batch、用GroupNorm替代BN显存溢出OOM模型太大、batch过大减小batch、混精度训练、梯度累积、换小模型训练和推理结果差很多忘记切train/eval模式训练用model.train()推理用model.eval()反向传播后梯度为0ReLU死神经元换LeakyReLU、检查初始化方式维度报错shape不匹配打印每层输出shape用view/permute调整这里面最容易被新手忽略的就是train/eval模式切换。很多人训练时准确率很好看一到测试或者部署就翻车第一反应是数据不对、模型有问题查了半天结果是忘了调用model.eval()BatchNorm和Dropout的行为把推理结果搅乱了。这个坑我踩过不止一次建议你把它刻在脑子里。还有一个心得很重要不要等整个模型跑完才调试。先拿一个batch的数据过一遍模型看loss是否能正常下降。这一步能同时验证数据读取、标签对齐、网络结构、损失函数有没有问题。如果连单个batch都loss不降别急着调学习率回去查数据管线和代码逻辑。我个人在实际操作中最深的感受是懂得每个层的原理比会调参重要得多。第一次跑CNN的时候我也是被各种shape变换绕得晕头转向后来把手推全连接和卷积层的输出尺寸练熟再看任何网络结构图都轻松很多。入门资源方面《动手学深度学习》适合当工具书一边做一边查鱼书《深度学习入门》对数学直觉的建立很有帮助配合吴恩达的课程把基础概念过一遍然后立刻动手复现一个LeNet或者ResNet。常用的这些层吃透了后面接触Transformer、图神经网络、深度强化学习都会顺很多。如果你正好在准备面试建议把每个层的参数量计算公式和shape变化手推一遍很多“深度学习八股”题其实就变成了送分题。
返回列表