TPLINK图像算法二面

1022 tplink 算法二面 面试题

  1. 自我介绍
  2. 多标签分类,标签缺失、类别不均衡
  3. python 中 is 与 == 的区别
  4. resnet 及其后续工作
  5. 详细询问CUB200项目,方法等等,数据增强
  6. 梯度消失与梯度爆炸
  7. 增大感受野的方法,空洞卷积、增大核面积
  8. diffusion model 项目的原理与工作
  9. 复杂场景下的行人识别???
  10. fixmatch 标签?
  11. 有没有关注最新的工作进展?
  12. Git 如何解决冲突,还需要 commit吗?

重写答案

多标签分类的类别缺失问题

首先说明,多标签分类中,类别标签缺失叫做 缺失标签学习(MLML),标注的部分标签正确,但是存在不相关的标签,称为部分标签学习(PML),对于PML,所有标签都应该包含在候选标签集中。

这个问题我不是很清楚,我的回答侧重于采用半监督学习类似的方法,或者划分集合将任务分解为多个二元分类问题后进行集成学习。

chatGPT回答:

多标签分类问题中,标签缺失通常指某些标签的标注不完整或缺失,导致模型无法获得完整的训练信息。应对这一问题的方法包括:

  • 使用部分标注学习(Partial Label Learning):部分标注学习方法能够处理只有部分标签信息的情况,通过估计未标注标签的可能性,或通过假设缺失标签的分布与已标注标签一致来进行训练。
  • 多任务学习(Multi-Task Learning):将标签预测任务视为多个相关任务,利用各个任务之间的相关性来填补标签缺失的数据。
  • 标签传播算法(Label Propagation):通过图结构将已知的标签信息传播到缺失标签的实例上,基于相似性将标签分配给未标注的数据。
  • 生成模型(Generative Models):利用生成模型(如变分自编码器、生成对抗网络)生成缺失标签,模型通过学习数据的分布生成合理的标签。

类别不均衡问题

在多标签分类中,类别不均衡指某些标签的样本数量远多于其他标签,这会导致模型偏向于预测常见标签。常见的解决方法包括:

  • 重采样(Resampling)
    • 上采样少数类:通过复制少数类样本或合成新样本(如SMOTE)来平衡类之间的样本数量。
    • 下采样多数类:减少多数类的样本数量,使其与少数类相匹配,但下采样可能丢失部分有用信息。
  • 代价敏感学习(Cost-Sensitive Learning):通过为不同类别分配不同的误分类代价,模型可以更加关注少数类。例如,对少数类分配较高的损失权重,迫使模型更好地学习这些类别。
  • 数据增强(Data Augmentation):通过数据增强技术(如旋转、翻转、裁剪等)生成更多少数类的样本,以增加其多样性。
  • 类平衡损失函数(Class-Balanced Loss Function):使用专门设计的损失函数,例如Focal Loss或加权交叉熵损失函数,对少数类和多数类样本的贡献进行重新加权,使模型在训练时不会过度偏向多数类。

Python 中 is 与 == 的区别

因为我给面试官说,我对语言特性不是非常的精通,所以说问一个简单的问题,这个面试题反映出来面试准备中还是需要重视语言部分。

is 运算符:

  • 作用is 用于比较两个对象的身份,即它们在内存中的引用地址是否相同。换句话说,is 判断的是两个变量是否指向同一个对象。
  • 使用场景is 通常用于检查两个对象是否是同一个实例,或者用于与 None 进行比较。

== 运算符:

  • 作用== 用于比较两个对象的,即它们的内容是否相同,而不关心它们是否是同一个对象。
  • 使用场景== 常用于比较两个变量的内容是否相等,不论它们是否是同一个对象。

简而言之,is 比较对象在内存中的地址是否相同,==检查两个对象的内容是否相等。

1
2
3
4
5
6
7
8
a = [1, 2, 3]
b = a
c = [1, 2, 3]

print(a is b) # True, 因为 a 和 b 引用的是同一个列表对象
print(a is c) # False, 因为 a 和 c 是不同的列表对象,虽然它们内容相同
print(a == b) # True, 因为 a 和 b 的内容相同
print(a == c) # True, 因为 a 和 c 的内容相同

chat:在一些情况下,特别是比较不可变对象(如整数、小字符串等)时,由于 Python 的内部优化,可能会出现 is== 都为 True 的情况(这种情况很难讲),例如:

