AI备忘录 - 图像分类
type: channel
link: https://www.aiuai.cn/tag/%E5%9B%BE%E5%83%8F%E5%88%86%E7%B1%BB/
items: Pytorch - 图像分类库timm快速使用
items: 基于深度神经网络的噪声标签学习问题[转]
items: 淘宝首页那些辣眼睛的图片过滤[转]
items: 淘宝噪声标签自动识别算法[转]
items: 计算机视觉八大任务全概述：PaddlePaddle工程师详解热门视觉模型[转]
items: TensorFlow - TFRecord 数据集的生成与模型训练
items: 论文阅读 - 基于CNN的年龄和性别分类
items: Caffe 实践 - Multi-label 多标签标注的训练与部署
items: Caffe实践 - 多标签图片分类的训练与部署
items: Caffe实践 - 单标签图片分类的训练与部署

Pytorch - 图像分类库timm快速使用
type: item
date: 2022-02-05T18:30:00+08:00
description: 原文：Getting Started with PyTorch Image Models (timm): A Practitioner’s Guide - 2022.02.02Github： rwightman/pytorch-image-modelsPyTorch Image Models（timm） 是一个优秀的图像分类 Python 库，其包含了大量的图像模型（Image Models）、Optimizers、Schedulers、Augmentations 等等.timm 提供了参考的 training 和 validation 脚本，用于复现在 ImageNet 上的训练结果；以及更多的 官方文档 和 timmdocs project.https://rwightman.github.io/pytorch-image-models/https://fastai.github.io/timmdocs/但，由于 timm 的功能之多，所以在定制使用时很难知道如何入手. 这里主要进行概述.pip install timm==0.5.41. Modelstimm 提供了大量的模型结构集合，而且很多模型都包含了预训练权重，或 PyTorch 训练、或从Jax和TensorFlow中移植，很方便下载使用.模型列表：https://paperswithcode.com/lib/timm查看模型列表：#打印 timm 提供的模型列表 print(timm.list_models()) print(len(timm.list_models())) #739 #带有预训练权重的模型列表 print(timm.list_models(pretrained=True)) print(len(timm.list_models(pretrained=True))) #592其中，timm.list_models() 函数：list_models(filter='', module='', pretrained=False, exclude_filters='', name_matches_cfg=False)查看特定族模型，如：print(timm.list_models('gluon_resnet*')) print(timm.list_models('*resnext*', 'resnet') ) print(timm.list_models('resnet*', pretrained=True))1.1. create_model 一般用法timm 创建模型最简单的方式是采用 create_model.以 Resnet-D 模型为例（Bag of Tricks for Image Classification For Convolutional Neural Networks paper），其是Resnet 的一种变形，其采用 average pool 进行下采样.model = timm.create_model('resnet50d', pretrained=True) print(model) #查看模型配置参数 print(model.default_cfg) ''' {'url': 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/resnet50d_ra2-464e36ba.pth', 'num_classes': 1000, 'input_size': (3, 224, 224), 'pool_size': (7, 7), 'crop_pct': 0.875, 'interpolation': 'bicubic', 'mean': (0.485, 0.456, 0.406), 'std': (0.229, 0.224, 0.225), 'first_conv': 'conv1.0', 'classifier': 'fc', 'architecture': 'resnet50d'} '''1.2. create_model 修改输入通道timm models 有个非常有用的特点，其可以处理任意通道数量的输入图像. 这是很多其他库所不具备的. 其实现原理可参考：https://fastai.github.io/timmdocs/models#So-how-is-timm-able-to-load-these-weights?model = timm.create_model('resnet50d', pretrained=True, in_chans=1) print(model) #test, single cha…

