Closed ykallan closed 1 year ago
以下为训练、测试数据集样本
美 B-BRAND
汁 I-BRAND
源 I-BRAND
_ O
果 O
粒 O
橙 O
_ O
1 B-SPECS
. I-SPECS
2 I-SPECS
5 I-SPECS
l I-SPECS
/ I-SPECS
瓶 I-SPECS
_ O
1 O
2 O
瓶 O
/ O
箱 O
_ O
整 O
箱 O
销 O
售 O
万 B-BRAND
宝 I-BRAND
龙 I-BRAND
( O
M O
O O
N O
T O
_ O
B O
L O
A O
N O
C O
) O
大 O
班 O
系 O
列 O
1 B-MODEL
4 I-MODEL
5 I-MODEL
墨 O
水 O
笔 O
我看了下你的代码,你labels处理的时候把O去掉了啊,我的理解这样就labels的长度就和token_ids不一样了吧
labels = [categories_id2label.get(x)[2:] for x in predict if categories_id2label.get(x)[2:] != "O"]
我看了下你的代码,你labels处理的时候把O去掉了啊,我的理解这样就labels的长度就和token_ids不一样了吧
labels = [categories_id2label.get(x)[2:] for x in predict if categories_id2label.get(x)[2:] != "O"]
修改推理的方法为:
def inference(text, maxlen=64, threshold=0):
model.eval()
text = text.replace(" ", "_").strip()
token_ids, segment_ids = tokenizer.encode(text, maxlen=len(text))
token_ids = torch.tensor(token_ids, dtype=torch.long, device=device)[None, :]
segment_ids = torch.tensor(segment_ids, dtype=torch.long, device=device)[None, :]
scores = model.predict(token_ids)
scores = scores.cpu().numpy()
print(scores)
print(list(scores[0]))
predict = list(scores[0])
# labels = [categories_id2label.get(x)[2:] for x in predict if categories_id2label.get(x)[2:] != "O"]
labels = []
for x in predict:
lab = categories_id2label.get(x)
if len(lab) > 2:
lab = lab[2:]
labels.append(lab)
print(labels)
text = text.replace("_", " ")
print("len of text=", len(text))
print("len of labels=", len(labels))
for char, label in zip(text, labels):
print(char, label)
得到的输出:
input text:海斯迪克 HKL-186 食品留样盒包装盒幼儿园学校保险取样盒 六格连体(送30标签)
[[0 1 2 2 2 0 3 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 6 6 6 6 6
6 6 6 6 0]]
[0, 1, 2, 2, 2, 0, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0]
['O', 'BRAND', 'BRAND', 'BRAND', 'BRAND', 'O', 'MODEL', 'MODEL', 'MODEL', 'MODEL', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'SPECS', 'SPECS', 'SPECS', 'SPECS', 'SPECS', 'SPECS', 'SPECS', 'SPECS', 'SPECS', 'SPECS', 'O']
len of text= 43
len of labels= 41
海 O
斯 BRAND
迪 BRAND
克 BRAND
BRAND
H O
K MODEL
L MODEL
- MODEL
1 MODEL
8 O
6 O
O
食 O
品 O
留 O
样 O
盒 O
包 O
装 O
盒 O
幼 O
儿 O
园 O
学 O
校 O
保 O
险 O
取 O
样 O
盒 SPECS
SPECS
六 SPECS
格 SPECS
连 SPECS
体 SPECS
( SPECS
送 SPECS
3 SPECS
0 SPECS
标 O
还是对应不上,不知道是否因为加上了掩码导致文本和预测的标签长度不一致
你先比较下token_ids和labels是否长度一致,我怀疑是tokenize时候有问题,不要传入maxlen,因为默认会添加cls和sep,你这样应该会截断掉两个
token_ids, segment_ids = tokenizer.encode(text)
你最好是debug看一下,默认tokenize后是[CLS]+sentence+[SEP]的,你输出的时候要对应一下
你最好是debug看一下,默认tokenize后是[CLS]+sentence+[SEP]的,你输出的时候要对应一下
好的谢谢,我debug看一下
利用mapping再把预测出来的起止位置映射到原始文本的位置上
mapping = tokenizer.rematch(d[0], tokens)
start_mapping = {i: j[0] for i, j in enumerate(mapping) if j}
end_mapping = {i: j[-1] for i, j in enumerate(mapping) if j}
for index, start, end, label in trans_entity2tuple(scores):
if start in start_mapping and end in end_mapping:
start = start_mapping[start]
end = end_mapping[end]
提问时请尽可能提供如下信息:
基本信息
训练代码
推理代码
输出信息
自我尝试
输入模型的字符串长度,与得到的推理标签长度不同,并且也无法对应相同数量,目前没找到具体问题出在哪里