我正在尝试为句子分类任务训练模型。输入是一个句子(整数向量),输出是一个标签(0 或 1)。我在这里和那里看到了一些关于使用 Bert 和 GPT2 进行文本分类任务的文章。但是,我不确定应该从哪一个开始。您会使用 NLP 中的哪些最新模型(例如原始 Transformer 模型、Bert、GPT2、XLNet)开始?为什么?我更愿意在 Tensorflow 中实现,但我也可以灵活地使用 PyTorch。谢谢!
该HuggingFace BERT TensorFlow实施使我们能够进在预先计算的地方嵌入查找是原产于BERT的嵌入。这是使用模型call方法的可选参数inputs_embeds(代替input_ids)完成的。为了测试这一点,我想确保如果我确实输入了 BERT 的嵌入查找,我会得到与输入input_ids它们自己相同的结果。
BERT 嵌入查找的结果可以通过将 BERT 配置参数设置output_hidden_states为True并从该call方法的最后一个输出中提取第一个张量来获得。(其余 12 个输出对应于 12 个隐藏层中的每一个。)
因此,我编写了以下代码来测试我的假设:
import tensorflow as tf
from transformers import BertConfig, BertTokenizer, TFBertModel
bert_tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
input_ids = tf.constant(bert_tokenizer.encode("Hello, my dog is cute", add_special_tokens=True))[None, :]
attention_mask = tf.stack([tf.ones(shape=(len(sent),)) for sent in input_ids])
token_type_ids = tf.stack([tf.ones(shape=(len(sent),)) for sent in input_ids])
config = BertConfig.from_pretrained('bert-base-uncased', output_hidden_states=True)
bert_model = TFBertModel.from_pretrained('bert-base-uncased', config=config)
result = bert_model(inputs={'input_ids': input_ids, …Run Code Online (Sandbox Code Playgroud) python nlp tensorflow bert-language-model huggingface-transformers
BERT 输出不是确定性的。当我输入相同的输入时,我希望输出值是确定性的,但是我的 bert 模型中的值正在发生变化。听起来很尴尬,相同的值被返回两次,一次。也就是说,一旦出现另一个值,就会出现相同的值并重复。如何使输出具有确定性?让我展示我的代码片段。我使用的模型如下。
对于 BERT 实现,我使用了 Huggingface 实现的 BERT pytorch 实现。这是 pytorch 领域非常有名的模型 ri 实现。[链接] https://github.com/huggingface/pytorch-pretrained-BERT/
tokenizer = BertTokenizer.from_pretrained(self.bert_type, do_lower_case=self.do_lower_case, cache_dir=self.bert_cache_path)
pretrain_bert = BertModel.from_pretrained(self.bert_type, cache_dir=self.bert_cache_path)
bert_config = pretrain_bert.config
Run Code Online (Sandbox Code Playgroud)
得到这样的输出
all_encoder_layer, pooled_output = self.model_bert(all_input_ids, all_segment_ids, all_input_mask)
# all_encoder_layer: BERT outputs from all layers.
# pooled_output: output of [CLS] vec.
Run Code Online (Sandbox Code Playgroud)
pooled_output
tensor([[-3.3997e-01, 2.6870e-01, -2.8109e-01, -2.0018e-01, -8.6849e-02,
tensor([[ 7.4340e-02, -3.4894e-03, -4.9583e-03, 6.0806e-02, 8.5685e-02,
tensor([[-3.3997e-01, 2.6870e-01, -2.8109e-01, -2.0018e-01, -8.6849e-02,
tensor([[ 7.4340e-02, -3.4894e-03, -4.9583e-03, 6.0806e-02, 8.5685e-02,
Run Code Online (Sandbox Code Playgroud)
对于所有编码器层,情况是相同的, - 一次两次相同。
我从bert中提取词嵌入特征,情况是一样的。
wemb_n
tensor([[[ 0.1623, 0.4293, …Run Code Online (Sandbox Code Playgroud) 我在将 Bert 嵌入层集成到 BiLSTM 模型中以进行词义消歧任务时遇到问题,
Windows 10
Python 3.6.4
TenorFlow 1.12
Keras 2.2.4
No virtual environments were used
PyCharm Professional 2019.2
Run Code Online (Sandbox Code Playgroud)
整个剧本
import os
import yaml
import numpy as np
from argparse import ArgumentParser
import tensorflow as tf
import tensorflow_hub as hub
from tensorflow.keras.layers import (LSTM, Add, Bidirectional, Dense, Input, TimeDistributed, Embedding)
from tensorflow.keras.preprocessing.sequence import pad_sequences
try:
from bert.tokenization import FullTokenizer
except ModuleNotFoundError:
os.system('pip install bert-tensorflow')
from tensorflow.keras.models import Model
from tensorflow.keras import backend as K
from tqdm import tqdm …Run Code Online (Sandbox Code Playgroud) python keras tensorflow recurrent-neural-network bert-language-model
我正在尝试BertForSequenceClassification一个简单的文章分类任务。
无论我如何训练它(冻结除分类层之外的所有层,所有层均可训练,最后k一层可训练),我总是得到几乎随机的准确度分数。我的模型训练准确率不超过 24-26%(我的数据集中只有 5 个类)。
我不确定在设计/训练模型时我做错了什么。我用多个数据集尝试了该模型,每次它都给出相同的随机基线精度。
我使用的数据集:BBC 文章(5 类)
https://github.com/zabir-nabil/pytorch-nlp/tree/master/bbc
包含来自 BBC 新闻网站的 2225 份文档,对应 2004 年至 2005 年五个主题领域的故事。自然课程:5(商业、娱乐、政治、体育、科技)
我添加了模型部分和训练部分,这是最重要的部分(以避免任何不相关的细节)。如果这对再现性有用,我也添加了完整的源代码+数据。
我的猜测是我设计网络的方式或者我将注意力掩码/标签传递给模型的方式有问题。此外,令牌长度 512 应该不是问题,因为大多数文本的长度 < 512(平均长度 < 300)。
型号代码:
import torch
from torch import nn
class BertClassifier(nn.Module):
def __init__(self):
super(BertClassifier, self).__init__()
self.bert = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels = 5)
# as we have 5 classes
# we want our output as probability so, in the evaluation mode, we'll pass the logits to a softmax layer
self.softmax = torch.nn.Softmax(dim = …Run Code Online (Sandbox Code Playgroud) 有没有最新的预训练多语言词嵌入(多种语言联合映射到同一个向量空间)?
我查看了以下内容,但它们不符合我的需求:
这是我试图解决的问题:
我有一个公司名称列表,可以是任何语言(主要是英语),并且我有一个英文关键字列表,用于衡量给定公司名称与关键字的接近程度。现在我有一个简单的关键字匹配解决方案,但我想使用预训练的嵌入来改进它。正如您在以下示例中看到的,存在几个挑战:
公司名称示例:“cheapfootball ltd.”、“wholesalefootball ltd.”、“footballer ltd.”、“soccershop ltd.”
关键词示例:“足球”
nlp word-embedding pre-trained-model fasttext bert-language-model
当我使用时(带有长 test_text 和短问题):
from transformers import BertTokenizer
import torch
from transformers import BertForQuestionAnswering
tokenizer = BertTokenizer.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad')
model = BertForQuestionAnswering.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad')
input_ids = tokenizer.encode(question, test_text)
print('Query has {:,} tokens.\n'.format(len(input_ids)))
sep_index = input_ids.index(tokenizer.sep_token_id)
num_seg_a = sep_index + 1
num_seg_b = len(input_ids) - num_seg_a
segment_ids = [0]*num_seg_a + [1]*num_seg_b
start_scores, end_scores = model(torch.tensor([input_ids]),
token_type_ids=torch.tensor([segment_ids]))
Run Code Online (Sandbox Code Playgroud)
我收到输出错误
令牌索引序列长度长于该模型指定的最大序列长度 (3 > 512)。通过模型运行此序列将导致索引错误
查询有 1,244 个标记。
如何将 test_text 分成最大长度的块,并且知道它不会超过 512 个标记?然后对每个文本块提出相同的问题,从所有文本中取出最佳答案,并使用不同的切片点对文本进行两次检查,以防答案在切片期间被剪切。
python tokenize python-3.x bert-language-model huggingface-transformers
我正在使用 Huggingface BERT 来执行 NLP 任务。我的文本包含被分成子词的公司名称。
tokenizer = BertTokenizerFast.from_pretrained('bert-base-uncased')
tokenizer.encode_plus("Somespecialcompany")
output: {'input_ids': [101, 2070, 13102, 8586, 4818, 9006, 9739, 2100, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}
Run Code Online (Sandbox Code Playgroud)
现在,我想将这些名称添加到标记器 ID 中,这样它们就不会被分割。
tokenizer.add_tokens("Somespecialcompany")
output: 1
Run Code Online (Sandbox Code Playgroud)
这将分词器的长度从 30522 扩展到 30523。
因此,所需的输出将是新的 ID:
tokenizer.encode_plus("Somespecialcompany")
output: 30522
Run Code Online (Sandbox Code Playgroud)
但输出与之前相同:
output: {'input_ids': [101, 2070, 13102, 8586, 4818, 9006, 9739, 2100, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, …Run Code Online (Sandbox Code Playgroud) bert-language-model huggingface-transformers huggingface-tokenizers
我的代码是:
import torch
from transformers import BertTokenizer
from IPython.display import clear_output
Run Code Online (Sandbox Code Playgroud)
我在行中遇到错误from transformers import BertTokenizer:
ImportError: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /mnt/home/wbj/anaconda3/envs/pytorch/lib/python3.8/site-packages/tokenizers/tokenizers.cpython-38-x86_64-linux-gnu.so)
Run Code Online (Sandbox Code Playgroud)
我找到了一个答案,问题是由于文件引起的/lib/x86_64-linux-gnu/libm.so.6,当我使用代码时,strings /lib/x86_64-linux-gnu/libm.so.6 | grep GLIBC_我得到了输出
GLIBC_2.2.5
GLIBC_2.4
GLIBC_2.15
GLIBC_2.18
GLIBC_2.23
GLIBC_PRIVATE
Run Code Online (Sandbox Code Playgroud)
该文件不支持 GLIBC_2.29。我该如何解决这个问题?
我训练了一个基于 BERT 的编码器解码器模型 ( EncoderDecoderModel),ed_model并以 HuggingFace 的 Transformers 模块命名。
我用的BertTokenizer是命名为input_tokenizer
我用以下方法标记了输入:
txt = "Some wonderful sentence to encode"
inputs = input_tokenizer(txt, return_tensors="pt").to(device)
print(inputs)
Run Code Online (Sandbox Code Playgroud)
输出清楚地表明 ainput_ids是返回字典
{'input_ids': tensor([[ 101, 5660, 7975, 2127, 2053, 2936, 5061, 102]], device='cuda:0'), 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0]], device='cuda:0'), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1]], device='cuda:0')}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试预测时,我收到此错误:
ed_model.forward(**inputs)
ValueError:您必须指定 input_ids 或 input_embeds
有任何想法吗 ?
nlp ×4
python ×4
tensorflow ×3
fasttext ×1
importerror ×1
keras ×1
python-3.x ×1
pytorch ×1
tokenize ×1