此项目对应作业一(图像主题识别)。包含了所需数据,以及一些基本的预处理程序。
文件整体目录为:
- resource: 作业所需用到的相关资源,如数据集源文件,文件名称信息等
- SandPlayPreProcess:沙盘文件预处理程序
- model_utils:基于沙盘图像的视觉预训练模型
对各个文件作进一步说明:
-
homework_sand_label_datasets: 本次作业所使用到的数据集,此目录下的每一个文件夹对应一个数据样本。每个 数据样本包含如下文件:
1)BireView.png 表示沙盘图像
2)heightmap.png 表示沙盘中 的 地势/河流信息
3)STinfo_xx.txt 表示沙盘中出现的所有沙具信息;其中,每一行表示一个沙具,包含的沙具信息有 (沙具名称,沙具类别,,x坐标,y坐标,xy平面的旋转角度,是否倾斜,是否颠倒,缩放比例,沙具长度,沙具宽度)
4)theme_label_infor.json表示主题标注信息;以列表的形式给出,列表中的每一个元素表示(不同)标注者判断的主题结果,以及相应的原因说明。 我们关注的6个主题,及其对应的正样本数量为:{'整合': 162, '流动': 221, '联结': 192,'分裂': 130, '混乱': 113, '空洞': 133}
tips:可以结合不同主题判定结果所对应的原因,来设计相应的主题判断程序
注:对于一个沙盘样本,BireView.png以视觉图像的形式,包含了其所有的信息;heightmap.png和STinfo_xx.txt文件一起,以另一种形式也包含了沙盘的所有信息
-
file_namelist_infor.json:以字典的形式存储沙盘样本名称信息。其中,"all_file"表示所有的样本文件名称(共409个); "train_file"与"test_file"表示划分的训练集样本(260个)和测试集样本(49个)。
注:应基于train_file中的文件来进行模型设计;使用test_file中的文件来测试模型的性能。提交作业时,需给出模型在训练集和测试集上的性能测量指标。
-
sanders_onehot_label.json:整个沙盘环境中,所涉及的所有沙具名称。每个沙具对应一个唯一的编号,在下文 沙具多标签多分类模型的设计中会有所涉及。
沙盘预处理程序库,将沙盘文件 读取和保存成特定的数据格式。可在此基础上进行主题识别程序的设计。
使用说明请参照 p1_1_load_sandplay_infor.py
由于数据集的规模较小(仅有409组有标注沙盘样本),不便于直接使用深度学习的方法。 这里提供了一个针对BireView.png图像的沙盘视觉预训练模型,可使用此模型得到的 特征图(网络后几层),来进行 后续主题识别模型的设计。
对于此模型,其所实现的任务是关于沙盘中所出现沙具的多标签多分类任务,其输入数据为BireView.png图像,输出数据为所有沙具(494个)的分类概率(概率大于0.5,视为沙盘中存在此沙具)。 网络模型由 clip视觉编码模块(具体为 "ViT-B/16") + 全连接分类层 组成,详情见CLIP(https://github.com/openai/CLIP) 以及model_base.py文件
此模型是在另外一个中等规模(5k) 未标注主题的 数据集(未提供)上训练得到,沙具的多标签多分类准确率可以达到80%(由于 沙具长尾分布的原因, 对于那些出现频率很少的沙具识别效果不佳,但对经常出现的绝大多数沙具,都能进行识别)。模型的权重为 sand_object_classification.pkl。
模型的使用请参照 p1_2_get_visual_feature.py
注:沙具多标签多分类 并不是我们所关心的任务,只是借助此任务来得到一个 关于沙盘图像的预训练模型, 我们希望 使用 此预训练模型 来服务于 最终的 沙盘主题识别
- 本次实验的目标是完成对沙盒图像的主题分类。本次实验的数据集共有309张沙盒图像,每张图像提供6个专家主题标注。主题共有6大类:整合、流动、联结、分裂、混乱、空洞。数据集划分为训练集260张图像、测试集49张图像。
- 本实验预期使用深度神经网络模型(ResNet18)、预训练模型(pretrained-Vit)、卷积神经网络模型(CNN)实现沙盒主题分类并对比不同方法之间的性能差异。
- 实验一:比较不同预训练模型在沙盒主题分类任务中的性能
- 使用在沙盒图像数据集上预训练的Vit-B/16模型进行视觉特征提取,设计并训练分类网络实现主题分类。
- 使用预训练的resnet-18进行特征提取和分类
- 实验二:比较使用预训练权重和不适用预训练权重的分类性能
- 使用预训练的resnet-18进行特征提取和分类
- 使用resnet-18从头训练实现沙盒主题分类
- 实验三:比较不同神经网络模型的分类性能
- 使用resnet-18从头训练实现沙盒主题分类
- 使用自主设计的卷积神经网络模型实现沙盒主题分类
- 统一标签:本次实验用到的数据集每个图像包含6个专家标注,每个专家标注给出了若干个可能的主题类别。因此需要设计方案来统一每张图像的具体类别。
- 实现的思路是统计6个专家标注,采用投票法选出被标注次数最多的主题作为最终标签。
- 如果每个主题被标注的次数相同,则统计这类样本的数量,如果数量较少例如小于总数据集的1%则可以作为outlier删除该样本;如果样本数量较多则随机选择一个主题作为该样本的最终标签
- 需要对全体数据集都进行统一标签的操作
- 代码实现见
sandplay_homework/SandPlayPreProcess/unify_labels.py
- 设计模型:本次实验需要设计6个模型,包括基于预训练Vit-B/16的分类模型、基于预训练resnet-50的分类模型、不使用预训练参数的resnet-50分类模型、自主设计的卷积神经网络模型、KNN模型、K-means模型
- 模型设计使用torch,避免从头造轮子。
- 代码实现见
sandplay_homework/model_utils/model_base.py
- 设计数据结构:
- 本次实验需要自主设计基于torch的
Dataset
和DataLoader
- 代码实现见
sandplay_homework/data/datasets/sandplay_dataset.py
,sandplay_homework/data/build.py
- 本次实验需要自主设计基于torch的
- 数据预处理设计:预训练Vit-B/16和预训练resnet分别需要设计对应的transforms
- 代码实现见
sandplay_homework/data/transforms/build_transforms.py
- 代码实现见
- 选择优化器:
- 代码实现见
sandplay_homework/solver/build_optimizer.py
- 代码实现见
- 实现训练和推理逻辑:
- 代码实现见
sandplay_homework/engine/trainer.py
,sandplay_homework/engine/inference.py
- 代码实现见
- 实现训练与测试的主程序:
- 代码实现见
sandplay_homework/tools/train_net.py
,sandplay_homework/tools/test_net.py
- 代码实现见
- 实现log和学习过程的可视化监控
- 代码实现见
sandplay_homework/utils/logger.py
- 代码实现见
- 在进行统一标签的步骤时发现309个数据中有13个图像没有专家标注,因此这13张图可以看作无效样本;62个图像每个专家标注都互不相同,因此这62个图像不具备有参考价值的标签,可以看作噪声样本;19个图像数量最多的专家标注是6个主题之外的词,因此这19张图可以看作偏差样本。这些样本对于训练会产生不利影响,因此本实验考虑将其剔除。清理过后剩下215个样本,其中训练样本181个,测试样本34个
- 本次实验将训练数据按照9:1进一步划分为训练集和验证集,即训练集163张图,验证集18张图。后续可以尝试使用K-fold validation
- 训练过程可视化分析
图1展示了四个模型分别在训练集上的分类准确率、损失和在验证集上的分类准确率和损失。 图中的四种颜色分别代表:
- 黄色:CNN模型
- 蓝色:预训练ResNet18模型
- 红色:ResNet18模型
- 绿色:预训练ViT模型
通过对比不难发现:
- CNN模型在训练集上收敛的速度最快,但是在验证集中也出现了比较大的过拟合问题。最终在验证集上的分类准确率大约收敛到0.52左右
- 预训练的ResNet18在训练集上的分类准确率收敛速度排在第二位,并且和CNN相似在大约50个epochs后开始出现过拟合,最终在验证集上的分类准确率收敛到0.45左右
- 没有预训练的ResNet18在训练集上的损失函数又较大波动,训练不够平稳,并且在验证集上的损失函数波动尤为明显。最终的分类准确率也大约收敛到了0.45左右,但是收敛速度明显不如预训练的ResNet18
- 预训练的ViT模型收敛速度最慢,但是其最终的分类准确率最高收敛到了大约0.62左右
根据学习曲线不难发现,ViT还没有完全收敛,因此又增加了训练轮数进行测试
如图所示,图中绿色为训练200个epochs的学习曲线,紫色为训练400个epochs的学习曲线,总的来看模型收敛到了更高的分类准确率,但是最优模型的性能没有提升。
综上所述最终的模型分类准确率对比如下表所示:
model | validation accuracy | test accuracy |
---|---|---|
ViT | 0.6842 | 0.588 |
Pretrained ResNet18 | 0.6316 | 0.324 |
ResNet 18 | 0.6316 | 0.412 |
CNN | 0.6316 | 0.471 |
通过该实验得知,由于ViT在sandplay数据集上进行过预训练因此具备该领域的先验知识这对于后续特征提取以及分类有着很大作用。 虽然ResNet18也在Imagenet-1K数据集上进行了预训练,但是由于Imagenet-1k数据集和sandplay数据集之间存在较大的domain gap导致预训练的ResNet18在sandplay数据集上微调后的分类性能不够理想,甚至不如从头训练的ResNet18 自主设计的CNN只有两层卷积神经网络,模型量级虽小但是性能却还可以。这也有可能是因为训练CNN时引入了一些数据增广,从而提高了在测试集上的泛化性