多标签分类任务-服装分类

Multi-Label Classification

首先分清一下multiclass和multilabel:

  • 多类分类(Multiclass classification): 表示分类任务中有多个类别, 且假设每个样本都被设置了一个且仅有一个标签。比如从100个分类中击中一个。
  • 多标签分类(Multilabel classification): 给每个样本一系列的目标标签,即表示的是样本各属性而不是相互排斥的。比如图片中有很多的概念如天空海洋人等等,需要预测出一个概念集合。

Challenge

多标签任务的难度主要集中在以下问题:

  • 标签数量较大且基本会呈现长尾形态。
  • 往往类标之间相互依赖并不独立。
  • absence标签占比较高,即标注的标签并不能完美覆盖所有概念面。
  • 标签往往较短语义少,理解困难。

Solution

现有的方法应对multi的预测主要有2大路线:

  • 改造数据适应算法:将多个类别合并成单个类别。
  • 改造算法适应数据:控制激活函数阈值得到结果。

而一般研究最多的应对relation会有3种策略:
一阶策略:忽略和其它标签的相关性,比如把多标签分解成多个独立的二分类问题。
二阶策略:考虑标签之间的成对关联,比如为相关标签和不相关标签排序。
高阶策略:考虑多个标签之间的关联,比如对每个标签考虑所有其它标签的影响。

Densenet

在这里插入图片描述

它的基本思路与ResNet一致,但是它建立的是前面所有层与后面层的密集连接(dense connection),它的名称也是由此而来。DenseNet的另一大特色是通过特征在channel上的连接来实现特征重用(feature reuse)。这些特点让DenseNet在参数和计算成本更少的情形下实现比ResNet更优的性能,DenseNet也因此斩获CVPR 2017的最佳论文奖。

DenseBlock

在这里插入图片描述
相比ResNet,DenseNet提出了一个更激进的密集连接机制:即互相连接所有的层,具体来说就是每个层都会接受其前面所有层作为其额外的输入。图1为ResNet网络的连接机制,作为对比,图2为DenseNet的密集连接机制。可以看到,ResNet是每个层与前面的某层(一般是2~3层)短路连接在一起,连接方式是通过元素级相加。而在DenseNet中,每个层都会与前面所有层在channel维度上连接(concat)在一起(这里各个层的特征图大小是相同的,后面会有说明),并作为下一层的输入。对于一个 L 层的网络,包含个连接,相比ResNet,这是一种密集连接。而且DenseNet是直接concat来自不同层的特征图,这可以实现特征重用,提升效率,这一特点是DenseNet与ResNet最主要的区别。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

整体网络结构

在这里插入图片描述
CNN网络一般要经过Pooling或者stride>1的Conv来降低特征图的大小,而DenseNet的密集连接方式需要特征图大小保持一致。为了解决这个问题,DenseNet网络中使用DenseBlock+Transition的结构,其中DenseBlock是包含很多层的模块,每个层的特征图大小相同,层与层之间采用密集连接方式。而Transition模块是连接两个相邻的DenseBlock,并且通过Pooling使特征图大小降低。上图给出了DenseNet的网络结构,它共包含3个DenseBlock,各个DenseBlock之间通过Transition连接在一起。Transition层包括一个1x1的卷积和2x2的AvgPooling,结构为BN+ReLU+1x1 Conv+2x2 AvgPooling。另外,Transition层可以起到压缩模型的作用。

在这里插入图片描述

原论文实验结果

在这里插入图片描述
综合来看,DenseNet的优势主要体现在以下几个方面:

  • 由于密集连接方式,DenseNet提升了梯度的反向传播,使得网络更容易训练。由于每层可以直达最后的误差信号,实现了隐式的“deep supervision”;
  • 参数更小且计算更高效,这有点违反直觉,由于DenseNet是通过concat特征来实现短路连接,实现了特征重用,并且采用较小的growth rate,每个层所独有的特征图是比较小的;
  • 由于特征复用,最后的分类器使用了低级特征。

服装多标签分类小实验

数据划分

总数据量:5547
训练(4993):测试(554) = 9 :1


