PaddlePaddle / PaddleHub

Awesome pre-trained models toolkit based on PaddlePaddle. (400+ models including Image, Text, Audio, Video and Cross-Modal with Easy Inference & Serving)【安全加固,暂停交互,请耐心等待】
https://www.paddlepaddle.org.cn/hub
Apache License 2.0
12.72k stars 2.08k forks source link

[BUG]多标签分类,有三个标签,最后的pre是什么东西 #326

Closed DC-Lin closed 4 years ago

DC-Lin commented 4 years ago

1)PaddleHub和PaddlePaddle版本:PaddleHub1.4.1,PaddlePaddle1.6.2 2)系统环境:Linux,python3.7版本

DC-Lin commented 4 years ago

hub.MultiLabelClassifierTask( feature, num_classes, feed_list, data_reader, startup_program=None, config=None, hidden_units=None, metrics_choices="default"): 关于hidden_units参数没有详细说明

Steffy-zxf commented 4 years ago

感谢反馈! hidden_units (list): MultiLabelClassifierTask最终的全连接层输出维度为[num_classes, 2],是属于各个标签的概率值。如设置num_classes=3,输出是[[0.1, 0.9], [0.7, 0.3],[0.2,0.8]]表示,属于第1个标签的概率是0.9,不属于第1个标签的概率是0.1;属于第2个标签的概率是0.3,不属于第2个标签的概率是0.7;属于第3个标签的概率是0.8,不属于第3个标签的概率是0.2; 在这个全连接层之前可以设置额外的全连接层,并指定它们的输出维度,例如hidden_units=[4,2]表示先经过一层输出维度为4的全连接层,再输入一层输出维度为2的全连接层,最后再拼接上输出维度为[num_classes, 2]的全连接层。

关于MultiLabelClassifierTask的详细信息可以参考 https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub-API:-MultiLabelClassifierTask

同时关于你说的pre含义,看输出不应该出现40,48,26之类的。预测输出应该是 输入样本是否含有该标签,“1”表示有,“0”表示没有。

关于多标签预测参考 https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.4/demo/multi_label_classification/run_predict.sh

DC-Lin commented 4 years ago

我在复现https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.4/demo/multi_label_classification/run_predict.sh的时候 输出的值依然是一串莫名的数字

Steffy-zxf commented 4 years ago

你的预测脚本方便分享吗?

DC-Lin commented 4 years ago

import paddlehub as hub from paddle.fluid.framework import switch_main_program import paddle.fluid as fluid import pandas as pd import numpy as np import codecs import csv hub.dataset.ChnSentiCorp() module = hub.Module(name="ernie_v2_eng_base") inputs, outputs, program = module.context( trainable=True, max_seq_len=128)

Download dataset and use MultiLabelReader to read dataset

dataset = hub.dataset.Toxic() reader = hub.reader.MultiLabelClassifyReader( dataset=dataset, vocab_path=module.get_vocab_path(), max_seq_len=128)

Setup feed list for data feeder

feed_list = [ inputs["input_ids"].name, inputs["position_ids"].name, inputs["segment_ids"].name, inputs["input_mask"].name ]

Construct transfer learning network

Use "pooled_output" for classification tasks on an entire sentence.

pooled_output = outputs["pooled_output"]

Select finetune strategy, setup config and finetune

strategy=hub.AdamWeightDecayStrategy( weight_decay=0.01, warmup_proportion=0.1, learning_rate=5e-5, lr_scheduler='linear_decay', optimizer_name='adam' )

Setup runing config for PaddleHub Finetune API

config = hub.RunConfig( use_cuda=True, num_epoch=1, batch_size=32, checkpoint_dir='args.checkpoint_dir', strategy=strategy)

Define a classfication finetune task by PaddleHub's API

multi_label_cls_task = hub.MultiLabelClassifierTask( data_reader=reader, feature=pooled_output, feed_list=feed_list, num_classes=dataset.num_labels, hidden_units=[128,10], config=config)

Finetune and evaluate by PaddleHub's API

will finish training, evaluation, testing, save model automatically

multi_label_cls_task.finetune_and_eval() data = [[d.text_a, d.text_b] for d in dataset.get_test_examples()[2:10]]

