1. 比较CNN和多层感知机MLP
- MLP由全连接层构成,每个神经元都和上一层中的所有节点连接,存在参数冗余;相比之下,CNN由于权重共享,参数更少,方便网络的训练与设计深层网络;
- MLP只接受向量输入,会丢失像素间的空间信息;CNN接受矩阵和向量输入,能利用像素间的空间关系
- MLP是CNN的一个特例,当CNN卷积核大小与输入大小相同时其计算过程等价于MLP
2. MMCV中Hook机制简介及创建一个新的Hook
- Runner是一个模型训练的工厂,HOOK可以理解为一种触发器,也可以理解为一种训练框架的架构规范,它规定了在算法训练过程中的种种操作,并且我们可以通过继承HOOK类,然后注册HOOK自定义我们想要的操作。
- MMCV在./mmcv/runner/hooks/hook.py中定义了Hook的基类以及Hook的注册器HOOKS。作为基类,Hook本身没有实现具体的函数,只是提供了before_run、after_run等6个接口函数,其他所有的Hooks都通过继承Hook类并重写相应的函数完整指定功能。
- Hook 的主要目的是扩展功能,而不是修改已经实现的功能。如果我们实现一个定制化的 Hook,使用时需要定义、注册、调用3个步骤。自定义Hook在./mmcv/runner/hooks目录下构建,在执行runner.run()前会调用BaseRunner类中的register_training_hooks方法进行注册,使用build_from_cfg进行实例获取,然后调用BaseRunner类的register_hook()进行注册,这样所有Hook实例就都被纳入到runner中的一个list中。在runner执行过程中,会在特定的程序位点通过call_hook()函数调用相应的Hook。
import torch
from mmcv.runner.hooks import HOOKS, Hook
@HOOKS.register_module()
class CheckInvalidLossHook(Hook):
def __init__(self, interval=50):
self.interval = interval
def after_train_iter(self, runner):
if self.every_n_iters(runner, self.interval):
assert torch.isfinite(runner.outputs['loss']), \
runner.logger.info('loss become infinite or NaN!')
def register_checkpoint_hook(self, checkpoint_config):
hook = mmcv.build_from_cfg(checkpoint_config, HOOKS)
self.register_hook(hook, priority='NORMAL')
3. 深度学习训练中如何区分错误样本和难例样本
- 一种方式是通过损失处理,论文标题:Unsupervised Label Noise Modeling and Loss Correction,可以使用一个Beta分布来刻画正常样本和噪音样本,从而将二者区分。
4. PyTorch 节省显存的常用策略
- 混合精度训练
- 大 batch 训练或者称为梯度累加:具体实现是在 loss = loss / cumulative_iters
- gradient checkpointing 梯度检查点
5. 深度学习模型训练时的Warmup预热学习率作用
Warmup是在ResNet论文中提到的一种学习率预热的方法,它在训练开始的时候先选择使用一个较小的学习率,训练了一些epoches或者steps(比如4个epoches,10000steps),再修改为预先设置的学习来进行训练。
由于刚开始训练时,模型的权重(weights)是随机初始化的,此时若选择一个较大的学习率,可能带来模型的不稳定(振荡),选择Warmup预热学习率的方式,可以使得开始训练的几个epoches或者一些steps内学习率较小,在预热的小学习率下,模型可以慢慢趋于稳定,等模型相对稳定后再选择预先设置的学习率进行训练,使得模型收敛速度变得更快,模型效果更佳。
6. PyTorch中的 ModuleList 和 Sequential的区别和使用场景
7. 考虑一个过滤器[-1 -1 -1; 0 0 0; 1 1 1] 用于卷积。该滤波器将从输入图像中提取哪些边缘?
该过滤器将从图像中提取水平边缘。为了获得更具体的理解,请考虑由具有以下像素强度的数组表示的灰度图像:
[0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
10 10 10 10 10 10;
10 10 10 10 10 10;]
从阵列中可以明显看出,图像的上半部分是黑色的,而下半部分是较浅的颜色,在图像中心形成明显的边缘。
两者的卷积将得到数组 [0 0 0 0; 30 30 30 30;30 30 30 30;0 0 0 0;]。从结果数组中的值可以看出,水平边缘已被识别。
8. 深度学习中为什么不对 bias 偏置进行正则化?
因为它对输入参数不敏感 公式上看就是它对所有的输入一视同仁,不贡献模型的曲率,求导的时候 bias 没多大作用
9. 深度学习模型中如何融入传统图像处理的特征?直接拼接融合有什么问题?
特征融合的一大难点在于不同的特征来自不同domain,直接物理拼接可能没有意义。比如常见的前融合或者后融合,以后融合举例,在卷积层铺平后的向量与传统视觉特征向量拼接,然后再接到全连接网络,可能效果不理想。
一种思路是采用discrimination correlation analysis方法进行融合,具体的:利用训练好的网络,从训练图像中提取特征向量;同时利用sift或者其他特征提取方式从训练图像中提取特征向量。然后对两组向量做dca分析,采用向量拼接的方式连接两组向量,训练分类器。
10. 多任务学习中各个任务损失的权重应该如何设计呢?
11. 为什么Adam常常打不过SGD?症结点与改善方案?
Adam拥有收敛速度快、调参容易的优点,却也存在时常被人攻击的泛化性与收敛问题。讨论模型泛化能力时,我们会希望模型找到的minimum是一个比较平缓 (flat) 、而非陡峭 (sharp) 的位置。不过相当多的论文指出或讨论了Adam在testing时error较大的事实。
12. 如何处理不平衡的数据集?
有多种方法可以处理不平衡的数据集,例如使用不同的算法、对类别进行加权或对少数类别进行过采样。
算法选择:某些算法比其他算法更适合处理不平衡数据。例如,决策树和随机森林往往在不平衡数据上表现良好,而逻辑回归或支持向量机等算法可能会很困难。
类权重:通过为少数类分配更高的权重,可以使算法在训练过程中更加重视它。这有助于防止算法总是预测多数类。
过采样:您可以通过随机复制现有样本或基于现有样本生成新样本来创建少数类的合成样本。这可以平衡类别分布并帮助算法更多地了解少数类别。
13. Pytorch代码中如何尽量避免.to(device)的操作?
- 其中一种情况是初始化一个全0或全1的张量,比如模型的输出已经在cuda上了,你需要另外的tensor也是在cuda上,这时,你可以使用*_like操作符.
14. Pytorch中nn.Identity()/torch.chunk/torch.masked_select/torch.gather操作的应用场景?
# 1:1的映射替换一些层
model = resnet50(pretrained=True)
model.fc = nn.Identity()
# 将输出分成N块
o1, o2, o3 = torch.chunk(one_layer(batch), 3, dim=1)
# 计算损失只在满足某些条件的张量上
data = torch.rand((3, 3)).requires_grad_()
mask = data > data.mean()
torch.masked_select(data, mask)
tensor([[0.0582, 0.7170, 0.7713],
[0.9458, 0.2597, 0.6711],
[0.2828, 0.2232, 0.1981]], requires_grad=True)
15. 如何将大模型有效地切割成若干个子模型?如何将切割后的子模型分配到多个节点上进行并行训练?
- 目前有很多的算法可以进行大型模型的切割。其中比较常用的方法包括"随机洗择切割点”、"图切割算法”和”局部洗择最优算法”等。这些算法的目的都是将大模型切割成尽可能平衡的若干个子模型,同时确保每个子模型都包含至少一部分的输入数据和特征,以确保每个子模型都能够顺利地进行训练。
- 目前已经有很多的分布式训练框架可以很好地支持大模型分布式训练。其中比较常用的分布式训练框架包括基于MPI的Horoygd、基于TensorFlow的TF.distribute、基于Pylorch的DDP和基于MXNet的Neuron等,这些框架够对切割后的子模型进行自动化地分配和管理,同时支持多节点之间的数据传输和通信,使得多节点分布式训练成为可能。
16. Pytorch训练时经常会合并多个数据集,ConcatDataset具体做了什么?
ConcatDataset继承自Dataset类, 构造函数要求一个列表L作为输入,其包含若干个数据集的, 重写了__len__方法和__getitem__方法。
https://zhuanlan.zhihu.com/p/222772996
17. Pytorch Lighting的设计哲学,及你觉得好用的点
Pytorch-lightning 的核心设计哲学是将 深度学习项目中的 研究代码(定义模型) 和 工程代码 (训练模型) 相互分离。深度学习项目代码可以分成如下4部分:
- 研究代码 (Research code),用户继承LightningModule实现。
- 工程代码 (Engineering code),用户无需关注通过调用Trainer实现。
- 非必要代码 (Non-essential research code,logging, etc…),用户通过调用Callbacks实现。
- 数据 (Data),用户通过torch.utils.data.DataLoader实现,也可以封装成pl.LightningDataModule。