基于深度神经网络的噪声标签学习问题[转]
type: item
date: 2021-08-11T22:52:00+08:00
description: 基于深度神经网络的噪声标签学习-云社区-华为云 (huaweicloud.com)神经网络的成功建立在大量的干净数据和很深的网络模型基础上。但是在现实场景中数据和模型往往不会特别理想，比如数据层面有误标记的情况，像小狗被标注成狼，而且实际的业务场景讲究时效性，神经网络的层数不能特别深。我们尝试不断迭代数据和模型缺陷情况下神经网络的有效训练方法，通过noisy label learning技术，解决网络训练过程中noisy data的问题，该技术已经在团队实际业务场景中落地，通过从损失函数、网络结构、模型正则化、损失函数调整、样本选择、标签纠正等多个模块的优化，不局限于全监督、半监督和自监督学习方法，提升整个模型的鲁棒性1. 损失函数主要是从损失函数去修改，核心思路是当数据整体是干净的时候，传统的交叉熵损失函数学习到少量的负样本，可以提升模型的鲁棒性；当数据噪声比较大时，CE会被噪声数据带跑偏，我们要修改损失函数使其在训练中每个样本的权重都是一样重要的，因此不难想到采用GCE Loss，控制超参数，结合了CE Loss和MAE LossA. Ghosh, H. Kumar, and P. Sastry,“Robust loss functions under label noise for deep neural networks,” in Proc. AAAI, 2017Generalized Cross Entropy Loss for Training Deep Neural Networks with Noisy Labels, NeurlPS 2018另外，还有从KL散度想法借鉴过来的，作者认为在计算熵的时候，原始q, p代表的真实数据分布和预测值在较为干净的数据上没有问题，但是在噪声比较大的数据上，可能q并不能代表真实数据分布，相反的是不是p可以表示真实数据分布，因此提出基于对称的交叉熵损失函数（Symmetric cross entropy ）Y. Wang, X. Ma, Z. Chen, Y. Luo, J. Yi, and J. Bailey, “Symmetric cross entropy for robust learning with noisy labels,” in Proc. ICCV, 2019, pp. 322–3302. 模型结构主要通过借鉴巧妙的网络结构，在模型训练过程中，通过模型对数据进行挑选，选择一批较为干净的数据，逐步提升模型的鲁棒性。首先要介绍的就是coteaching framework，首先是基于两个模型相互挑选数据输入给对方计算loss，传递给对方网络的数据是每个min-batch里面loss最低的一些数据，随着epoch增加，数据量有所变化，另外每一轮epoch结束，会shuffle数据，保证数据不会被永久遗忘How does Disagreement Help Generalization against Label Corruption? ICML 2019Co-teaching: Robust Training of Deep Neural Networks with Extremely Noisy Labels, NeurlPS 2018还有一种思路，是基于attention注意力机制给干净样本和噪声数据进行打分，文章叫做Attention Feature Mixup，在计算最终loss的时候有两部分，一部分是同一个类的每张图和标签计算的交叉熵损失；另外一个损失是数据mixup得到的新的数据x'和标签y'计算的loss3. 正则化主要是通过一些添加正则ticks，防止模型过拟合到噪声数据上，常用的正则方法包含：label smooth、l1、l2、MixUp等4. 样本选择主要是从如何挑选出更好的数据为出发点，一种方法，叫做Area Under the Margin metric (AUM)，是我们去年参加CVPR WebVision 2020（图像识别领域最高级别的比赛，接替ImageNet）取得冠军的方案。该方案是一种在训练过程中一边训练一边筛选数据的方式，具体思想是在一个min-batch利用模型计算每张图片的logits值和其它类中最大的logits求差值当做area，这样多轮epoch求平均，得到每张图的aum值。试验发现如果这个数据是较为干净的数据area的值会比较大，如果是存在mis-label的数据area值比较小，甚至是负值，作者就是通过这个思想将一个类的干净数据和噪声数据分离开的。当然论文在最后也指出，干净数据和噪声数据占比99%的阈值是最优的。Pleiss, Geoff, et al. "Identifying mislabeled data…

