精华内容
下载资源
问答
  • bert得到向量

    2020-07-02 16:23:08
    modeling,tokenization为bert在github上的代码,链接: https://github.com/google-research/bert. chinese_L-12_H-768_A-12是中文语料训练的模型,链接: ...from bert_demo import modeling from bert_demo import

    modeling,tokenization为bert在github上的代码,链接: https://github.com/google-research/bert.

    chinese_L-12_H-768_A-12是中文语料训练的模型,链接: https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip.

    from bert_demo import modeling
    from bert_demo import tokenization
    import numpy as np
    import tensorflow as tf
    
    
    class bert_vec():
        def __init__(self):
            # graph
            self.input_ids = tf.placeholder(tf.int32, shape=[None, None], name='input_ids')
            self.input_mask = tf.placeholder(tf.int32, shape=[None, None], name='input_masks')
            self.segment_ids = tf.placeholder(tf.int32, shape=[None, None], name='segment_ids')
    
            bert_config = modeling.BertConfig.from_json_file('chinese_L-12_H-768_A-12/bert_config.json')
            # 初始化BERT
            self.model = modeling.BertModel(
                config=bert_config,
                is_training=False,
                input_ids=self.input_ids,
                input_mask=self.input_mask,
                token_type_ids=self.segment_ids,
                use_one_hot_embeddings=False
            )
            # bert模型地址
            init_checkpoint = "chinese_L-12_H-768_A-12/bert_model.ckpt"
            # 模型的训练参数
            tvars = tf.trainable_variables()
            # 加载模型
            (assignment_map, initialized_variable_names) = modeling.get_assignment_map_from_checkpoint(tvars,init_checkpoint)
            tf.train.init_from_checkpoint(init_checkpoint, assignment_map)
    
            self.sess = tf.Session()
            self.sess.run(tf.global_variables_initializer())
    
    
    
        def get_embedding(self,char_lists,mask_lists,seg_lists):
            # 获取最后一层和倒数第二层
            encoder_last_layer = self.model.get_sequence_output()
            # encoder_last2_layer = model.all_encoder_layers[-2]
    
            feed_data = {self.input_ids: np.asarray(char_lists), self.input_mask: np.asarray(mask_lists), self.segment_ids: np.asarray(seg_lists)}
            embedding = self.sess.run(encoder_last_layer, feed_dict=feed_data)
            return embedding
    
    
    if __name__ == '__main__':
    
        #数据处理
        string = '设置一个随机种子'
        char_list = ['[CLS]'] + list(string) +['[SEP]']
        #不做masked处理
        mask_list = [1] * (len(string)+2)
        #不做分词处理
        seg_list = [0] * (len(string)+2)
    
    
        # 根据bert的词表做一个char_to_id的操作
        # 未登录词会报错,更改报错代码使未登录词时为'[UNK]'
        # 也可以自己实现
        token = tokenization.FullTokenizer(vocab_file='chinese_L-12_H-768_A-12/vocab.txt')
        char_list = token.convert_tokens_to_ids(char_list)
        bertVec = bert_vec()
    
        #得到bert的embedding
        embedding = bertVec.get_embedding([char_list], [mask_list], [seg_list])
    
    展开全文
  • from pytorch_pretrained_bert import BertTokenizer, BertModel def get_embeddings(mname): '''Gets pretrained embeddings of Bert-tokenized tokens or subwords mname: string. model name. &#...
  • 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...
    
    展开全文
  • BERT在用于下游各项NLP任务上都有明显提升,但是被发现直接作为sentence embedding的预训练模型效果不好,作者发现这是因为没有很好地挖掘BERT里面的语义信息,作者从理论上证明了bert的训练目标(MLM,NSP)和相似度...

    On the Sentence Embeddings from Pre-trained Language Models 阅读笔记

    code : github/BERT-Flow

    source : EMNLP 2020

    BERT在用于下游各项NLP任务上都有明显提升,但是被发现直接作为sentence embedding的预训练模型效果不好,作者发现这是因为没有很好地挖掘BERT里面的语义信息,作者从理论上证明了bert的训练目标(MLM,NSP)和相似度任务之间差异,并可视化展示。发现bert的语义空间是非光滑的各向异性(non-smooth anisotropic)的语义空间,不利于用于语义相似任务。那么将其转换为光滑的各向同性的高斯分布是不是就解决了呢?因此作者提出利用有监督的normalizing flows来做空间转换,并且实验证明有超过SOTA。

    问题:

    • BERT在检索语义相似的句子时表现不佳,是因为它带了太少的语义信息,还是没有语义信息没有充分利用?
    • 如果语义信息足够,那么怎么在不额外增加监督任务下,充分利用其中信息?

    BERT句向量空间分析

    语义相似度任务和BERT预训练有关联

    bert的掩码任务MLM,通过句子的上下文来预测被掩码的单词 x x x, 其向量表示 w x w_x wx h c h_c hc是其上下文 c c c经过深度网络之后的向量表示,语言模型和掩码任务都是建模上下文c条件的x分布,可以表示为:
    p ( x ∣ c ) = exp ⁡ h c ⊤ w x ∑ x ′ exp ⁡ h c ⊤ w x ′ p(x \mid c)=\frac{\exp \mathbf{h}_{c}^{\top} \mathbf{w}_{x}}{\sum_{x^{\prime}} \exp \mathbf{h}_{c}^{\top} \mathbf{w}_{x^{\prime}}} p(xc)=xexphcwxexphcwx

    2017Breaking指出,对于一个充分训练的语言模型, h c ⊤ w x \mathbf{h}_{c}^{\top} \mathbf{w}_{x} hcwx可以近似的表示为:
    h c ⊤ w x ≈ log ⁡ p ∗ ( x ∣ c ) + λ c = PMI ⁡ ( x , c ) + log ⁡ p ( x ) + λ c PMI ⁡ ( x , c ) = log ⁡ p ( x , c ) p ( x ) p ( c ) \begin{aligned} \mathbf{h}_{c}^{\top} \mathbf{w}_{x} & \approx \log p^{*}(x \mid c)+\lambda_{c} \\ &=\operatorname{PMI}(x, c)+\log p(x)+\lambda_{c} \end{aligned} \\ \operatorname{PMI}(x, c)=\log \frac{p(x, c)}{p(x) p(c)} hcwxlogp(xc)+λc=PMI(x,c)+logp(x)+λcPMI(x,c)=logp(x)p(c)p(x,c)
    其中PMI(x,c)表示x和c之间的互信息,表征的是x和c的共现近似度,而”语义“在数学空间上的表达就是共现关系的统计表示,因此,词向量和上下文向量的点击是可以反应词语和上文问的语义相似度的。

    因此,如果两个上下文 c c c c ′ c' c和同一个词w有共现关系,那么一定程度上 c c c c ′ c' c也是相似的,这表明BERT训练过程和语义相似度目标很接近,训练出的句向量也包含了句子语义相似的信息

    那么,是否是没有有效利用BERT中的句向量信息呢?

    各向异性向量空间会导致较差的语义相似性度量

    由于cos相似度和点积,都是基于向量的基是正交的且各向同性,这种情况下的向量夹角才具有可比性,如果不同的基非正交,那么不同的基向量计算出来的向量夹角没有几何意义。例如下图中,基向量是非正交,且各向异性(基向量单位向量长度不一样),计算向量x1与x2的cos相似度为0,x1与x3的cos相似度为0(正交),但是我们从几何角度上看,其实x1是与x3更相似的,所以导致计算相似度结果也会有问题。

    同时,目前已近有论文发现BERT的向量空间是各向异性的,且词嵌入呈现锥形分布,作者也做了一些论证,为了验证BERT词向量分布是否和词频有关,通过计算不同词频的 l 2 \mathcal{l}_2 l2范数、词向量之间的欧式距离,如下表所示。

    因为词向量空间和句向量空间共享的是同一个高维空间,如果词向量空间有什么问题,那句向量空间也会有同样的问题。

    image-20210125233325825

    词频会给词向量引入偏差:从表中可以看出,无论是 l 2 \mathcal{l}_2 l2范数还是词向量之间的欧式距离,不同词频之间分布都不一致。对于 l 2 \mathcal{l}_2 l2范数,明显高频词语离原点更近,这会导致同意词语由于词频不同带来的语义空间的偏差,不能使用词向量距离来表示其相似性,推理到句向量也同理。

    低频词语更稀疏:同时高频词语的词向量之间的欧式距离更小,说明高频词语更加稠密,低频词语更加稀疏,稀疏会导致语义空间的某些地带空白(holes),没有语义表示,因为bert句向量是词向量的平均池化,是一种保凸性运算,然而这些没有语义定义的空间使得分布不是凸性的,所以可以认为BERT句向量上是语义不平滑的(semantically non-smoothing),这导致句向量相似度不一定准确表示句子的语义相似度。

    BERT-flow

    为了解决bert语义不平滑问题,作者通过Normalizing Flows来讲bert句向量分布转换到高斯分布,因为它是一个光滑的、各向同性的分布空间。

    image-20210125234838801

    为什么要转换为高斯分布呢,标准高斯分布是各向同性的,同时标准高斯分布是凸的,或者说是没有"holes",因此语义分布更为光滑。

    Flow-based Generative Model

    A flow-based generative model会将潜在空间 Z \mathcal{Z} Z到观测空间 U \mathcal{U} U的可逆变换 ,生成过程为:
    z ∼ p Z ( z ) , u = f ϕ ( z ) \mathbf{z} \sim p_{\mathcal{Z}}(\mathbf{z}), \mathbf{u}=f_{\phi}(\mathbf{z}) zpZ(z),u=fϕ(z)
    其中$ p_{\mathcal{Z}} 是 标 准 的 高 斯 分 布 , 是标准的高斯分布, \mathcal{U}$是bert的分布,通过将一个标准的高斯分布生成一个bert的句子embedding分布,通过下面公式来最大化似然:
    m a x ϕ E u = B E R T ( s e n t e n c e ) , s e n t e n c t   D l o g p Z ( f ϕ − 1 ( u ) ) + l o g ∣ d e t ∂ f − 1 ( u ) ∂ u ∣ max_{\phi} E_u = BERT(sentence),sentenct \ D \\ log p_{\mathcal Z(f^{-1}_{\phi}(u))} + log |det \frac{\partial f^{-1}(u)}{\partial u}| maxϕEu=BERT(sentence),sentenct DlogpZ(fϕ1(u))+logdetuf1(u)
    其中D是数据集,即很多句子,训练的时候,bert的参数不变,通过学习可逆变化 f ϕ − 1 f^{-1}_\phi fϕ1,将bert 的句子embedding转换为一个高斯的输出分布z。

    而这个可逆变换 f ϕ − 1 f^{-1}_\phi fϕ1可以通过一个神经网络来模拟,结构设计时候通常需要考虑变换的可逆性,同时 l o g ∣ d e t ∂ f − 1 ( u ) ∂ u ∣ log |det \frac{\partial f^{-1}(u)}{\partial u}| logdetuf1(u)也需要容易计算,保证训练能够进行,本文使用了Glow

    实验

    image-20210215134636553

    上面的实验中,都没有使用NLI的监督标签,而target表示使用了NLI的语料来训练flow,但是并没有使用其监督的标签。

    可能是用的一个相关的语料,使用bert获取其原始embedding,然后将可逆变换映射到一个高斯分布上。

    其中bret-flow模型默认使用了最后两层的avg pooling(last2avg).

    下面的实验中,使用了NLI的有监督标签进行训练,但是flow的训练仍然是无监督的。可以看到,flow多数数据集上仍然是表现最好的。

    image-20210215135446502

    QA问题探索

    作者通过将此方法应用的问题和答案对匹配上,即去计算问题和答案的embeeding的cosin相似度来预估它们是否相关,在QNLI数据集上证明也是有明显提升。

    flow对比其他校准算法

    SN(Standard Normalization): 后处理,计算均值和方差,然后 u − μ σ \frac{u-\mu}{\sigma} σuμ通过来做归一。

    Nulling Away Top-k Singular Vectors (NATSV): nulling away the top-k singular vectors,

    对比也证明,flow是这些校准算法中最好的。

    image-20210215141106490

    也有大佬试验过flow是否必要:你可能不需要BERT-flow:一个线性变换媲美BERT-flow

    语义相似度和字的关系

    研究句子相似度是否和编辑距离是否有强关系,相比于真实标签,bert与编辑距离的关系很高。就上图中,当句子对的编辑距离小于4的时候,bert的语义相似度很高,但是真实标签却不是这样,例如句子“我喜欢这家饭店”和“我不喜欢这家饭店”,虽然编辑距离很小,但是确是相反的句子,而bert会倾向于认为他们相似。

    读后感

    本文对bert的向量表达做了细致的分析,从提出质疑、验证问题、方法探索对问题进行了解决,提出的方法是一方面,发现问题也很重要,当然,也有大佬试验过flow是否必要:你可能不需要BERT-flow:一个线性变换媲美BERT-flow

    Reference

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

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

    bert_base

    bert_large

    哈工大

    wwm

    最新

    细分领域的暂时不写

    展开全文
  • 使用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/...
  • 1.获取bert的SST2句向量,通过Keras构建一个简单的基于句向量的文本分类算法,得益于bert的强大性能,在SST2文本分类的准确率高达81.80,实验结果比CRAN,CAM,DA,textCNN模型都好,训练速度特别快,收敛也特别快 ...
  • BERT向量-batch提取

    2020-05-06 20:28:32
    一开始model_path设置为‘bert-base-uncased’,网络模型,字典都会下载在cache/torch/transformer中,之后save保存之后,就可将model_path设置为保存的位置。主要由于标注没有使用wordpiece,因此词由分词之后第一个...
  • 闲聊机器人(chatbot),BERT向量-相似度(Sentence Similarity),文本分类(Text classify) 数据增强(text augment enhance),同义句同义词生成,句子主干提取(mainpart),中文汉语短文本相似度,文本特征...
  • 我在启动Bert的中文训练包时,遇到这个问题不知道如何解决 ``` I: [35mVENTILATOR [0m:freeze, optimize and export graph, could take a while... 2020-02-27 21:54:07.408910: W tensorflow/stream_executor/...
  • Bert中的位置向量

    千次阅读 2019-07-29 10:46:39
    为什么bert中position embedding即使加一个随机矩阵 把position的0,1,2,3,4看成word id一样用embedding_lookup表示成和word embedding同样维数,也就是用一个vector代表0,用一个vector代表1,用一个vector代表2……...
  • BERT向量召回问答对, FAQ标准问答对数据量不大 不能把BERT编码部署于网络服务, 如http请求的形式, 因为网络传输耗时, 此外传输的数据量还很大768(维度)*32(float) 几乎所有的模型服务只能用cpu, 硬盘、内存都还可以 ...
  • 利用bert-serving-server搭建bert向量服务(一)

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

    万次阅读 多人点赞 2019-02-19 11:41:39
    之前的文章介绍了BERT的原理、并用BERT做了文本分类与相似度计算,本文将会教大家用BERT来生成句向量,核心逻辑代码参考了hanxiao大神的bert-as-service,我的代码地址如下: 代码地址:BERT向量 传统的句向量 ...
  • 基于bert微调输出的textCNN文本分类(包含bert输出的SST2数据集) 第一次发表博客,也是第一次写,大家多多包涵,都是有质量的东西。 基于Keras实现textCNN源代码 模型实现代码: // 基于Keras框架的textCNN模型...
  • 最近刚出来效果最好的模型是bert的动态词向量,刷新了各个自然语言处理Task的成绩如QA,NER,CLASSIFICATION等 接下来就让我们实际来构建一个以bert为后端词向量的文本分类模型 1、首先安装腾讯开源的Bert-as-...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,119
精华内容 4,047
关键字:

bert位置向量