def read_split_data(root: str, test_rate: float = 0.1):
    random.seed(0)  # 保证随机结果可复现
    assert os.path.exists(root), "dataset root: {} does not exist.".format(root)

    # 拿到所有类别
    class_ = set()
    for cla in os.listdir(root):
        class_.add(cla.split('_')[0])
        class_.add(cla.split('_')[1])
    class_ = list(class_)
    class_.sort()

    # 建立类别索引并存储
    class_indices = dict((k, v) for v, k in enumerate(class_))
    json_str = json.dumps(dict((val, key) for key, val in class_indices.items()), indent=4)
    with open('class_indices.json', 'w') as json_file:
        json_file.write(json_str)

    # 读取所有图像路径和对应类别索引
    train_images_path = []  # 存储训练集的所有图片路径
    train_images_label = []  # 存储训练集图片对应索引信息
    val_images_path = []  # 存储验证集的所有图片路径
    val_images_label = []  # 存储验证集图片对应索引信息
    supported = [".jpg", ".JPG", ".png", ".PNG"]  # 支持的文件后缀类型

    # onehot编码形式表示出每张图像的label
    images_path_and_onehot = {}
    for dir_ in os.listdir(root):
        for img_name in os.listdir(os.path.join(root, dir_)):
            image_path = os.path.join(root, dir_, img_name)
            onehot_class = [0] * 9
            # print(str(image_path), str(image_path).split('\\'))
            class0, class1 = str(image_path).split('\\')[-2].split('_')[0], image_path.split('\\')[-2].split('_')[1]
            idx0, idx1 = class_indices[class0], class_indices[class1]
            onehot_class[idx0], onehot_class[idx1] = 1, 1
            images_path_and_onehot[image_path] = onehot_class

    # 随机抽取相应比例的数据作为测试集
    test_path = random.sample(list(images_path_and_onehot), k=int(len(list(images_path_and_onehot)) * test_rate))

    # 分别存储训练和测试的图像路径及其对应onehot标签
    for image_path in images_path_and_onehot.keys():
        if image_path in test_path:  # 如果该路径在采样的验证集样本中则存入验证集
            val_images_path.append(image_path)
            val_images_label.append(images_path_and_onehot[image_path])
        else:  # 否则存入训练集
            train_images_path.append(image_path)
            train_images_label.append(images_path_and_onehot[image_path])


    print("{} images were found in the dataset.".format(len(images_path_and_onehot.keys())))
    print("{} images for training.".format(len(train_images_path)))
    print("{} images for validation.".format(len(val_images_path)))

    return train_images_path, train_images_label, val_images_path, val_images_label

模型

  • 使用densenet121网络,
  • loss函数:二值交叉熵
  • pretrain:imagenet 1000k
  • lr: 0.0001
  • epoches: 50(实际跑42epoch就收敛了)
  • scheduler:余弦衰减

loss

在这里插入图片描述

结果评估

在这里插入图片描述
部分测试图像预测可视化:
在这里插入图片描述

