zoukankan      html  css  js  c++  java
  • Pytorch tokenizer使用及补充vocab词汇表

    我们现在需要对一句话做分词,然后转换成index,作为Bert的输入

    tokenizer = BertTokenizer.from_pretrained(config.PRE_TRAINED_MODEL_NAME)
    
    text = '天空下着暴雨,o2正在给c1穿雨衣,他自己却只穿着单薄的军装,完全暴露在大雨之中。角色: o2'
    
    input_ids =tokenizer.encode(text)
    output = tokenizer.decode(input_ids)

    输出的output长这样,长度45:

    '[CLS] 天 空 下 着 暴 雨 , o2 正 在 给 c1 穿 雨 衣 , 他 自 己 却 只 穿 着 单 薄 的 军 装 , 完 全 暴 露 在 大 雨 之 中 。 角 色 : o2 [SEP]'

    但是input_ids的长度是47,??难道不是一一对应

    确实不是,一一与词汇表对比,发现 'o2' 对应了两个 id,'o'对应一个, '##2'对应一个(在bert的词汇表里'##x'通常表示以'x'为后缀)

    神奇的是 'c1' 词汇表中是有的

    也就是说,为了让token和id一一对应起来,我们需要将不存在的token添加到vocab中,网上查到两种方法:

    1. 利用前100里的[unused]

    https://github.com/google-research/bert/issues/396

    将[unused]换成自己想要添加的

    具体有多少个[unused]要看自己的预训练模型,可能100个,可能1000个,但都有限

    2. 利用transformers库里有个 add_tokens 方法

    https://github.com/huggingface/transformers/issues/1413

    https://blog.csdn.net/qq_23944915/article/details/102781463

    import torch
    from transformers import BertTokenizer, BertModel
    import ipdb
    import config   
    
    
    tokenizer = BertTokenizer.from_pretrained(config.PRE_TRAINED_MODEL_NAME)
    model = BertModel.from_pretrained(config.PRE_TRAINED_MODEL_NAME)
    
    x = model.embeddings.word_embeddings.weight[-1, :]
    
    print(len(tokenizer))  # 28996
    tokenizer.add_tokens(["NEW_TOKEN"])
    print(len(tokenizer))  # 28997
    
    model.resize_token_embeddings(len(tokenizer)) 
    # The new vector is added at the end of the embedding matrix
    
    print(model.embeddings.word_embeddings.weight[-1, :])
    # Randomly generated matrix
    
    with torch.no_grad():
        model.embeddings.word_embeddings.weight[-1, :] = torch.zeros([model.config.hidden_size])
    
    print(model.embeddings.word_embeddings.weight[-1, :])
    # outputs a vector of zeros of shape [768]
    
    y = model.embeddings.word_embeddings.weight[-2, :]
    
    print(x == y) # 会改变原来embedding weight 吗? 不会
    ipdb.set_trace()

    这种方法,因为是添加token,需要修改embedding matrix

    不知道它这个resize matrix会不会打扰预训练的embeddings? 经测,不会

    感觉两种都行,待测 

    也有可能都没必要,Bert可能能够学会新的组合词汇

     
  • 相关阅读:
    设置为自动启动的WindowService没有开机启动
    Asp.Net部署问题
    MSDTC的折磨
    C# WinForm 边框阴影窗体
    升级DotNetNuke
    常用缩写
    DotNetNuke的升级路径
    日本語文法勉強
    PostSubmitter~在WEB应用程序以外的其他程序里提交Web请求的类
    vue中的锚链接跳转问题
  • 原文地址:https://www.cnblogs.com/lfri/p/15547118.html
Copyright © 2011-2022 走看看