精华内容
下载资源
问答
  • 主要是调用bert实现词向量的转换,生成新的词向量,之后将词向量作为入参对接其他的模型
  • Bert词向量 Bert本质上是一个两段式的NLP模型。第一个阶段:Pre-training,跟WordEmbedding类似,利用现有无标记的语料训练一个语言模型。第二个阶段:Fine-tuning,利用预训练好的语言模型,完成具体的NLP下游任务...

    一、Word2Vec词向量

    1.分词

    ①经典工具

    ②方法比较

    2.训练

    ①使用Word2Vec

    • 安装模块
    pip install word2vec
    
    • 构建词向量
    import word2vec
    word2vec.word2vec('corpusSegDone.txt', 'corpusWord2Vec.bin', size=300, verbose=True)
    
    • 显示并使用词向量

    ②使用gensim

    • 安装模块
    pip install gensim
    
    import logging
    import multiprocessing
    import os.path
    import sys
    import jieba
    
    from gensim.models import Word2Vec
    from gensim.models.word2vec import PathLineSentences
    
    if __name__ == '__main__':
        
        # 日志信息输出
        program = os.path.basename(sys.argv[0])
        logger = logging.getLogger(program)
        logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
        logging.root.setLevel(level=logging.INFO)
        logger.info("running %s" % ' '.join(sys.argv))
        
        # check and process input arguments
        # if len(sys.argv) < 4:
        #     print(globals()['__doc__'] % locals())
        #     sys.exit(1)
        # input_dir, outp1, outp2 = sys.argv[1:4]
        
        input_dir = 'segment'
        outp1 = 'baike.model'
        outp2 = 'word2vec_format'
        fileNames = os.listdir(input_dir)
        # 训练模型 
        # 输入语料目录:PathLineSentences(input_dir)
        # embedding size:256 共现窗口大小:10 去除出现次数5以下的词,多线程运行,迭代10次
        model = Word2Vec(PathLineSentences(input_dir),
                         size=256, window=10, min_count=5,
                         workers=multiprocessing.cpu_count(), iter=10)
        model.save(outp1)
        model.wv.save_word2vec_format(outp2, binary=False)
    
        # 运行命令:输入训练文件目录 python word2vec_model.py data baike.model baike.vector
    

    二、Bert词向量

    • Bert本质上是一个两段式的NLP模型。第一个阶段:Pre-training,跟WordEmbedding类似,利用现有无标记的语料训练一个语言模型。第二个阶段:Fine-tuning,利用预训练好的语言模型,完成具体的NLP下游任务。

    方法一:直接生成

    1.下载Bert项目

    extract_features.py——句向量生成文件

    2.下载Bert中文预训练模型

    1.TensorFlow 模型文件(bert_model.ckpt) :包含预训练模型的权重,模型文件有三个
    2.字典文件(vocab.txt) :记录词条与 id 的映射关系
    3.配置文件(bert_config.json ) :记录模型的超参数

    3.句向量特征提取

    • 传入参数
    --input_file="./data/input.txt"
    --output_file="./data/output.jsonl"
    --vocab_file="./chinese_L-12_H-768_A-12/vocab.txt"
    --bert_config_file="./chinese_L-12_H-768_A-12/bert_config.json"
    --init_checkpoint="./chinese_L-12_H-768_A-12/bert_model.ckpt"
    --layers=-2
    --max_seq_length=128
    --batch_size=8
    layers: 是输出那些层的参数,-1就是最后一层,-2是倒数第二层,一次类推
    max_seq_length: 是最大句子长度,根据自己的任务配置。如果你的GPU内存比较小,可以减小这个值,节省存储
    
    • 输出
    {"linex_index": 1, "features": [{"token": "[CLS]", "layers": [{"index": -1, "values": [-0.2844, 0.450896, 0.285645, 0.421341, 0.411053, ...
    

    方法二:Bert-as-Service

    1.安装Bert-as-Service

    pip install bert-serving-server  # server
    pip install bert-serving-client  # client, independent of `bert-serving-server`
    

    2.下载Bert中文预训练模型

    3.开启服务

    • cmd进入bert-serving-start.exe所在的文件夹,一般这个文件夹在python安装路径下的Scripts文件夹下
    cd D:\Anaconda3\Scripts
    bert-serving-start -model_dir E:/chinese_L-12_H-768_A-12 -num_worker=1
    
    • 其中,-model_dir 是预训练模型的路径,-num_worker 是线程数,表示同时可以处理多少个并发请求
    • 注意: 路径名中间千万不要有空格

    在这里插入图片描述

    • 当出现:ready and listening! 表明此时已经开启了bert-as-service,但是注意此时 cmd窗口不要关闭

    4.加载句向量

    • 转到pycharm,创建一个py文件然后输入如下代码,如果产生了向量矩阵则说明配置成功
    from bert_serving.client import BertClient
    bc = BertClient()
    vec = bc.encode(["今天天气真好", "我感冒了"])
    print(vec)
    
    • 输出

    在这里插入图片描述

    from bert_serving.client import BertClient
    import numpy as np
    bc = BertClient()
    result = []
    value = 0.90
    f = open('1.txt', 'r', encoding='utf-8-sig')
    for line in f:
        result.append(line.strip('\n'))
    Input = bc.encode(result)
    print(Input)
    
    • 这样可以将1.txt中的每一行文字转化成词向量表示的矩阵,但bert默认最大句子的长度为32,去除首尾CLS和SEP则只剩下30个字符,因此这里在处理文本时会出现只能处理一行30个字符的情况,超过30个部分则不会算进去。

    5.加载词向量

    • 启动服务时将参数 pooling_strategy 设置为 None
    bert-serving-start -pooling_strategy NONE -model_dir E:/chinese_L-12_H-768_A-12/
    
    • 此时返回的是语料中每个 token 对应 embedding 的矩阵
    from bert_serving.client import BertClient
    bc = BertClient()
    vec = bc.encode(['hey you', 'whats up?'])
    print('vec.shape:', vec.shape)
    

    在这里插入图片描述

    vec # [2, 25, 768]
    vec[0] # [1, 25, 768], sentence embeddings for hey you
    vec[0][0] # [1, 1, 768], word embedding for [CLS]
    vec[0][1] # [1, 1, 768], word embedding for hey
    vec[0][2] # [1, 1, 768], word embedding for you
    vec[0][3] # [1, 1, 768], word embedding for [SEP]
    vec[0][4] # [1, 1, 768], word embedding for padding symbol
    vec[0][25] # error, out of index!

    方法三:不开启servers服务生成句向量

    from bert.extrac_feature import BertVector
    bv = BertVector()
    bv.encode(['今天天气不错'])
    
    • 输出:
    [[ 1.21984698e-01  7.84057677e-02 -1.06496774e-01 -3.25891018e-01
       4.94978607e-01 -4.69692767e-01  2.54333645e-01 -8.82656407e-03...
    
    展开全文
  • 使用pytorch获取bert词向量

    千次阅读 2020-07-19 22:48:46
    首先安装pytorch-pretrained-bert包: pip install pytorch-pretrained-bert 然后加载预训练模型 from pytorch_pretrained_bert import BertTokenizer, BertModel, BertForMaskedLM # Load pretrained model/...

    本文主要为如何使用pytorch来获取bert词向量。

    首先安装pytorch-pretrained-bert包:

    pip install pytorch-pretrained-bert

    然后加载预训练模型

    from pytorch_pretrained_bert import BertTokenizer, BertModel, BertForMaskedLM
    # Load pretrained model/tokenizer
    tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
    model = BertModel.from_pretrained('bert-base-uncased')
    
    

    如果是第一次使用,执行上述代码后程序会开始自动下载相应的模型,但是会耗费大量时间,因此最好事先下载好相应的模型,然后指定目录。

    tokenizer = BertTokenizer.from_pretrained('data/cased_L-12_H-768_A-12') #改为自己存放模型的目录
    model = BertModel.from_pretrained('data/cased_L-12_H-768_A-12')

    如何下载模型:

    Bert模型下载地址如下,根据自己的需求下载相应模型。

    https://github.com/google-research/bert#pre-trained-models

    该链接下载后的模型是支持tensorflow的而不是支持pytorch的,因此需要将其进行转化,生成pytorch_model.bin文件。

    (也可以直接照pytorch_model.bin的链接下载,但是下载起来太慢了而且可能打不开,所有还是建议用上面的链接然后再转化)

    详情可参考https://blog.csdn.net/weixin_41287060/article/details/105080705

    转换完成之后,存放模型的目录下应有以下三个文件:

    获取隐藏层向量

    text = " the man went to the store "
    tokenized_text = tokenizer.tokenize(text) #token初始化
    indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text) #获取词汇表索引
    tokens_tensor = torch.tensor([indexed_tokens]) #将输入转化为torch的tensor
    with torch.no_grad(): #禁用梯度计算 因为只是前向传播获取隐藏层状态,所以不需要计算梯度
        last_hidden_states = model(tokens_tensor)[0]

    隐藏状态的四个维度(参考 Bert词向量指南):

    从输出可知,模型为每个单词输出了12个隐藏层向量,那么该如何利用这些隐藏层向量获取最终的词向量?

    Bert作者利用不同的向量组合作为输入特征进行NER实验来测试这一点。

    以下为通过最后四层的连接和求和来创建单词向量的示例

    token_embeddings=[]
    for token_i in range(len(tokenized_text)):
        hidden_layers=[]
        for layer_i in range(len(last_hidden_states)):
            vec=last_hidden_states[layer_i][0][token_i] #如果输入是单句不分块中间是0,因为只有一个维度,如果分块还要再遍历一次
            hidden_layers.append(vec)
        token_embeddings.append(hidden_layers)
    concatenated_last_4_layers = [torch.cat((layer[-1], layer[-2], layer[-3], layer[-4]), 0) for layer in token_embeddings] #连接最后四层 [number_of_tokens, 3072]	
    summed_last_4_layers = [torch.sum(torch.stack(layer)[-4:], 0) for layer in token_embeddings] #对最后四层求和 [number_of_tokens, 768]

     pytorch获取bert词向量的一些相关文章:

    1. https://github.com/huggingface/transformers
    2. https://blog.csdn.net/u011984148/article/details/99921480  (这个博主写得非常明白)

     

    展开全文
  • 常见bert词向量版本

    2020-04-05 10:04:07
    bert_base bert_large 哈工大 wwm 最新 细分领域的暂时不写

    bert_base

    bert_large

    哈工大

    wwm

    最新

    细分领域的暂时不写

    展开全文
  • BERT词向量-batch提取

    2020-05-06 20:28:32
    代码来源于网址,做了一点小修改,添加了一点注释。一开始model_path设置为‘bert-...主要由于标注没有使用wordpiece,因此词由分词之后第一个词的词向量表示。batch从长到短排列,是为了方便之后的rnn结构。 impo...

    代码来源于网址,做了一点小修改,添加了一点注释。一开始model_path设置为‘bert-base-uncased’,网络模型,字典都会下载在cache/torch/transformer中,之后save保存之后,就可将model_path设置为保存的位置。主要由于标注没有使用wordpiece,因此词由分词之后第一个词的词向量表示。batch从长到短排列,是为了方便之后的rnn结构。
    此代码仅仅只能提取bert词向量,无法finetune。如果需要fintune,首先需要继承nn.Module,然后需要在forward中调用extract_features,并把with torch.no_grad去掉。这里的fix embedding只是固定了wordpiece,position embedding 和segment embedding。即输入transformer之前的权重。

    import torch
    from transformers import *
    
    class Bertvec:
        def __init__(self, model_path, device, fix_embeddings=True):
            self.device = device
            self.model_class = BertModel
            self.tokenizer_class = BertTokenizer
            self.pretrained_weights = model_path
            self.tokenizer = self.tokenizer_class.from_pretrained(self.pretrained_weights)
            self.model = self.model_class.from_pretrained(self.pretrained_weights).to(self.device)
            if fix_embeddings:
                for name, param in self.model.named_parameters():
                    if name.startswith('embeddings'):
                        param.requires_grad = False
    
        def extract_features(self, input_batch_list):
            batch_size = len(input_batch_list)
            words = [sent for sent in input_batch_list]
            word_seq_lengths = torch.LongTensor(list(map(len, words)))
            # 每句句子的长度,获得最长长度
            max_word_seq_len = word_seq_lengths.max().item()
            word_seq_lengths, word_perm_idx = word_seq_lengths.sort(0, descending=True)
            # 长度从长到短排列,并获得由原始排列到从长到短排列的转换顺序 eg:[2,3,1]句子长度,则转换顺序为[1,0,2]
            batch_tokens = []
            batch_token_ids = []
            subword_word_indicator = torch.zeros((batch_size, max_word_seq_len), dtype=torch.int64)
            for idx in range(batch_size):
                one_sent_token = []
                one_subword_word_indicator = []
                for word in input_batch_list[idx]:
                    word_tokens = self.tokenizer.tokenize(word)
                    # 按照wordpiece分词
                    one_subword_word_indicator.append(len(one_sent_token) + 1)
                    # 由于分词之后,和输入的句子长度不同,因此需要解决这个问题,这里保存原始句子中词和分词之后的首个词的对应关系
                    one_sent_token += word_tokens
                    # 针对一句句子,获得分词后的结果
                # 添加 [cls] and [sep] tokens
                one_sent_token = ['[CLS]'] + one_sent_token + ['[SEP]']
                one_sent_token_id = self.tokenizer.convert_tokens_to_ids(one_sent_token)
                # token转换id
                batch_tokens.append(one_sent_token)
                batch_token_ids.append(one_sent_token_id)
                subword_word_indicator[idx, :len(one_subword_word_indicator)] = torch.LongTensor(one_subword_word_indicator)
            token_seq_lengths = torch.LongTensor(list(map(len, batch_tokens)))
            max_token_seq_len = token_seq_lengths.max().item()
            # 计算分词之后最长的句子长度
            batch_token_ids_padded = []
            for the_ids in batch_token_ids:
                batch_token_ids_padded.append(the_ids + [0] * (max_token_seq_len - len(the_ids)))
                # 补充pad
            batch_token_ids_padded_tensor = torch.tensor(batch_token_ids_padded)[word_perm_idx].to(self.device)
            subword_word_indicator = subword_word_indicator[word_perm_idx].to(self.device)
            # 都按照之前得出的转换顺序改变为没有分词之前的句子从长到短的排列。
            with torch.no_grad():
                last_hidden_states = self.model(batch_token_ids_padded_tensor)[0]
            # 提取bert词向量的输出
            batch_word_mask_tensor_list = []
            for idx in range(batch_size):
                one_sentence_vector = torch.index_select(last_hidden_states[idx], 0, subword_word_indicator[idx]).unsqueeze(
                    0)
                # 根据对应关系,用分词之后的第一个分词来代表整个词,并添加batch的维度
                batch_word_mask_tensor_list.append(one_sentence_vector)
            batch_word_mask_tensor = torch.cat(batch_word_mask_tensor_list, 0)
            return batch_word_mask_tensor
            
        def save_model(self, path):
            # 将网上下载的模型文件保存到path中
            self.tokenizer.save_pretrained(path)
            self.model.save_pretrained(path)
    
    if __name__ == '__main__':
        input_test_list = [["he", "comes", "from", "--", "encode"],
                           ["One", "way", "of", "measuring", "the", "complexity"],
                           ["I", "encode", "money"]
                           ]
        bert_embedding = Bertvec('./bert-base-uncased/', 'cpu', True)
        batch_features = bert_embedding.extract_features(input_test_list)
    	print(batch_features)
    
    展开全文
  • 最近刚出来效果最好的模型是bert的动态词向量,刷新了各个自然语言处理Task的成绩如QA,NER,CLASSIFICATION等 接下来就让我们实际来构建一个以bert为后端词向量的文本分类模型 1、首先安装腾讯开源的Bert-as-...
  • 利用bert-serving-server搭建bert词向量服务(一)

    万次阅读 热门讨论 2019-05-19 22:22:17
      Bert是去年谷歌发布的一款新模型,在11个主流NLP任务中都取得优异的结果,因此成为NLP领域最吸引人的一个模型。它的核心思想在于:作者认为语言表示 存在一个通用模型,而具体到专业领域,可以对通用模型进行...
  • pytorch_transformers使用之获取bert词向量

    千次阅读 热门讨论 2019-08-21 12:33:47
    使用convert_tf_checkpoint_to_pytorch.py脚本,将TensorFlow checkpoint(以bert_model.ckpt开头的三个文件)和相关的配置文件(bert_config.json)作为输入,并为此配置创建PyTorch版本模型。 详情请见 ...
  • 基于bert微调输出的textCNN文本分类(包含bert输出的SST2数据集) 第一次发表博客,也是第一次写,大家多多包涵,都是有质量的东西。 基于Keras实现textCNN源代码 模型实现代码: // 基于Keras框架的textCNN模型...
  • 序列标注任务 现在很多自然语言处理的任务都被视为基于神经网络的序列标注...本文介绍的是基本的Bert_BiLSTM_CRF的序列标注,其中的Bert是预训练语言模型,主要用来获取文本对应的向量Bert是在大规模的文本语料上训

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,758
精华内容 3,103
关键字:

bert词向量