【参考】
https://zhuanlan.zhihu.com/p/37189203
https://nakaizura.blog.csdn.net/article/details/114753747?spm=1001.2014.3001.5506

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
PHPOK系统(下述简称OK系统)是由深圳锟铻科技有限公司(前身是PHPOK工作室)开发的一套针对网站建设的内容管理系统,采用 PHP 语言编写,默认使用 MySQL 数据库存储,基于 LGPL 开源协议授权发布到网上共享使用。 PHPOK系统特色: 项目 这是系统比较有特别味道的一个功能,有类似的CMS系统又称之为“页面”,这一块也是系统的核心,也就是说,我们的系统前端所有功能都是围绕着它来转。 绑定模块,实现列表+详细页(如新闻列表+新闻详细页) 不绑定模块,实现单页面模式,当然,这基本上是需要配合【自定义扩展字段】使用 自身扩展字段,页面读取项目信息时,可以输出相应的扩展,以满足各种需求 可以关联分类,实现列表+分类+详细的扩展 可以开启电商,实现电子商务功能 可以定义后台及前台基本权限 【通俗的说】假定有一个超市(本系统),一般会对超市分区操作,例如说副食品区,生鲜区,水果区,服装区等等。项目功能在本系统也是有类似的功能! 模块 基本上来讲,绝大多数的CMS都有这个功能,叫法不一。在本系统中,模块只有一个功能:服务项目。例如:我们的网站中基本上都有新闻,产品,友情链接这几个项目(页面),各自呈现的内容不一样,模块就是为了区分管理而服务。 【通俗的说】逛超市时,逛到服装区,给客服呈现给客户: 我们要卖衣服,那可以很肯定的衣服不是一件,是有很多件(这就是模块,用于存放多条数据) 为了方便客户对比各个衣服有什么特色,会在标签上放一些参数(类似模块上的字段信息) 分类 所有CMS系统都有这个功以有,在本系统中,分类的主要任务是对同一个模块的数据进行整理归纳,特别说明一下,系统的分类可以对自身数据进行扩展,以满足用户定制需求。 【通俗的说】这次我们拿超市的副食品区来说,副食品就是非主食,一般是经过精加工的食品。如何管理是一个大的问题,怎么办,我们可以再次分门别类来处理!比如基于荤素生熟,再细分下来可以分成食糖、糖果、罐头、茶叶、调味品、乳制品、蜜制品、豆制品、饮料、饼干、糕点、小食品以及烟、酒、果品等等,分类的作用亦是如此 首页 就是输入网址默认访问进来的一个页面,这是一个特殊的项目,后台可以针对这个建一个项目标识为 index 的项目信息,也可以不建。首页的一个特点就是:所有首页的上数据都是通过调用获取的,我们可以简单的理解为它本身不生产数据不存储数据。 【通俗的说】首页就像超市的入口,入口为了吸引人继续走进去,会放一些好看的产品宣传信息,促销信息,等等。 会员及会员组 基本上来讲任意平台都有包含这个功能,在本系统中,除了有基本功能外,我们还直持会员数据自定义扩展字段功能!只需要一开始预设好,就可以无限量的增加自己需要的字段。 【通俗的说】会员信息就像超市的顾客,会员组就是超市为方便管理,将顾客信息进行归纳整理 财富 类似其他平台的积分系统,与其他平台不大一样的是,本系统支持的财富方案是要可以自己扩展的!包括积分,威望,信用值等等,都是可以自己的!甚至更大胆点,可以创建钱包功能,实在站点的充值及消费功能(在配置中启用充值功能+抵现功能) 推荐人 本系统支持简单的推荐人功能,配合财富功能实现推荐人获取积分。 购物车及订单 系统有完善的一整套购物车功能,也有一整套完善的订单系统,可以实现网站的基本电商功能。特别说明,本系统支持游客下单,就像超市一样,不办理会员也可以购物。 支持外币 本系统支持多国货币,当然,货币的汇率是需要人工设置的(暂时不支持实时汇率) 支付 支持接入支付宝,微信支付,Paypal,银联支付等(用户有需要定制也可以联系我们) 快递物流 支持接入快递物流远程查询,实时了解快递进度 运费 是的,我们程序内置了四种运费计算,分别是基于重量,体积,数量,固定。这四种计算方式绝大多数能满足要求了,如有需求定制,可以联系我们噢 小程序 对了,最新版的程序已经内置小程序风格了,只要将wxapp 目录移进来,调整 app.js 里的两个参数,就可以拥有一套自己的小程序系统了,一样是开源的! 评论 又称回复,在最新版本中,这个功能支持图片,支持星级(1-5星),支持管理员多次回复 全局配置 又称站点信息配置,除了系统内置的功能参数外,系统也支持自己扩展噢,功能很强大,但不要把什么东西都往这里扔噢,因为这一块是前台任意页面都可以直接读取的信息 报表统计 支持查看到的统计报表有:1会员注册情况,2订单销售情况,包括查看订单周销售,月销售,年销售情况。3 财富增长情况。4 主题内容的月增长情况 等等 多站点多语言 实现一个后台管理多个网站,文件共用,图片共用。   PHPOK更新日志: v6.0 老用户只需在后台升级到 PHPOK 5.8 即可! 这里说明一下,PHPOK5.8 和 PHPOK6.0 区别: 前台逻辑不一样,其他的完全

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shashank497

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值