惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
LangChain Blog
雷峰网
雷峰网
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
T
Tailwind CSS Blog
V
Visual Studio Blog
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 司徒正美
有赞技术团队
有赞技术团队
J
Java Code Geeks
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
Engineering at Meta
Engineering at Meta
B
Blog
Recent Announcements
Recent Announcements
C
Check Point Blog
MongoDB | Blog
MongoDB | Blog
GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
F
Full Disclosure
Microsoft Security Blog
Microsoft Security Blog
N
Netflix TechBlog - Medium
I
InfoQ
云风的 BLOG
云风的 BLOG
量子位
D
Docker
D
DataBreaches.Net
Vercel News
Vercel News
Blog — PlanetScale
Blog — PlanetScale
宝玉的分享
宝玉的分享
V
V2EX
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Y
Y Combinator Blog
美团技术团队
小众软件
小众软件
阮一峰的网络日志
阮一峰的网络日志
博客园 - 聂微东
B
Blog RSS Feed
MyScale Blog
MyScale Blog
月光博客
月光博客
T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
aimingoo的专栏
aimingoo的专栏
M
MIT News - Artificial intelligence
U
Unit 42
Google DeepMind News
Google DeepMind News

Lowin Li

IQuest-Coder-V1调研,NanobananaPro + Gemini3Pro生成 | Lowin Li Vibecoding 时代,程序员会消失吗?——从“全自动”到“半自动”的冷思考 | Lowin Li AzureOpenAI vs OpenAI | Lowin Li ChatGPT出圈的秘诀 | Lowin Li 人工反馈的强化学习 | Lowin Li Stable Diffusion的模型量化,降低内存75%、Streamlit的在线生成图片调试、docker服务部署 | Lowin Li 训练一个SentenceTransformer模型 | Lowin Li 8位混合精度矩阵乘法,小硬件跑大模型 | Lowin Li Constrained Beam Search | Lowin Li 盘点开源“Copilot”,do it yourself | Lowin Li 使用fastgpt提速huggingface的GPT文本生成模型 | Lowin Li docker启devpi服务 | Lowin Li DataMeasurementsTool介绍 | Lowin Li bigbird长文本预训练模型介绍 | Lowin Li Transformers仓库做语言生成的解码方法介绍 | Lowin Li 转载:人工智能能否实现? | Lowin Li 分享CML工具在github上的一个原创例子 | Lowin Li .li域名注册教程 | Lowin Li Transformers仓库解读之一DataCollator | Lowin Li
谁说torchtext不能做多标签任务 | Lowin Li
文章作者: Lowin Li · 2021-10-24 · via Lowin Li

背景

最近刷到一篇博客,吐槽torchtext不能做多标签任务,特来为torchtext鸣不平,看好,我要用torchtext做多标签任务了。

简要

  • 解读
    • torchtext库,做多标签任务
  • 实践
  • 运行
    • githubaction中,完成全程训练、批测,结果报告通过cml工具发送至commit评论

解读

  • 如何用torchtext库,做多标签任务

读取数据

顾名思义,多标签任务像是不定项选择题,是一条样本对应一个或多个标签,也可以没有对应标签,所以标注字段不能再用sequential=False参数,要对标注列进行切分,源码中的注释说明:

sequential: Whether the datatype represents sequential data. If False, no tokenization is applied. Default: True.

写入标签数据
  • <pad>表示占位符没有任何意义
echo -e "label\n汽车&&银行\n汽车&&天气\n天气\n<pad>\n咖啡" > label.tsv
字段设置

&&切分标注标签,那么可以这样写:

label = torchtext.data.Field(
    tokenize=lambda x: x.split("&&"), unk_token=None
    )
读取Dataset
dataset = torchtext.data.TabularDataset(
            path="label.tsv",
            format="tsv",
            skip_header=True,
            fields=[("label", label)],
        )
print(dataset.examples[0].__dict__)
print(dataset.examples[1].__dict__)
print(dataset.examples[2].__dict__)
print(dataset.examples[3].__dict__)
print(dataset.examples[4].__dict__)

{‘label’: [‘汽车’, ‘银行’]}
{‘label’: [‘汽车’, ‘天气’]}
{‘label’: [‘天气’]}
{‘label’: [“<pad>“]}
{‘label’: [“咖啡”]}

建立标签id映射表
label.build_vocab(dataset)
with open("label_dict.json", "w") as f:
    json.dump(
        dict(label.vocab.stoi),
        f,
        indent=4,
        ensure_ascii=False
    )
print(label.vocab.stoi)

{‘<pad>‘: 0, ‘天气’: 1, ‘汽车’: 2, ‘咖啡’: 3, ‘银行’: 4}

读取Iterator
train_iter = torchtext.data.BucketIterator(
        dataset,
        device="cpu",
        repeat=False,
        batch_size=2,
        sort=False,
        shuffle=True,
    )
for batch in train_iter:
    print(batch.label)
# 注意这里每一列是一个样本
tensor([[2],
        [4]])  # 汽车、银行;
tensor([[2, 1],
        [1, 0]]) # 汽车、天气;天气、<pad>
tensor([[3, 0]]) # 咖啡;<pad>

损失函数

  • 多分类任务相当于单选题,每个标签是互斥的,预测整个logits在这个标签体系上做softmax,然后计算交叉熵损失函数;
  • 多标签任务相当于不定项选择题,每个标签是独立的,每个标签位置的logit做sigmoid,然后单独计算交叉熵损失函数,然后再求和;
  • pytorch已经包装好多标签任务的损失函数BCEWithLogitsLoss
torch.nn.BCEWithLogitsLoss

标注标签转onehot格式

  • 当前从生成器BucketIterator出来的batch数据,是标签id,需要把它映射成onehot格式便于计算Loss
def multi_label_metrics_transfer(self, y, label_num):
    """
    输入 torchtext 的多分类标签体系,0表示占位符没有意义
    tensor([[1, 1, 1, 2, 1, 1, 1, 1, 1],
            [2, 3, 2, 1, 0, 2, 2, 0, 2],
            [0, 0, 3, 0, 0, 0, 0, 0, 0]])
    输出 onehot多标签矩阵
    tensor([[1., 1., 0.],
            [1., 0., 1.],
            [1., 1., 1.],
            [1., 1., 0.],
            [1., 0., 0.],
            [1., 1., 0.],
            [1., 1., 0.],
            [1., 0., 0.],
            [1., 1., 0.]])
    """
    return torch.zeros(
        y.shape[1],
        label_num,
        dtype=torch.float,
        device=self.config.device,
    ).scatter_(
        1,
        y.T,
        torch.ones(
            y.shape[1],
            label_num,
            dtype=torch.float,
            device=self.config.device,
        ),
    )[
        :, 1:
    ]

实践

统计

数据项目 统计值
训练集单条jieba分词个数均值 31.63
训练集单条jieba分词个数98%分位 101
训练集条数 11958
验证集条数 1498
jieba分词去重个数 40113
标签个数 65

因此模型最大长度设置100

词向量sgns_百度.pt是来自词向量sgns.merge.word中,训练集出现过的词汇、以及原词向量中词频最高的前10000个词

运行

详见笔者仓库,以及仓库actionscml报告

参考致谢

  1. 百度事件标签竞赛
  2. cml
  3. cml.dev
  4. onnx
  5. textcnn
  6. word2vec