1. 模型
1.1 模型方案定义
实际问题是复杂的,如何从实际问题中抽象关键需求并定义为一个模型预测问题是非常重要和讲究的。这一步绝对不是拍脑袋看到个模型就用可以解决的,它要求设计者必须对深度学习有深入的了解。如果一开始的方案定义就有问题,那么后边再怎么做都是无用功。
深度学习能做什么——方案定义是否合理?
比如用卷积网络去做某件事,那么就必须了解卷积有什么特性、能做什么、不能做什么。一个common
sense是卷积具有两大特性:局部连接和权值共享。从这两个特性往下推就是平移不变性,也就是说对同一个物体,不管处于图像上的哪个位置,其语义定义都应该是一致的、不能有歧义。比如同样一个物体,处于图像上的A区域时将其类别定义为
另一方面,必须意识到深度学习模型的能力边界,什么样的设计会让模型学不好。比如数据不均衡导致了长尾效应,那么模型对于长尾类别的预测效果自然不好,设计的时候就要考虑是不是有更好的定义方式从而缓解长尾效应呢?比如要预测非常细小的物体,那么我给定的分辨率下模型能不能看到,如果看不到要考虑是不是输入分辨率要高一些或者使用对细小物体预测效果更好的模型呢?
什么样的模型能最好解决这个问题?
如何抽象出来关键需求同样重要,这决定了要用什么复杂度的模型解决问题。粗略地说,如果单纯想知道一片区域是什么东西,那么语义分割就足够了;如果想要粗粒度的实例级信息,那么目标检测就足够了,如果想要细粒度的实例级信息,那么实例分割就足够了;如果想要全图物体的信息并尽可能给出实例级信息,那么就要考虑全景分割等等。更进一步的,在每一个类型下还可以继续细分找最合适的模型方案,最合适的模型才是最好的模型,才能事半功倍。
1.2 数据的重要性
我认为数据集和模型是互相定义的,数据集提供先验数据分布,决定了模型的预测能力和预测方向;模型则定义了数据集的形式和接口并在实际应用过程中指明数据集的扩充方向。
数据驱动
对于深度学习应用来说非常重要的一点是建立由数据驱动的闭环迭代流程,即数据 -> 模型 -> 场景 -> 数据....这样的良性循环。
由数据训练模型、模型上线应用于场景这两点是很容易做到的,困难的在于如何从场景中获取高质量的数据,这就需要有一套完备的数据挖掘流程。只有打通这个流程,才能实现模型、数据和场景的迭代闭环。
数据集
搭建数据集的注意事项有几点:
- 如上边说过的,标注定义不能有歧义;
- 数据集应该丰富、多样、有效;
- 要有可靠的评估集,这意味着首先要独立,不能与训练集存在交叠。严格地讲,同一个场景不应该既出现在训练集中又出现在评估集中;其次评估集的数据应该有效,其大体上应该和训练集处于同一数据分布中。
1.3 类别不均衡 / 长尾问题
长尾问题是一个经常遇到又不好解决的问题,一方面在数据和模型设计上应该尽量避免和缓解这个问题,另一方面需要一些策略缓解。
数据集上:
- 借助于生成模型、仿真环境等方法扩充数据集中的长尾数据;
模型上:
- 重采样策略:训练时对tail类过采样,或对head类欠采样;
- 在loss计算时,使用Focal loss等;对不同的类别设置不同的权重,对tail类设置更大的权重;
- 在分割任务中使用region-based损失取代distributed-based损失
- 采用一些少样本问题的训练方法,如:meta-learning、few-shot learning、transfer learing;
- 训练时采用OHEM挖掘难负样本;
- Equalization Loss for Long-Tailed Object Recognition
1.4 多任务模型
对于一些数据同源或者基本同源的任务来说,可以将其合并在一个模型中,不同任务共享backbone(或backbone+FPN),每个任务有自己的head,这样做的好处有几点:
- 共用特征提取部分可以降低总的模型参数和运算量,减小负载;
- 如果任务之间没有明显冲突的话,多个任务联合训练有助于提升backbone的特征提取能力,获得更丰富的语义信息;
- 使用同一个模型后不同任务的结果是可以对齐到图像的,这样也有助于做一些后期的verify。
然后,要把多个任务合并在一个模型中不是一件容易的事情,处理不好的话会导致各个任务都显著降点。处理上大概有以下几个要点:
- 不同任务的数据量存在差异,可以考虑对不同任务过采样 / 欠采样;
- 使用多任务训练的策略,比如
CAGrad
、MTAN
等; - 调整各个任务的loss和权重,尽量使各项任务的收敛趋势基本一致,并且控制不同任务的loss量级在合理的范围内。
2. 部署
TODO