1
2
3
4
5
6
7
8
9
a = 1000
b = 1000
print(a is b) # False, 因为它们是不同的对象,但是注意,这里我实际上在 python 3.8 中进行测试,结果是 True
print(a == b) # True, 因为它们的值相同

x = 100
y = 100
print(x is y) # True, 因为小整数在 Python 中被缓存,指向相同对象
print(x == y) # True, 因为它们的值相同

ResNet 及其后续工作

ResNet的主要贡献包括:

  1. 残差学习:通过引入残差连接,使得网络可以学习输入到输出的残差映射,而不是直接学习映射本身,这有效缓解了梯度消失问题。
  2. 批量归一化:ResNet还采用了批量归一化(Batch Normalization)技术,进一步提高了模型的训练稳定性和性能。
  3. 全局平均池化:ResNet使用全局平均池化层替代了传统的全连接层,减少了模型参数并提高了泛化能力。

ResNeXtResNeXt 是 ResNet 的扩展版本,提出了一种叫做“分组卷积”(Grouped Convolution)的设计。它通过引入多个并行的卷积路径(即“分支”)来提升模型的表达能力,同时保持参数量的可控性。ResNeXt 提供了更好的模块化设计,使得可以通过简单增加分支数来提高模型的性能。

Wide ResNetWide ResNet 提出,通过增加网络的宽度(即每层通道数)而非深度,可以减少网络的训练时间,同时保持甚至提升精度。与非常深的网络相比,宽网络在计算效率和收敛速度上具有一定优势。

DenseNetDenseNet 是受 ResNet 启发提出的另一种网络结构,它通过在每一层中连接所有前一层的特征图,使得网络的梯度传递更加顺畅,进一步缓解了梯度消失问题。与 ResNet 的残差连接不同,DenseNet 采用的是密集连接(Dense Connection),每一层都接收所有前面层的输入。

Res2NetRes2Net 是对 ResNet 进一步扩展的版本,它通过将每个残差块内部进行分组,并使不同组之间的特征有级联连接,实现了更细粒度的特征表示,提升了网络的表达能力。

SENetSENet (Squeeze-and-Excitation Network)通过引入通道注意力机制,提升了 ResNet 的表示能力。SENet 在每个残差块中增加了“压缩”和“激励”操作,使得网络能够自适应地重新调整每个通道的重要性。

梯度消失与梯度爆炸

  1. 梯度消失:(Vanishing Gradient):
  • 定义:梯度消失是指在反向传播过程中,随着网络层数的增加,梯度逐渐变得非常小,接近于零,导致前面层的权重更新几乎停滞不前,模型难以有效训练。这在深层神经网络中特别常见,尤其是在使用饱和激活函数(如 sigmoid、tanh)时,梯度的值会随着层数的增加迅速衰减。
  • 影响:网络的前面层权重更新变得非常缓慢,网络难以收敛,甚至可能无法训练到有效的参数。
  • 解决方法
    • 使用 ReLU 激活函数
      • ReLU(Rectified Linear Unit)激活函数避免了 Sigmoid 或 Tanh 的饱和区域,它的导数要么为 1(正区域),要么为 0(负区域),可以在一定程度上减轻梯度消失问题。
      • 其他 ReLU 的变体如 Leaky ReLU、ELU 也可以用于缓解梯度消失问题
    • 残差网络(ResNet):ResNet 通过引入跳跃连接(skip connections),将输入直接传递到后续层,从而有效缓解了梯度消失问题。这使得深层网络的梯度可以更加顺畅地传递。
    • LSTM 和 GRU(解决 RNN 中的梯度消失):长短时记忆网络(LSTM)和门控循环单元(GRU)在结构设计上,通过引入门机制控制信息流,能够有效减轻循环神经网络(RNN)中的梯度消失问题
    • 批归一化(Batch Normalization):在每一层后添加批归一化层,可以将输入数据归一化,使得数据在训练过程中保持稳定的分布,从而有助于避免梯度的急剧消失。
    • 权重初始化方法:使用合适的权重初始化方法(如 Xavier 初始化或 He 初始化),能够让初始的激活函数值保持适当的范围,从而避免梯度过小或过大,帮助梯度更好地传递。
  1. 梯度爆炸 Exploding Gradient:
  • 定义:梯度爆炸是指在反向传播过程中,随着网络层数的增加,梯度变得非常大,导致前面层的权重更新幅度过大,模型参数不稳定,最终导致梯度无法收敛或参数溢出。在深层网络或循环神经网络(RNN)中,梯度爆炸问题尤其严重,因为梯度在长时间步内累积,容易产生数值溢出。模型训练时权重更新非常不稳定,损失值波动过大,难以收敛。
  • 解决方法
    • 梯度裁剪(Gradient Clipping):梯度裁剪是处理梯度爆炸的一种常见方法。通过设置梯度的最大值,当梯度的范数超过设定的阈值时,将梯度进行裁剪,防止其变得过大。例如,在 RNN 中经常使用梯度裁剪来避免梯度爆炸。
    • 权重初始化方法:适当的权重初始化也可以减轻梯度爆炸问题。通过 Xavier 或 He 初始化,可以确保权重值不会导致过大的激活函数输出,从而避免梯度过大。
    • 使用正则化技术L2 正则化(权重衰减)通过在损失函数中添加权重的平方和项,能够有效限制权重值的增长,防止梯度爆炸问题的发生。
    • 使用较小的学习率:调整学习率可以有效控制权重更新的幅度,使用较小的学习率可以减轻梯度爆炸问题,使模型训练更加稳定。
    • 批归一化(Batch Normalization):批归一化除了可以缓解梯度消失问题,也能帮助稳定梯度传递,避免梯度爆炸。它通过将激活值归一化,避免激活值的分布过度偏离,进而保持梯度的稳定性。
    • 更改激活函数可以缓解,但是不能从根本上解决。