淘宝首页那些辣眼睛的图片过滤[转]
type: item
date: 2020-02-18T21:10:06+08:00
description: 原文：淘宝首页那些“辣眼睛”的图去哪了？- 2019.12.13出处：天池大数据科研平台 - 微信公众号作者：忘返导读：在淘宝这个平台上，消费者每天都在浏览着琳琅满目的图片，图片是消费者与商品交互的第一媒介. 图片的质量会极大影响消费者的消费体验和转化效果，高质量的图片会让消费者怦然心动，流连忘返，而低质量的“辣眼睛”图片会让消费者望而却步. 在淘宝首页猜你喜欢(以下简称首猜)场景下，由于图片数量太多，让人工来审核所有图片是不现实的. 作为阿里技术人，我们的使命就是使用技术手段过滤掉低质量的图片，将高质量的图片和素材呈现给消费者.一. 摘要恶心图片，顾名思义，就是让人感到恶心，不适的图片. 其大致可以被分为跟动物有关的，跟人有关的，以及物体这三种类型. 要从数量巨大的商品池中精确地将恶心图片过滤出来，面临着以下几个技术难点：[1] - 初始样本很少且难收集，面临模型冷启动的问题；[2] - 线上真实数据场景下，正负样本比例差距过大，面临严重的类别不平衡问题；[3] - 恶心样本多种多样，如昆虫，爬行动物，人的各个身体部位等等，样本的特征分布非常分散. 针对第一个问题，我们通过本团队的小样本平台从淘宝内容池中召回恶心图片扩充样本量，并通过半监督算法利用淘宝的无标签数据进行训练. 针对第二个问题，我们在训练中通过 online hard example mining +级联的方法，并且通过 active learning和噪声样本识别算法加快模型迭代. 针对第三个问题，我们在模型中引入了attention机制，让模型focus在恶心的局部区域. 本文的二、三、四节分别论述了这三个解决方案. 模型于19年10月初在首猜上线，在集团的各个业务场景下累计召回了几万张恶心图片. 最新版的模型的精确率为95%，召回率为94%.二. 冷启动方案由于初始样本量比较少，面临冷启动的问题. 我们从首猜负反馈数据里拿到了几百张恶心图片，并通过本团队的小样本召回平台，用图像检索的方法从淘宝内容池中召回了几百张恶心图片，组成了最开始的训练样本. 为了防止过拟合，我们采用了轻量级的网络 mobilenet v2. 另外，我们通过半监督算法利用淘宝的无标签数据进行训练，提高模型的泛化能力. 具体思想为：一个网络的输出可以被认为是 $Y=\mathbf{f}_{\mathbf{w}}(X)$，其中 W 是网络参数，X 是输入图片. 一个好的模型应该足够鲁棒，无论是 W 的扰动(本文称为参数扰动)还是X的扰动(本文称为 输入扰动)，输出都应该保持不变. 训练流程如下所示：对于有标签数据，对 student 网络的输出构造交叉熵损失函数，对于所有数据(无标签+有标签)，对student 网络和 teacher网络(两个网络结构一致)的输出构造 MSE 损失函数. 每次迭代的时候使用梯度下降法更新student网络参数并使得teacher网络的参数成为student网络参数的滑动指数平均. (具体可参考论文 Mean teachers are better rolemodels: Weight-averaged consistency targets improve semi-supervised deeplearning results - 2017)如下式所示：$$ \theta^{\prime}_t = \alpha \theta^{\prime}_{t-1} + (1-\alpha) \theta_t $$Github - CuriousAI/mean-teacher在参数扰动上，我们使用的是上述公式中的滑动指数平均. 在输入扰动上，我们对student网络和teacher网络的输入做了不同的数据增强. 我们使用了随机翻转，random resized crop,random erasing等方法，在后来召回来的 bad case中，发现有一部分召回来的负样本是化了妆的嘴唇、眼部、脸部等，这些区域和某些恶心图正样本比较相似. 因此尝试了random_distort 的方法,经过处理之后，类似的 bad case 基本消除.三. 算法迭代流程在线上数据中，正负样本的比例非常不均衡(远低于千分之一)，大部分都是各种各样的正常图片，只有少量的恶心图. 这意味着，即使模型在验证集上能达到99%的准确率，剩下的1%的错误也会在线上被无限放大，而且线上还有很多训练集里没出现过的负样本. 在模型版本快速的更替中，我们采取了 active learning，噪声样本识别，OHEM+级联的迭代流程，如下图所示. 3.1. active learning在每次的版本迭代过程中，模型都会召回一批数据. 在一开始数据量比较少的情况下，可以全部标注然后进行训练. 但是当数据变多了以后…