index = 0 run_states = multi_label_cls_task.predict(data=data) results = [run_state.run_results for run_state in run_states] for result in results:

get predict index

label_ids = []
for i in range(dataset.num_labels):
    label_val = np.argmax(result[i])
    label_ids.append(label_val)
print("%s\tpredict=%s" % (data[index][0], label_ids))
index += 1
Steffy-zxf commented 4 years ago

预测时,batch_size建议设置为1,

config = hub.RunConfig(
use_cuda=True,
batch_size=1,
checkpoint_dir='PATH/TO/CKPT',
strategy=strategy)

checkpoint_dir设置保持和finetune时设置一致。 同时,你的预测数据data = [[d.text_a, d.text_b] for d in dataset.get_test_examples()[2:10]] 是文本对?

DC-Lin commented 4 years ago

batch_size与任务无关的吧,只是速度问题吧, checkpoint_dir是我保存参数的位置 预测的是文本数据2到10行,输出的应该是对应的标签列表

Steffy-zxf commented 4 years ago

看上面的预测代码后处理是适合batch_size=1的情况。 paddlehub 1.5.0 版本predict接口增加了return_result参数,可以直接获得预测结果,省去了你写后处理代码。升级paddlehub 至 1.5.0,具体参考https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.5/demo/multi_label_classification/predict.py

DC-Lin commented 4 years ago

非常感谢! paddlehub是今天发布的1.5吗 是适用于现在github的文档吗

Steffy-zxf commented 4 years ago

最近两天刚发布1.5.0版本,适用于release/v1.5分支下文档。

DC-Lin commented 4 years ago

image 最终经过[num_classes]后的输出是sigmoid激活再经过二元交叉熵得到【num_classes,2]吗

Steffy-zxf commented 4 years ago

[num_classes, 2]是对上一全链接层进行num_classes次sigmoid激活得到的,损失是num_classes个二元交叉熵的叠加。具体实现参考 https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.5/paddlehub/finetune/task/classifier_task.py#L233

https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.5/paddlehub/finetune/task/classifier_task.py#L266

DC-Lin commented 4 years ago

bias_attr=fluid.ParamAttr( name="cls_outb%d" % i, initializer=fluid.initializer.Constant(0.)), act="softmax")) 这里用的不是softmax函数吗 我觉得很奇怪,怎么会用softmax

Steffy-zxf commented 4 years ago

输出层fc size=2,此时用softmax函数激活和用sigmoid激活作用相同。 https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.5/paddlehub/finetune/task/classifier_task.py#L249

DC-Lin commented 4 years ago

那网络结构是这样子的? image

Steffy-zxf commented 4 years ago

不是对输出层的各个神经元对应softmax进行激活,上一层所有的输出神经元再经过一层拥有2个神经元的全连接层softmax激活得到。具体网络实现参考代码:https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.5/paddlehub/finetune/task/classifier_task.py#L233

DC-Lin commented 4 years ago

image

Steffy-zxf commented 4 years ago

由于只是最后一层预测标签时使用的网络权重不同而已,其他的网络权重都是共享的,而且计算总loss时是各个标签对应的loss之和。所以本质上还是一个分类器。

DC-Lin commented 4 years ago

麻烦您了,最近在学习... image 只是一个这样的网络只会对整个句子输出0跟1的概率,怎么会输出一个句子的多个标签的概率. 如果最后一层预测标签时使用的网络权重不同而已,其他的网络权重都是共享的,那么在预测绝望的时候,就有可能没有预测出悲伤

Steffy-zxf commented 4 years ago

这是个循环,针对每一标签都会预测一次,这个样本是不是包含这个标签。可以参考代码,加深理解。

DC-Lin commented 4 years ago

image 老是报一些奇奇怪怪的错误paddlehub==1.5.0

Steffy-zxf commented 4 years ago

在加载模型hub.Module(name='ernie')之前,先用命令行!hub install ernie安装模型

Steffy-zxf commented 4 years ago

您好,此issue在近一个月内暂无更新,我们将于今天内关闭。若在关闭后您仍需跟进提问,可重新开启此问题。