增大感受野的方式

  1. 使用空洞卷积(不增加计算量,一般在语义分割里面用的比较多,能在保持高分辨率的同时捕获更加广泛的上下文信息·`)
  2. 增加网络深度(会让参数量增多)
  3. 使用较大的卷积核(但是会增大参数量与计算量)
  4. 调整步长(卷积或者池化层)
  5. 空间金字塔池化(SPP):在不同尺度对特征图进行池化操作。
  6. 小波变换的新型卷积方式(WTConv),级联小波变换和在不同频率带上执行小卷积核的卷积增加感受野。
  7. 下采样降低分辨率。

DiffuPPS 的工作原理

这个暂时不能说,论文还没发出来。

复杂场景下的行人重识别

这个也还暂时不能说。

有没有关注最新的工作进展?

最近一段时间我主要集中精力在撰写一篇与NLP相关的论文,因此没有太多时间专门关注图像算法领域的最新工作。不过,我一直对该领域保持高度兴趣,之前我有深入研究过[提到一些你熟悉的图像算法领域的工作或模型]。我非常愿意在接下来的时间里迅速跟进最新的研究进展,以确保自己的知识保持前沿。

FixMatch及其相关工作

这个可以参考我另外外一篇有关于半监督分类的博客。

Git 是如何解决冲突的,还需要 commit 吗?

Git 冲突的本质:(个人认为)远程库包含了本地库中没有的内容,或者说,本地库的修改基础不是远程库的版本。

发生冲突后:

  1. 拉取远程仓库内容: git pullgit pull 等价于 git fetch + git merge
  2. 提示存在冲突,进入 MERGING状态
  3. 通过 git status 查看需要修改的文件名
  4. 也可以使用 git diff 查看已经修改的文件的差异
  5. 在文件中进行冲突修改
  6. 待文件修改完成之后,再次执行提交动作,需要包含 add commit 两个动作
  7. 提交后使用 git-log 查看本地库的记录,一般能够看到一个双分支合并在一起
  8. 本地提交完成后即可推送远程代码 git push

没明白这个面试官反问我“解决冲突之后难道还需要再次comit吗?不会产生一个新的提交记录吗”是什么意思。

貌似还有一种解决冲突的办法:

  1. 本地修改代码后按步骤提交
  2. 推送远程代码失败,需拉取远程库代码
  3. 使用拉取命令“git pull --rebase origin master”
  4. 找到冲突代码人工修改
  5. 重新执行提交动作, (1)git add .
    (2)git commit -m “xxx”
    (3)git rebase --continue (4)git push origin master

这种rebase方法似乎时不能用在有多个分支的主分支上面的。

一般来讲,解决冲突比较好的办法:个人认为:

  1. 多分支开发,大家使用PR合并
  2. 提交之前先进行 git pull,杜绝强行覆盖远程仓库
  3. 抢先提交(狗头

一般来说,我比较赞同第一种,有一个bug修改或者一个功能开发,应该新建分支,而不是在原有分支上直接进行改动,这样也有利于进行测试和规范化。

预防冲突的办法: 1. 频繁拉取 2. 小步提交 3. 良好的沟通,了解彼此的工作进展

复习一些常见的Git指令,见另外一个博客。