淘宝噪声标签自动识别算法[转]
type: item
date: 2019-09-15T09:57:00+08:00
description: 原文：每天审核淘宝性感图的工程师，竟然还做了这个 - 2019.09.11出处：淘系技术 - 微信公众号作者：胡佳洁(佳婕) 、黄锦池(尘漠)，曲烈(汤问)出品：阿里巴巴新零售淘系技术部论文：O2U-Net: A Simple Noisy Label Detection Approach for Deep Neural Networks - ICCV2019导读：获取高置信标注的大规模数据集是有监督学习算法的一个难点问题，训练集中的噪声标签会严重降低模型的精度. 通过所提出的噪声标签自动识别算法，无需人工干涉就可获取高质量的干净数据集，可以充分发挥海量弱标签数据的潜力，并提升模型的精度. 本文相关工作收录于 ICCV2019(IEEE International Conference on Computer Vision，CV 领域三大顶会之首)，详细介绍了淘系技术部算法团队提出的一种简单、高效的噪声标签识别算法，只需调节训练时的学习率，就可以让 90% 的噪声标签原形毕露.1. 背景训练数据的规模及其标注质量对有监督学习算法的性能影响重大. 互联网上虽然有海量的可爬取的数据，但这些按照标签语义收集来的数据往往带有大量噪声. 因此，要在这些弱标签数据上训练出高性能的深度神经网络模型，研究人员往往面临着从噪声中提取足够多有用信息的挑战. 本文将介绍一种简单高效的噪声标签自动识别算法 ，只需设置学习率的变更策略就能识别出 90% 的噪声样本，进一步提高训练模型的精度和收敛速度. 通常基于 human-supervision 的标签净化方法中，为保障训练数据的质量往往需要投入高昂的成本. 著名的图像数据集 ImageNet 有 120 万带标数据，标注过程中李飞飞实施多轮多人带验证题的复杂标注策略，才确保了数据集的质量. 但在实际业务中我们不可能投入如此巨大的成本，外包标注的数据往往是单次打标，许多因素会导致我们拿到的训练集存在不同程度的噪声，例如下图是外包对性感图任务打标结果的截图，对类似的图片标注结果完全相反，用这批带噪数据进行训练得到的模型精度无法达到上线要求. 因此，对高质量数据的需求与低效率的人工标注，构成了广大算法攻城狮们在模型开发的初级阶段所要解决的主要矛盾. 针对噪声问题，一味地调整模型和算法治标不治本. 我们在淘宝内容库类目分类识别的业务问题中发现，如果训练数据的精度不到 80% ，那么训练出来的模型精度是 72% 左右，无论模型怎么调整，精度只有 2%～3% 的提高，无法达到上线要求，因此还是需要从数据源头上解决问题. 依赖 human supervision 的方式净化数据集需要耗费大量的时间，让多个外包统一打标的边界也需要付出很大的沟通成本. 为提高业务效率，我们沉淀出一套简单高效易移植的噪声样本识别算法，自动找出可能是噪声的样本，并通过剔除可疑噪声数据在干净训练集上训练以提高模型精度. 在解决业务问题中，噪声样本识别算法给我们带来了以下两方面显著的好处：[1] - 提高标注效率. 通过算法找出最可疑的样本，只需要对筛选出来的最可疑的样本进行二次审核，减少标注人员的工作量，也能大幅提高迭代速率. [2] - 提高模型精度. 如果我们的噪声样本识别精度足够高，甚至识别精度达到95%以上，我们甚至不需要对可疑的噪声样本做人工复审，直接剔除掉训练模型以提高精度. 接下来，我们将详细介绍噪声样本标签识别算法，相关工作已被计算机视觉领域的顶会ICCV2019接收《O2U-Net: A Simple Noisy Label Detection Approach for Deep Neural Networks》.2. 解决思路我们调研了在噪声样本识别、抗噪模型等领域的前沿技术. 以下是针对 state-of-the-art paper 的调研分析. [1] - 《Understanding Black-box Predictions via Influence Functions》 论文主要利用 influence function 识别出噪声样本. 算法计算每个训练样本对验证集 loss 变化影响，如果某个训练样本对于验证数据集的精度起到负影响，那么就可能是不好的样本，这些样本可能包含了比较多的噪声样本. 论文的创新点在于提出了计算每个训练样本对当前模型性能的影响大小的方法，即 influence function . 对于影响为负值的训练样本，且该绝对值很大时，那么该样本就不是好的样本. [2] - 《CurriculumNet: Weakly Supervised Learning from Large-Scale Web Images》文章采用课程学习的思想：人类学习知识的过程是从简单到难，读书教学，我们的学习过…

