# HuaweiDIGIX-2020 **Repository Path**: liuwentao1234/huawei-digix-2020 ## Basic Information - **Project Name**: HuaweiDIGIX-2020 - **Description**: No description available - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-03-17 - **Last Updated**: 2021-04-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ✨2020 DIGIX全球校园AI算法精英大赛✨ ================================= 队伍名称 ***[您吃了么]***, 第一次参加机器学习类比赛, 主要为了学习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 * 具体步骤移步[环境搭建](https://github.com/liuwentao1992/HuaweiDIGIX-2020/blob/master/%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md) 算法实现逻辑 ============== ![2](https://github.com/liuwentao1992/HuaweiDIGIX-2020/blob/master/README%E5%9B%BE%E7%89%87/%E6%AD%A5%E9%AA%A4.jpg) 1. [对官方数据集进行预处理,制作训练验证测试集](#制作训练验证测试集) 2. [构建网络](#构建网络) 3. [冻结部分卷积层做迁移学习](#) 4. [数据增强](#图像增强) 5. [开始训练](#) 6. [提取图库特征建立特征数据库](#建立特征库) 7. [开始检索测试集图片输出结果](#检索) 8. [后期优化调整策略](#后期优化调整策略) ### 制作训练验证测试集 * 制作本次项目数据集到脚本所在文件夹,例如脚本所在文件`/workspace`中,包含了三个子文件夹分别为测试集、训练集和验证集,文件夹结构如下: ```cpp ./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有如下几点优点: > 1. 省参数。在 ImageNet 分类数据集上达到同样的准确率,DenseNet 所需的参数量不到 ResNet 的一半 > 2. 省计算。达到与 ResNet 相当的精度,DenseNet 所需的计算量也只有 ResNet 的一半左右。计算效率在深度学习实际应用中的需求非常强烈,抗过拟合。 > 3. 具有非常好的抗过拟合性能,尤其适合于训练数据相对匮乏的应用。对于 DenseNet 抗过拟合的原因有一个比较直观的解释:神经网络每一层提取的特征都相当于对输入数据的一个非线性变换,而随着深度的增加,变换的复杂度也逐渐增加(更多非线性函数的复合)。相比于一般神经网络的分类器直接依赖于网络最后一层(复杂度最高)的特征,DenseNet 可以综合利用浅层复杂度低的特征,因而更容易得到一个光滑的具有更好泛化性能的决策函数。 > 4. 泛化性能更强。如果没有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的查询结果 ### 后期优化调整策略 1. 更深的网路结构 2. 解冻更多层进行联合训练 3. 调节验证比例`scale` 4. 调节训练数据比例`rate` 5. 调节`epoch`、`batch_size`、`adam_learn_rate`超参数 6. 更换相似度比较算法 借助云GPU平台运行调试 ====================== 由于我的电脑显卡仅6G,因此我使用的是深度学习雾计算平台[MistGPU](https://mistgpu.com/)加速深度学习模型训练 * 用PyCharmy远程连接服务器同步代码进行调试 * 进入`控制台`,`创建服务器`,`设置服务器密码` * 根据`服务区列表`的ssh命令,获取`host`,`user name`,`端口号` 来配置pycharm的ssh服务器 ``` 例如:mist@gpu28.mistgpu-xyz.com -p 41500, [host]: gpu28.mistgpu-xyz.com [user name]: mist [端口号]: 41500 ``` * 具体配置参考官网教程[PyCharm连接教程](http://blog.mistgpu.com/2020/04/08/PyCharm%E8%BF%9E%E6%8E%A5%E6%95%99%E7%A8%8B/) * 在pycharm终端Terminal中输入`ssh mist@gpu28.mistgpu-xyz.com -p 41500`连接服务器的终端。 * 通过`上传数据集`单独上传训练/验证/测试集/预处理模型的权值压缩包文件,上传的数据挂在根目录下`/data`文件内, 建议不要直接在`/data`目录下将您压缩的文件进行解压,这样会造成不必要的空间占用,以及文件夹数据获取速度往往会比压缩包获取速度慢. ![1](https://github.com/liuwentao1992/HuaweiDIGIX-2020/blob/master/github%E5%9B%BE%E7%89%87/train_test_validation.png) * `cd ~`在~目录下创建一个工作目录`mkdir work` * 使用命令`rsync --progress train.zip ~/work`拷贝大文件到`~/work`目录下 * 解压文件`unzip train.zip`