自我介绍
面试官好 我叫黄伟琛 本科毕业于厦门大学经济学院 统计系 现在在人民大学信息学院读计算机的硕士 24年毕业 研究方向是计算机视觉和深度学习 接触过比较多种类型的深度学习项目 比如 语义分割 医疗图像分割 命名实体识别 文本分类 知识图谱实体预测和零样本图像分类 能使用 python c++等语言编程 熟悉 pytorch sklearn等工具 独立实现了一个基于pytorch的支持单机多卡的图像分割套件 熟悉linux环境 会简单的shell脚本编程 具备较强的动手实践能力 能够快速用程序把想法实现 具备良好的团队合作精神 善于沟通
论文介绍
医疗图像分割指引这个文 原本是想做一个综述的 比较了不同的数据增强方法、不同的模型和图像上不同的注意力模块在医疗图像分割上的作用 做了对比实验和消融实验 然后在实验的几个数据集上找出了一个比较好的策略组合 但是实验就只涉及两个数据集 不能说明这个组合的泛用性 然后就是把CapsNet Attn UNet进行组合 搞了一个模型 效果一般(Capsnet:一个capsule是一个向量 用向量模的大小衡量某个实体出现的概率 模值越大 概率越大 胶囊之间的传递用的是一种动态路由的方法 实现了可反向传播 )
关于零样本学习的这个文是要做一个新问题 就是零样本学习他本身定义是模仿人类通过语义描述或者说属性的描述 来学习新类别的一个过程 但是在学习者联网的状态下 对未见类除了理解它的语义描述 也应该对这些类别进行网络检索 获取有效的数据 这样比较符合人类学习的过程 那我作为一台机器通过网络检索 拿到了一些图片 然后通过离群检测 发现斑马和狮子有蛮多和其他的动物分布比较符合的图片 闪电鸟没有有效图片或者只有一两张有效图片 这里的闪电鸟是胡诌的 就是代表一个检索不到有效数据的类 那这个任务里的未见类其实是发生了变化的 可以通过网络检索出的数据扩充现有数据集 这个才比较符合人类学习新类别的这个过程 但是我们必须还得用零样本学习的模型和方法 因为在扩充网络数据以后 依然可能有闪电鸟这样的未见类 大概就是这样一个问题 工作主要是要做这个问题的数据集 还有就是做一个baseline跑一下实验 目前这边 数据集做完了 做的baseline是生成式的模型 实验也基本跑完了
零样本
训练过程
- 提取visual特征 visual特征->语义特征 D(G(语义特征+z)) 对抗训练
- 用 训练集+假未见类 训练分类器
augmentation
Mixup 将随机的两张样本按比例混合,分割的结果按比例混合
Cutout 随机的将样本中的部分区域cut掉,并且填充0像素值,分割的结果去掉目标区域
CutMix 就是将一部分区域cut掉但不填充0像素而是随机填充训练集中的其他数据的区域像素值
极坐标变换 代码有点问题
高斯滤波 cv2.GaussianBlur() 滤波过程就像卷积 只是权重是固定的
双边滤波 用于平滑图像 同时保留边缘 原理是在像素值的差值较大的区域 对应值域权重接近于0 可以保持边缘梯度
attention in cv
channel attention 如squeeze and excitation 对feature的各个channel的二维张量进行一个全局平均池化 然后通过线性映射和sigmoid 得到一个各个channel的权重 更多地关注信息丰富的特征 抑制信息少的特征
spatial attention 在channel的维度上使用最大池化或平均池化得到一个channel数量为1的二维张量 然后在对这个矩阵进行大核的卷积和归一化 就得到空间注意力矩阵
self attention 如DANet 让特征和自己的reshape进行矩阵乘积和softmax 来关注每个position之间的注意力
医疗图像分割的模型
DC-UNet 采用多个通路的3个3x3卷积层代替ResUNet残差连接
UACANet 显著图 抠出 前景和背景 然后对前景和背景用进行self attention模块进行处理
ResUNet++ 有残差连接 基于ResUNet 加入channel attention和spatial attention 和ASPP(Atrous Spatial Pyramid Poolingb)
小样本学习
因为医疗图像的小样本分割 很难找到相似的场景 或者说匹配的先验 比如我做的两个任务一个是眼底图血管的分割 一个是超声图血管瘤的分割 迁移学习基本就不管用 所以当时只尝试了半监督的方式和数据增强的方式
self-training 把测试集当成无标签的数据 策略是把置信度大于阈值点做一个平均 然后排序 把平均置信度最高的几个pred作为标签 加入训练集中
数据增强 mixup cutout cutmix
为什么用UNet做医疗
首先是病灶或者说分割的目标类边界模糊 需要融合不同层次的特征 然后就是说输入比较规范 特征的语义信息比较简单 所以低级的特征融合进来对分割也很有帮助 还有一点是因为医疗图像的样本量不大 也就是说如果用大模型
模型能力相对来说就太强 容易过拟合
NER
输入和输出 词向量(token embeddings)、段向量(segment embeddings)、位置向量(position embeddings)
vectorized用的是sklearn的TextVectorization 最后BERT的输出seq接一个crf
Bi-LSTM+CRF 将向量序列输入两个双向的LSTM单元 将正向反向输出拼接 CRF(条件随机场)可以学习到句子的约束条件 可以加入一些约束来保证最终预测结果是有效的
MacBERT 用相似的单词(大部分)和随机的单词进行mask
RoBERTa-chinese 相对于BERT的静态 mask,换成动态mask 即每次数据被 feed 进模型时,重新做一遍随机 mask 相当于扩大了训练数据的量级
self attention 将query和每个key进行相似度计算得到权重(点积/sqrt(d))用softmax函数对这些权重进行归一化 最后将权重和相应的键值value进行加权求和得到最后的attention
实体预测
transE embedding模型 embedding后从实体矩阵和关系矩阵中各自抽取一个向量 进行L1或者L2运算 得到的结果近似于实体矩阵中的另一个实体的向量(L1是模型各个参数的绝对值之和 L2是模型各个参数的平方和的开方值)
项目介绍
研一上学期老师给我制定的任务是分割 开学前那会在学深度学习 为了方便工作还有就是对巩固一下学习的知识 就写了一个基于pytorch的分割套件 就是针对自定义的数据集 可以选用套件里的优化器 lr-scheduler 损失函数 数据增强方式 模型 进行训练和测试 然后训练 验证的时候 可以调用套件里的评估指标 然后因为学校那边给的计算资源是单机多卡 所以套件也用了ddp模块 除了这些以外套件里还有一些工具 比如ema 比如像grad-cam这种可视化的工具 大概是这样一个东西
ddp
dp用的parameter server的结构 loss会reduce到server统一更新梯度 类似于client server结构 效率不高 server显存分配更多 容易oom 仅单机多卡
ddp用的all reduce比较像p2p模型 梯度更新用的一种环状更新的方法 不需要server 显存平均分配 效率高 支持多机
设置local_rank 本地进程序号
init the DDP backend (GLOO)
torch.distributed.barrier() 对不同卡上的进程进行同步
dataloader里要用DistributedSampler作为sampler
要用SyncBatchNorm和ddp包装模型 (torch.nn.parallel.DistributedDataParallel as DDP)
torch.distributed.reduce和broadcast进行进程通讯 reduce 里有op 例如sum就是把不同进程上的tensor求和放到目的进程
评估指标
准确率(accuracy) = 预测对的/所有 = (TP+TN)/(TP+FN+FP+TN)
查准率(precision) = 真阳性/预测为阳性 = TP/(TP+FP)
召回率(recall) = 真阳性/gt为阳性 = TP/(TP+FN)
f1-score = 2*P*R / (P+R)
IoU intersection over union
Acc在样本不均衡的时候不能很好的作为衡量指标 比如在样本集中 正样本有90个 负样本有10个 只需要将全部样本预测为正样本 就能得到90%的准确率
P是查准 R是查全 此消彼长 所以用加权平均来衡量 这个就是F1
语义分割模型
PSPNet backbone是ResNet 有个SPP模块 把feature池化到不同的大小 然后用1x1conv融合不同channel的信息 最后再把不同大小的feature进行上采样然后拼接 就有了不同的感受野信息
deeplabv3 类似ASPP模块 用不同dilation rate的空洞卷积进行特征提取 然后进行上采样拼接 然后用1x1conv去融合不同channel的信息 然后decode的过程像UNet的一样 在上采样完以后和低级特征拼接在一起 就是他可以获取不同感受野 不同层级的信息
lr_scheduler
逐步衰减
余弦退火 T_max代表1/2个cos周期所对应的epoch值 学习率下降到最小值时的epoch数 即当epoch=T_max时 学习率下降到余弦函数最小值 当epoch>T_max时,学习率将增大
遇到平台期衰减 ReduceLROnPlateau
自定义 LambdaLR 自己实现的平台期退火
loss
weighted_loss 对正样本和负样本赋予不同的权重
focal_loss 将像素分为难学习和容易学习这两种样本
dice_loss 2*pred交gt/(pred正样本数量+gt正样本数量) 也在一定程度上解决正负样本不均
focalloss diceloss 两者区别 focalloss 注重样本数量上的不均 dice注重的是面积上的不均衡衡的问题
grad-cam
有点忘了 具体不太清楚 只知道是对每个目标类的预测值进行backforward 求出特征层的每个通道的每个像素的梯度u
过拟合和欠拟合
欠拟合 模型能力不足过于线性 不能很好地拟合样本的分布 和样本和总体的偏差很大
解决方法 增加模型深度 增加激活层 减少正则 增加特征
过拟合 模型能力强但样本量不足 在训练集上表现很好 但测试集上表现很差
解决方法 early stopping drop out augmentation regularazation 交叉验证 减少输入特征 batchnorm
正则化
L1 在loss里对weight的绝对值之和进行惩罚
L2 在loss里对weight的欧几里得范数进行惩罚
更新梯度的时候 L1相当于对weight的绝对值做了一个减法 可以把部分weight直接降到0 L2相当于对weight进行decay不会降到零 L1可能会影响模型参数优化的效率
BN
BN取的是不同样本的同一个特征 而LN取的是同一个样本的不同特征
在BN和LN都能使用的场景中 BN的效果一般优于LN 原因是基于不同数据 同一特征得到的归一化特征更不容易损失信息 但是有些场景是不能使用BN的 例如batchsize较小
- BN使得网络中每层输入数据的分布相对稳定,加速模型学习速度
- BN的引入极大的降低了sigmoid和tanh这样的激活函数梯度消失的风险
- 使用了Batch Normalization 初始化参数对神经网络的影响减小
- BN具有一定的正则化效果。
一般加在激活函数之前 测试的时候用的是测试集的均值和方差 running_mean running_var
linux
conda screen
一行查找包含字符串的文件 grep -rn "hello world" * (find也可以)
* : 表示当前目录所有文件,也可以是某个文件名
-r 是递归查找
-n 是显示行号
-R 查找所有文件包含子目录
-i 忽略大小写
shell脚本 传参 变量定义 反引号的使用 流程控制(for in do done/ if then fi) 输入输出流
推荐算法
协同过滤 有基于用户的和基于物品的两种 基于用户的是说给用户推荐与他爱好相似的用户群的喜好 基于物品的是说推荐与喜欢的物品相似的物品
系统结构
- 推荐池:一般会基于一些规则,从整体物料库(可能会有几十亿甚至百亿规模)中选择一些item进入推荐池,再通过汰换规则定期进行更新。
- 召回:从推荐池中选取几千上万的item,送给后续的排序模块。由于召回面对的候选集十分大,且一般需要在线输出,故召回模块必须轻量快速低延迟。
- 粗排:获取召回模块结果,从中选择上千item送给精排模块。粗排可以理解为精排前的一轮过滤机制,减轻精排模块的压力。粗排介于召回和精排之间,要同时兼顾精准性和低延迟。一般模型也不能过于复杂。
- 精排:获取粗排模块的结果,对候选集进行打分和排序。精排需要在最大时延允许的情况下,保证打分的精准性,是整个系统中至关重要的一个模块,也是最复杂,研究最多的一个模块。精排系统构建一般需要涉及样本、特征、模型三部分。
- 重排:获取精排的排序结果,基于运营策略、多样性、context上下文等,重新进行一个微调。
- 混排:多个业务线都想在Feeds流中获取曝光,则需要对它们的结果进行混排。比如推荐流中插入广告、视频流中插入图文和banner等。
svm
是一个二分类器 他的目标是找到和支持向量(离分类超平面最近的点)与超平面的距离之和最大的那个超平面
核函数:通过低维空间的一个复杂运算代替高维空间中的普通内积,实现等效升维,维度够高都是线性可分的
BiLSTM
首先,BiLSTM-CRF的输入是词向量,输出是每个单词的预测的序列标注。
第一步:单词输入,单词进入look-up layer层,使用CBOW、Skip-gram或者glove模型映射为词向量。
第二步:词向量进入BiLSTM层,通过学习上下文的信息,输出每个单词对应于每个标签的得分概率。
例如,对于w0,BiLSTM节点的输出得分是1.5 (B-Person), 0.9 (I-Person), 0.1 (B-Organization), 0.08 (I-Organization) 以及0.05 (O),这些score作为CRF layer的输入。
此处的标签的得分概率作为CRF模型中的未归一化的发射概率。
第三步:所有的BiLSTM的输出将作为CRF层的输入,通过学习标签之间的顺序依赖信息,得到最终的预测结果
目标检测
1-stage r-cnn 先用分割方法选出目标区域 然后用一个算法合并一些目标区域 最后通过分类和IoU阈值得出结果
2-stage yolo 将图像划分为SxS个patch 对每一个区域卷积网络的一个head直接输出指定数量个的bounding box(中心点 h w prob) 另一个head直接输出每个patch的logit 然后对于每一个类的所有bb根据prob从大到小进行排序 所以第一个框是概率最大的框 开始扫描下一个框跟第一个框 看是否IOU大于0.5 大于0.5表示重复 可以删去 然后重复这个过程 第二轮开始选中概率第二大的框和后面的其他框进行同样的IoU判别
anchor base 就是先生成候选框 anchor free就是网络直接生成bb(yolo)
梯度下降的原理
y=x^2举例 x>0 梯度为正 y上升 如果步幅合适往梯度相反的方向移动x就可以到达极值点附近
finetune
一般在基础特征提取网络上进行finetune训练时 建议q冻结除BatchNormalization layers的其他layer 因为BN层冻结了会导致running average/variation 不更新
上采样
逆卷积 二次线性插值 最近插值
分割边缘模糊
带有边缘检测的损失函数
重载和重写的区别
重载是根据参数调用同名的不同方法 重写是子类重写父类的方法