计算机视觉八大任务全概述：PaddlePaddle工程师详解热门视觉模型[转]
type: item
date: 2019-03-22T17:01:00+08:00
description: 原文： 计算机视觉八大任务全概述：PaddlePaddle工程师详解热门视觉模型 - 2019.03.22出处：量子位 - 微信公众号本文转载自 PaddlePaddle.编者按：来自百度的深度学习工程师，围绕计算机视觉领域的八大任务，包括：图像分类、目标检测、图像语义分割、场景文字识别、图像生成、人体关键点检测、视频分类、度量学习等，进行了较为详细的综述并形成此文. 这篇综述中，介绍了这些任务的基本情况，以及目前的技术进展、主要的模型和性能对比等. 而且还逐一附上了GitHub传送门，用于更进一步的学习与安装实践指南. 其中不少教程还是用中文写成，非常友好. 总之，这篇综述全程干货，推荐收藏阅读. 计算机视觉（Computer Vision）是研究如何使机器“看”的科学，更进一步的说，是使用摄像机机和电脑代替人眼对目标进行识别、跟踪和测量等的机器视觉，并通过电脑处理成为更适合人眼观察或传送给仪器检测的图像. 形象地说，就是给计算机安装上眼睛（摄像机）和大脑（算法），让计算机像人一样去看、去感知环境. 计算机视觉技术作为人工智能的重要核心技术之一，已广泛应用于安防、金融、硬件、营销、驾驶、医疗等领域. 本文中，一方面，介绍基于PaddlePaddle的计算机视觉技术在图像分类、目标检测、图像语义分割、场景文字识别四大基本任务场景下，如何帮助计算机从单个或者一系列的图片中提取分析和理解的关键信息及其相关的深度学习模型. 另一方面，视频在人们生活中越来越重要，伴随着技术成熟度的提高，计算机视觉技术的突破也从静态图像识别的“看到”转向了视频理解的“看懂”，故还介绍了基于PaddlePaddle的图像生成、人体关键点检测、视频分类相关的深度学习模型.一. 图像分类图像分类是根据图像的语义信息对不同类别图像进行区分，是计算机视觉中重要的基础问题，是物体检测、图像分割、物体跟踪、行为分析、人脸识别等其他高层视觉任务的基础. 图像分类在许多领域都有着广泛的应用. 如：安防领域的人脸识别和智能视频分析等，交通领域的交通场景识别，互联网领域基于内容的图像检索和相册自动归类，医学领域的图像识别等.1.1. 模型结构得益于深度学习的推动，图像分类的准确率大幅度提升. 在经典的数据集ImageNet上，训练图像分类任务常用的模型，包括AlexNet、VGG、GoogLeNet、ResNet、Inception-v4、MobileNet、MobileNetV2、DPN(Dual Path Network)、SE-ResNeXt、ShuffleNet等. △ AlexNet△ VGG△ GoogLeNet△ ResNet△ Inception-v4△ MobileNet△ SE-ResNeXt△ ShuffleNet1.2. 精度对比PaddlePaddle - 预训练模型下载，及 PaddlePaddle Fluid 文档：(还包括将Caffe模型转换为PaddlePaddle Fluid模型配置和参数文件的工具. )https://github.com/PaddlePaddle/models/blob/develop/fluid/PaddleCV/image_classification模型的结构和复杂程度都不一样，最终得到的准确率也有所区别. 下面这个表格中，列出了在ImageNet 2012数据集上，不同模型的top-1/top-5验证准确率.modeltop-1/top-5 accuracy(PIL)top-1/top-5 accuracy(CV2)AlexNet56.71%/79.18%55.88%/78.65%VGG1169.22%/89.09%69.01%/88.90%VGG1370.14%/89.48%69.83%/89.13%VGG1672.08%/90.63%71.65%/90.57%VGG1972.56%/90.83%72.32%/90.98%MobileNetV170.91%/89.54%70.51%/89.35%MobileNetV271.90%/90.55%71.53%/90.41%ResNet5076.35%/92.80%76.22%/92.92%ResNet10177.49%/93.57%77.56%/93.64%ResNet15278.12%/93.93%77.92%/93.87%SE_ResNeXt50_32x4d78.50%/94.01%78.44%/93.96%SE_ResNeXt101_32x4d79.26%/94.22%79.12%/94.20%△ 图像分类系列模型评估结果二. 目标检测目标检测任务的目标是给定一张图像或是一个视频帧，让计算机找出其中所有目标的位置，并给出每个目标的具体类别. 对于人类来说，目…

