队伍名称 [您吃了么], 第一次参加机器学习类比赛, 主要为了学习AI相关知识, 用时2个月,从python都不会到机器学习入门、实现代码、训练模型、预测结果并提交成功,最终成绩机器学习赛道B榜全球98名, (由于设备只有一台GTX1060 6GB)训练设备有限,无法训练出精度更高的模型。 关于这段时间学习机器学习的内容有很多,特此记录。
- 完成数码设备图像检索任务,即给定一张含有数码设备的查询图片,算法需要在数码设备图像库中查找并返回含有该商品的图片。
- 本次比赛提供的数据集包含两部分:
- 训练集(train)和测试集(test)。其中训练集包含不同数码商品,每个数码设备商品会对应数量不等的图片
- 测试集包含查询图片(query)和检索图像库(gallery),用于指标评估
- 采用top-1 accuracy 和mAP@10两种测评指标加权
𝟧𝟢% * 𝚝𝚘𝚙-𝟷 + 𝟧𝟢% * 𝚖𝖠𝖯@𝟷𝟢
- A/B榜
- 系统配置
- 操作系统(OS):Win10 x64
- 显卡(GPU):NVIDIA GeForce GTX 1060 6GB
- 安装内容
- Anaconda3
- Pycharm-2020专业版
- keras 2.2.0
- tensorflow_gpu-1.9.0-cp36-cp36m-win_amd64.whl
- cuda_9.2.148_win10
- cudnn-9.2-windows10-x64-v7.6.5.32
- 第三方库
- h5py
- numpy
- os
- csv
- keras
- tensorflow
- matplotlib.pyplot
- PIL
- shutil
- 具体步骤移步环境搭建
- 制作本次项目数据集到脚本所在文件夹,例如脚本所在文件
/workspace
中,包含了三个子文件夹分别为测试集、训练集和验证集,文件夹结构如下:
./workspace
|---test
|---gallery
|---query
|---train
|---DIGIX_000000
|---DIGIX_000001
......
|---validation
|---DIGIX_000000
|---DIGIX_000001
.......
- 本项目的训练集和验证集数据来自官方提供的
train_data
,按照8:2的比例进行切分,(在代码中切分的比例可以通过参数scale = 0.8
进行设置)。 - 测试集数据来自官方train_data_A数据。
- 官方提供的数据集共22G,由于设备原因一次训练或测试全部100%的数据耗时巨大,因此前期调整测试模型阶段选择前10%的数据作为参考,加速准确率的验证(在代码中可以通过参数
rate = 0.1
进行设置)。
- 我们采用了一个自定义的网络结构,但是,想要将深度学习应用于小型图像数据集,通常不会贸然采用复杂网络并且从头开始训练,因为训练代价高,且很难避免过拟合问题,所以采用一种更高效的方法——使用预训练网络。
- 利用预训练模型做迁移学习,在已有的模型上进行微调,好处是可以根据自己任务需要,将预训练的网络和自定义网络进行一定的融合,此外还可以使用图像增强的方式进行端到端的训练。训练代价虽大幅增加,但相对于从头训练来说,使用预训练网络的训练代价肯定要低得多。
- 我们利用了预训练的denseNet网络卷积层来提取图像的特征,并用这些特征进行检索任务,使用denseNet有如下几点优点:
- 省参数。在 ImageNet 分类数据集上达到同样的准确率,DenseNet 所需的参数量不到 ResNet 的一半
- 省计算。达到与 ResNet 相当的精度,DenseNet 所需的计算量也只有 ResNet 的一半左右。计算效率在深度学习实际应用中的需求非常强烈,抗过拟合。
- 具有非常好的抗过拟合性能,尤其适合于训练数据相对匮乏的应用。对于 DenseNet 抗过拟合的原因有一个比较直观的解释:神经网络每一层提取的特征都相当于对输入数据的一个非线性变换,而随着深度的增加,变换的复杂度也逐渐增加(更多非线性函数的复合)。相比于一般神经网络的分类器直接依赖于网络最后一层(复杂度最高)的特征,DenseNet 可以综合利用浅层复杂度低的特征,因而更容易得到一个光滑的具有更好泛化性能的决策函数。
- 泛化性能更强。如果没有data augmention,CIFAR-100下,ResNet表现下降很多,DenseNet下降不多,说明DenseNet泛化性能更强。
- DenseNet仍使用了大量的的参数,耗费计算资源,有3个全连接层,其中绝大多数的参数都是来自于第一个全连接层。但是通过测试发现,这些全连接层即使被去除,对于性能也没有什么影响,这样就显著降低了参数数量,提高训练速度。因此我们去掉中间两层全连接层减少训练代价的同时,也能保证更好的迁移学习效果。
- 通过解冻部分denseNet网络,联合训练解冻层和自定义网络。通常keras的冻结和解冻操作用的是模型层的trainable属性。定义这一属性后,模型需要重新编译才能生效,定义DenseNet网络和自定义网络结构,通过遍历每一层,解冻深层block,然后联合训练解冻层和自定义网络。
- 为了解决过拟合问题,除了采用dropout正则化减小模型复杂度还使用了图像增强,在Keras中,可以利用图像生成器定义一些图像变换。
- 利用训练好的图像特征模型对gallery库提取特征并使用HDF5文件进行储存,因为HDF为存储和处理大容量科学数据设计的文件格式及相应库文件,支持非常多的数据类型,通用,高效的 I/O 性能,支持几乎无限量(高达 EB)的单文件存储等,在python中用 h5py 操作 HDF5 文件,我们可以像使用目录一样使用 group,像使用 numpy 数组一样使用 dataset,像使用字典一样使用属性,非常方便和易用。
- 经过上述操作,我们已经将数据集中的所有图片的特征保存到数据库中,依次抽取query查询库图片的特征,然后和特征库中的特征一一使用numpy比较向量间的相似度(knn的balltree),然后按照相似度排序,返回top10的查询结果
- 更深的网路结构
- 解冻更多层进行联合训练
- 调节验证比例
scale
- 调节训练数据比例
rate
- 调节
epoch
、batch_size
、adam_learn_rate
超参数 - 更换相似度比较算法
由于我的电脑显卡仅6G,因此我使用的是深度学习雾计算平台MistGPU加速深度学习模型训练
- 用PyCharmy远程连接服务器同步代码进行调试
- 进入
控制台
,创建服务器
,设置服务器密码
- 根据
服务区列表
的ssh命令,获取host
,user name
,端口号
来配置pycharm的ssh服务器
- 进入
例如:[email protected] -p 41500,
[host]: gpu28.mistgpu-xyz.com
[user name]: mist
[端口号]: 41500
- 具体配置参考官网教程PyCharm连接教程
- 在pycharm终端Terminal中输入
ssh [email protected] -p 41500
连接服务器的终端。 - 通过
上传数据集
单独上传训练/验证/测试集/预处理模型的权值压缩包文件,上传的数据挂在根目录下/data
文件内, 建议不要直接在/data
目录下将您压缩的文件进行解压,这样会造成不必要的空间占用,以及文件夹数据获取速度往往会比压缩包获取速度慢.
cd ~
在~目录下创建一个工作目录mkdir work
- 使用命令
rsync --progress train.zip ~/work
拷贝大文件到~/work
目录下 - 解压文件
unzip train.zip