TensorFlow - TFRecord 数据集的生成与模型训练
type: item
date: 2018-07-14T13:42:11+08:00
description: TensorFlow 提供了多种图片数据读取的方法 - TensroFlow - 数据读取[转] 基于 TFRecord Flowers 数据集 fine-tune InceptionV1 模型.TensorFlow 数据数据读取方法主要有： 直接从磁盘读取 - 在 train_op 运行会话Session 时，采用 feed_dict 传递数据. 但是对于大规模数据集可能不太适用，因为需要足够的 GPU 内存来存储训练数据. 从 CSV 文件读取 - 不适用于图片. 从 TFRecord 文件读取 - 将图片转化为 TensorFlow 可读取格式的 TFRecord 文件，在训练是不用再读取原始图像文件，具有更高的读取效率. 这里主要基于 TFRecord 处理大规模数据集. 虽然 TFRecord 文件的创建不如从 HDF5 格式读取数据的方式(如 Keras 采用的)直接，但这种方式更便于采用数据管道工具(data pipeline tools) 进行图片训练，比如 queue runners，coordinaors 和 supervisors，有益于训练数据流的管理.TensorFlow 提供了 TF-Slim 封装用于 TFRecord 文件的创建与读取 - slim/datasets. TensorFlow - TF-Slim 使用总览 - 有关于基于 TFRecord Flowers 数据集的模型(不包括 TFRecord 文件的创建) TensorFlow - TF-Slim Data TensorFlow - TF-Slim 封装模块 1. 创建 TFRecord Flowers 数据集Flowers 数据集下载 - Flowers Dataset解压后的目录结构为：flowers_photos/ |----daisy | -------- *.jpg (633 张) |----dandelion | -------- *.jpg (898 张) |----roses | -------- *.jpg (641 张) |----sunflowers | -------- *.jpg (699 张) |----tulips | -------- *.jpg (799 张) TensorFlow 提供了将 Flowers 数据集转换为 TFRecord 的脚本： dataset_utils.py """ 用于数据集下载和转换. """ from __future__ import absolute_import from __future__ import division from __future__ import print_function import os import sys import tarfile from six.moves import urllib import tensorflow as tf LABELS_FILENAME = 'labels.txt' def int64_feature(values): """Returns a TF-Feature of int64s. Args: values: A scalar or list of values. Returns: A TF-Feature. """ if not isinstance(values, (tuple, list)): values = [values] return tf.train.Feature(int64_list=tf.train.Int64List(value=values)) def bytes_feature(values): """Returns a TF-Feature of bytes. Args: values: A string. Returns: A TF-Feature. """ return tf.train.Feature(bytes_list=tf.train.BytesList(value=[values])) def float_feature(values): """Returns a TF-Feature of floats. Args: values: A scalar of list of values. Returns: A TF-Feature. """ if not isinstance(values, (tuple, list)): values = [values] return tf.train.Feature(float_list=tf.train.FloatList(value=values)) def image_to_tfexample(i…

论文阅读 - 基于CNN的年龄和性别分类
type: item
date: 2018-05-20T22:36:13+08:00
description: 论文：Age and Gender Classification using Convolutional Neural Networks - 2015. Multi-task Multi-label 类似问题.主要是针对年龄和性别分别建立分类问题，基于CaffeNet，年龄转化为 8 类别、性别为 2 分类问题，训练两个网络模型，实现原理较为直接简单.项目路径 - Caffe源码路径 - Caffe年龄分类网络结构 - 对应caffemodel性别分类网络结构 - 对应caffemodel1. 年龄和性别分类的CNN网络CNN的第一个应用是用于字符识别的LeNet5 网络. 随着GPU发展，训练数据的快速增长，用于图像分类的深度CNN网络显著提高了准确率. 随后，CNN成功应用于更多领域，如人体姿态估计、人脸关键点检测、语音识别及动作分类等. 这里将CNN网络用于年龄和性别分类任务.收集大型的、标签化的年龄和性别图像训练集有两种方式： 用户的个人注册信息，如出生日期和性别，往往是私人信息. 手工标注，繁琐且耗时. 现阶段，尚无该类型数据集. 针对小型图像数据集，机器学习方法易出现过拟合问题. 深度CNN网络方法由于其具有大量的模型参数，过拟合问题更加突出. 因此，过拟合问题需要慎重考虑.网络结构说明 Figure2. CNN网络结构例示. 网络包括 3 个卷积层，每一个卷积层后接一个 ReLU 和 Pooling 层. 此外，前两层采用LRN(local response normalization)归一化. 第一个卷积层是 96 个 7×7 fliters， 第二个卷积层是 256 个5×5 fliters，第三个和最后一个卷积层均是 384 个 3×3 fliters. 网络最后是两个全连接层，均是 512 个输出单元. 如Figure3. 主要是基于CaffeNet. 分类问题： 年龄分类: 8 类 age = "0 - 2" age = "4 - 6" age = "8 - 13" age = "15 - 20" age = "25 - 32" age = "38 - 43" age = "48 - 53" age = "60 -" 性别分类: 2 类 网络输入图片是从 256×256 中裁剪 227×227 大小，输出的全连接层后接 softmax layer，以估计各类的概率. 针对测试图片，概率最大的类即为预测结果.2. 联合训练年龄和性别分类网络根据对论文方法及其实现的学习，个人考虑，可以将年龄和性别分类问题转化为二标签多任务分类问题，即每张人脸图像均有两个标签——年龄和性别，训练数据格式为：# train.txt faceimg1.jpg 1 0 faceimg2.jpg 0 1 faceimg3.jpg 2 0 ... 具体操作可参考 - Caffe 实践 - Multi-label 多标签标注的训练与部署. - Caffe实践 - 多标签图片分类的训练与部署

Caffe 实践 - Multi-label 多标签标注的训练与部署
type: item
date: 2018-05-19T13:45:36+08:00
description: 采用 LMDB 读取图片数据和标签, 处理 multi-label 问题. 基于 ResNet101 backbone 网络 multi-task 输出 类似问题, 图像自动标注上一篇博文曾尝试过修改 Caffe ImageDataLayer 源码的方式来读取多个 labels - ImageMultilabelDataLayer [Caffe实践 - 多标签图片分类的训练与部署].修改源码的方式可能显得稍微有点繁琐, 毕竟需要重新编译.这里尝试了一种新的方式来进行多标签自动标注.与 [Caffe实践 - 多标签图片分类的训练与部署] 不同的是, 前者是以 Multi-task 的方式进行处理的,每一个 task 分别是一个label的分类问题. 而这里是以多标签标注方式进行的.1. 数据集1.1 数据格式转换数据形式如, images_labels.txt:img1.jpg 1 0 1 ... 0 img2.jpg 0 1 0 ... 1 img3.jpg 1 1 0 ... 0 ...... 每一行是一个数据样本, 其对应的 multilabels 为一个 01 向量的形式. 且所有的样本所对应的 multilabels 向量长度是相同的.可以类似于 [Caffe实践 - 多标签图片分类的训练与部署] 来读取 multilabels 数据.但这里采用了另外的一种方式:首先将数据转换为两个文件, 其内容格式分别为: imageslist.txt img1.jpg 2 img1.jpg 5 img1.jpg 3 ...... 每一行对应一个数据样本, 图片 + 标签labels数 的形式. labelslist.txt 1 0 1 ... 0 0 1 0 ... 1 1 1 0 ... 0 ...... 每一行对应与一个数据样本的 multilabels. 01 向量. 1.2 生成 lmdb 数据gen_label_lmdb.py:#! --*-- coding: utf-8 --*-- import numpy import argparse from caffe.proto import caffe_pb2 import lmdb def parse_args(): parser = argparse.ArgumentParser(description='End-to-end inference') parser.add_argument('--labels', dest='labels', help='label txt file', default=None, type=str ) parser.add_argument('--images', dest='images', help='image txt file, for keys of datum', default=None, type=str ) parser.add_argument('--lmdb', dest='lmdb', help='label lmdb file', default=None, type=str ) if len(sys.argv) == 1: parser.print_help() sys.exit(1) return parser.parse_args() def array_to_datum(arr, label=0): """ Converts a 3-dimensional array to datum. If the array has dtype uint8, the output data will be encoded as a string. Otherwise, the output data will be stored in float format. """ if arr.ndim != 3: raise ValueError('Incorrect array shape.') datum = caffe_pb2.Datum() datum.channels, datum.height, datum.width = arr.shape if arr.dtype == numpy.uint8: datum.data = arr.tostring() else: datum.float_data.extend(arr.flat) datum.label = label return datum if __name__ == '__main__': print 'Starting Generate lmdb' args = parse_args() labels_array = numpy.loadtxt(…

Caffe实践 - 多标签图片分类的训练与部署
type: item
date: 2018-05-19T13:38:10+08:00
description: 这里采用从图像直接读取图片数据和标签的方式进行多标签分类. 基于 VGG16 backbone 网络 修改 ImageDataLayer 读取图片和多标签数据 multi-task 输出 类似问题, 图像自动标注1. 问题描述假定每张图片具有 N 个标签(本文N=3)，分别为 label1, label2, label3,...,labelN. 数据集 train.txt 内容格式如下：img1.jpg 5 6 7 ... 8 img2.jpg 1 2 3 ... 6 img3.jpg 7 8 9 ... 10 ...... 以 train.txt 第一行为例， img1.jpg 为图像名，5 为在label1 所对应的索引，6 为在label2 所对应的索引，7 为在label3 所对应的索引，8 为 在labelN 所对应的索引(均为从 0 开始).2. 解决方案基于 Caffe 官方提供的 ImageDataLayer 只能读取单个 label，因此这里参考 ImageDataLayer 添加新的网络数据读取层 —— ImageMultilabelDataLayer.Caffe 添加网络数据层所涉及主要步骤如下： 添加 hpp 头文件，如 include/image_multilabel_data_layer.hpp 添加 cpp 实现文件，如 src/caffe/layers/image_multilabel_data_layer.cpp 添加 Layer 对应的类及其类涉及参数，在 src/caffe/proto/caffe.proto文件中 2.1 添加 image_multilabel_data_layer.hpp#ifndef CAFFE_IMAGE_MULTILABEL_DATA_LAYER_HPP_ #define CAFFE_IMAGE_MULTILABEL_DATA_LAYER_HPP_ #include <string> #include <utility> #include <vector> #include "caffe/blob.hpp" #include "caffe/data_transformer.hpp" #include "caffe/internal_thread.hpp" #include "caffe/layer.hpp" #include "caffe/layers/base_data_layer.hpp" #include "caffe/proto/caffe.pb.h" namespace caffe { /** * @brief Provides data to the Net from image files. * * TODO(dox): thorough documentation for Forward and proto params. */ template <typename Dtype> class ImageMultilabelDataLayer : public BasePrefetchingDataLayer<Dtype> { public: explicit ImageMultilabelDataLayer(const LayerParameter& param) : BasePrefetchingDataLayer<Dtype>(param) {} virtual ~ImageMultilabelDataLayer(); virtual void DataLayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top); virtual inline const char* type() const { return "ImageData"; } virtual inline int ExactNumBottomBlobs() const { return 0; } virtual inline int ExactNumTopBlobs() const { return 2; } protected: shared_ptr<Caffe::RNG> prefetch_rng_; virtual void ShuffleImages(); virtual void load_batch(Batch<Dtype>* batch); vector<std::pair<std::string, int *> > lines_; // string 对应 train.txt 中的图片名，int * 实现多label，其中各label间默认以空格隔离. int lin…

Caffe实践 - 单标签图片分类的训练与部署
type: item
date: 2018-05-18T17:35:32+08:00
description: 单标签图片分类是指, 每张图片只能有一个标签, 比如是狗, 或猫. 一般来说的图片分类就是单标签的. 这也是 CNN 成功最初很好解决的问题.1. 训练数据制作主要是生成 train.txt、 val.txt 和 test.txt 文件，使其内容格式为：image_name1 label1 image_name2 label2 image_name3 label3 ...... 如：img1.jpg 0 img2.jpg 0 img3.jpg 1 img4.jpg 1 img5.jpg 2 img6.jpg 2 ...... 2. 生成数据集的 lmdb主要是利用 caffe 里自带的 create_imagenet.sh 和 make_imagenet_mean.sh 脚本，主要修改的地方有： - create_imagenet.sh#!/usr/bin/env sh # Create the imagenet lmdb inputs # N.B. set the path to the imagenet train + val data dirs set -e EXAMPLE=/path/to/save/lmdb/ # 生成lmdb的保存路径 DATA=/path/to/tranorval/txt/ # train.txt, val.txt 所在路径 TOOLS=/path/to/caffe/build/tools # caffe 编译后的工具 TRAIN_DATA_ROOT=/path/to/images/train/ # train 图像数据集的根目录 VAL_DATA_ROOT=/path/to/images/val/ # val 图像数据集的根目录 # Set RESIZE=true to resize the images to 256x256. Leave as false if images have # already been resized using another tool. RESIZE=false ## 修改为 true，将图片尺寸统一为 256x256 if *RESIZE; then RESIZE_HEIGHT=256 RESIZE_WIDTH=256 else RESIZE_HEIGHT=0 RESIZE_WIDTH=0 fi if [ ! -d "*TRAIN_DATA_ROOT" ]; then echo "Error: TRAIN_DATA_ROOT is not a path to a directory: *TRAIN_DATA_ROOT" echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \ "where the ImageNet training data is stored." exit 1 fi if [ ! -d "*VAL_DATA_ROOT" ]; then echo "Error: VAL_DATA_ROOT is not a path to a directory: *VAL_DATA_ROOT" echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \ "where the ImageNet validation data is stored." exit 1 fi echo "Creating train lmdb..." GLOG_logtostderr=1 *TOOLS/convert_imageset \ --resize_height=*RESIZE_HEIGHT \ --resize_width=*RESIZE_WIDTH \ --shuffle \ *TRAIN_DATA_ROOT \ *DATA/train.txt \ *EXAMPLE/train_lmdb # 生成 train 的 lmdb, 可以修改名字 echo "Creating val lmdb..." GLOG_logtostderr=1 *TOOLS/convert_imageset \ --resize_height=*RESIZE_HEIGHT \ --resize_width=*RESIZE_WIDTH \ --shuffle \ *VAL_DATA_ROOT \ *DATA/val.txt \ *EXAMPLE/val_lmdb # 生成 val 的 lmdb, 可以修改名字 echo "Done." make_imagenet_mean.sh #!/usr/bin/env sh # C…