Hugging Face 中文预训练模型使用介绍及情感分析项目实战

2023-10-27


Hugging Face 中文预训练模型使用介绍及情感分析项目实战

Hugging Face
一直致力于自然语言处理NLP技术的平民化(democratize),希望每个人都能用上最先进(SOTA, state-of-the-art)的NLP技术,而非困窘于训练资源的匮乏"
在这里插入图片描述

其中,transformer库提供了NLP领域大量预训练语言模型和调用框架,方便根据自己的需求快速进行语言模型搭建,这里为自己学习做下简单总结(参考官方教程)。

目录

  1. Transformer整体介绍

    1. 语言模型与自然语言处理
      1. 语言模型
      2. 自然语言处理常见任务
      3. 其他非文本任务
    2. 经典模型处理能力(句子序列长度)
    3. transformer库piepeline接口介绍
  2. tokenizer和model介绍

    1. tokenizer介绍
    2. model介绍
  3. Transformer常用model架构(带head)接口输出

    1. AutoModel架构的输出(通用类,不带head部分)
    2. AutoModelForMaskedLM 架构的输出
    3. AutoModelForSequenceClassification架构的输出
    4. AutoModelForTokenClassification架构的输出
    5. 模型输出logits概率处理
  4. 微调预训练模型实战-情感分析

    • 数据集预处理
    • 模型搭建(预训练模型加载)
    • 数据集编码和数据加载器生成
    • 微调训练
    • 模型保存

正文

  1. Transformer整体介绍

    1. 语言模型与自然语言处理

      1. 语言模型:简易理解就是求概率P(tm|t1、t2、…、tn)

      2. 自然语言处理常见任务

        • Classifying whole sentences: 情感分析,检测垃圾邮件,判断句子语法上是否正确或两个句子逻辑上是否有关联。
        • Classifying each word in a sentences: 识别句子的语法成分(动名词、形容词)或NER命名实体识别(人名,地名,组织)。
        • Generating text content: 文本自动生成,或文本填空。
        • Extracting an answer from a text : 问答系统,给定问题和上下文,根据上下文信息提取问题的答案。
        • Generating a new sentence from an input text: 文本摘要、文本翻译。
      3. 其他非文本任务

        图像:

        • 图像分类:对图像进行分类。

        • 图像分割:对图像中的每个像素进行分类。

        • 物体检测:检测图像中的物体。

          音频:

        • 音频分类:为给定的音频片段分配标签。

        • 自动语音识别 (ASR):将音频数据转录为文本。

    2. 经典模型处理能力(句子序列长度)

      • RNN 10-40
      • LSTM/GRU 50-100
      • Transformer BERT 521 GPT 1024
      • Transformer-XL LXNet 3000-5000
    3. transformer库piepeline接口介绍

      ​ Transformers library 中最基本对象是pipeline,它将数据预处理、预训练语言模型和目标结果处理步骤串联起来,使我们能够直接输入文本并获得自己需要的答案。

      Pipeline结构示意图:
      在这里插入图片描述

      pipeline的简单使用:

      import torch
      from transformers import pipeline
      
      # 哈工大中文预训练模型bert-roberta-wwm (已下载到本地)
      model_path = r"D:\appData\bert-wwm-ext\chinese-roberta-wwm-ext"
      
      # 测试中文填词任务
      fill_mask_model = pipeline(task='fill-mask', # 填写要做的任务类型,确定POST-processing
                                 model=model_path, # 处理任务要使用的预训练语言模型
                                 tokenizer=model_path # 输入数据预处理,需要的分词编码器(与要使用的语言模型相关)
                                )
      
      
      fill_mask_model(['我[MASK]你'])
      # 返回
      '''
      [{'score': 0.8178807497024536,
        'token': 4263,
        'token_str': '爱',
        'sequence': '我 爱 你'},
       {'score': 0.05486121028661728,
        'token': 2682,
        'token_str': '想',
        'sequence': '我 想 你'},
       {'score': 0.02797825261950493,
        'token': 3221,
        'token_str': '是',
        'sequence': '我 是 你'},
       {'score': 0.019031845033168793,
        'token': 1469,
        'token_str': '和',
        'sequence': '我 和 你'},
       {'score': 0.01068081520497799,
        'token': 3612,
        'token_str': '欠',
        'sequence': '我 欠 你'}]
      '''
      

      ​ 默认情况下,给定特定任务,pipeline会自动选择一个特定的预训练模型。

      ​ 将文本输入pipeline,pipeline的处理涉及3个步骤,对应上面的pipeline结构图

      • tokenizer: 文本预处理为对应model可以理解的格式

      • model: 预处理模型输入对应model

      • post-processing: 将model的输入经过全连接/激活,处理成任务需要输出的形式

      ​ 至此,只需要修改参数 task名+匹配的预训练语言模型,就能简单实现自然语言处理任务(同样也可以使用pipeline实现其他如图像、音频分类等任务)。

  1. tokenizer和model介绍

    ​ 通过pipeline接口,我们能实现特征的任务,但越简单的接口,往往伴随着缺乏灵活性的问题。一般情况下,不直接使用pipeline,使用其中tokenizer和model,配合模型后续处理生成适合自己任务的模型。

    1. tokenizer介绍

      from transformers import BertModel,BertTokenizer,BertConfig
      
      # 主要加载预训练模型词汇表,分词规则等
      tokenizer = BertTokenizer.from_pretrained(model_path)
      
      #分词器序列编码,解码
      data_encode = tokenizer(
          text = ['我 爱 你','我恨你','天空'], #  输入多条分本
          text_pair = None,
          add_special_tokens = True, # 
          padding = 'max_length', # 填充长度不够的序列
          truncation = True, # 过长序列截断
          max_length = 5, # 指定序列长度
          stride = 0,
          is_split_into_words = False, # text或text_pair参数输入字符串列表时,起作用,指定序列是否分批
          pad_to_multiple_of = None,
          
          # 指定数据处理后的返回
          return_tensors = 'pt',# 指定返回数据类型,pt:pytorch np:数组 'tf':tensorflow 不指定返回list
          return_token_type_ids = True, # 指定上下句子关系,上句为0,下句为1
          return_attention_mask = True, # 返回句子序列实际长度,1代表真实token,0代表填充
          return_overflowing_tokens = False,
          return_special_tokens_mask = True,# 指定特殊字符位置,1代表起始符[CLS],分隔符[sep],填充符[PAD]等,0代表正常token
          return_offsets_mapping = False,
          return_length = True,# 返回序列长度
          verbose = True
          )
      
      
      data_encode
      '''
      {'input_ids': tensor([[ 101, 2769, 4263,  872,  102],
                            [ 101, 2769, 2616,  872,  102],
                            [ 101, 1921, 4958,  102,    0]]), 
       'token_type_ids': tensor([[0, 0, 0, 0, 0],
                                 [0, 0, 0, 0, 0],
                                 [0, 0, 0, 0, 0]]), 
       'special_tokens_mask': tensor([[1, 0, 0, 0, 1],
                                      [1, 0, 0, 0, 1],
                                      [1, 0, 0, 1, 1]]), 
       'length': tensor([5, 5, 4]), 
       'attention_mask': tensor([[1, 1, 1, 1, 1],
                                 [1, 1, 1, 1, 1],
                                 [1, 1, 1, 1, 0]])}
      '''
      
      
      tokenizer.decode(token_ids=data_encode['input_ids'][0]) 
      
      # 字符解码 >> [CLS] 我 爱 你 [SEP] [PAD]
      
    2. model介绍

      # 加载预训练bert中文语言模型(主要是预训练参数)
      model = BertModel.from_pretrained(pretrained_model_name_or_path=model_path)
      
      bert_out = model.forward(
          input_ids = data_encode.input_ids,     # 对应tokener输出字符序列编码
          attention_mask = data_encode.attention_mask,
          token_type_ids = data_encode.token_type_ids,
          position_ids = None,
          head_mask = None,
          inputs_embeds = None,
          encoder_hidden_states = None,
          encoder_attention_mask = None,
          past_key_values = None,
          use_cache = None,
          output_attentions = None,
          output_hidden_states = True, # 是否返回
          return_dict = None
          )
      
      # bert_out.hidden_states # 返回每个block的隐藏层输出
      bert_out.last_hidden_state.shape # 返回bert模型最后一个block隐藏层输出
      bert_out.pooler_output.shape # 返回[CLS]标记处对应的向量后面接个全连接再接tanh激活后的输出
      
      '''
      torch.Size([3, 5, 768]) (batch,sequence_len,word_embedding_szie)
      torch.Size([3, 768]) (batch,word_embedding_szie)
      '''
      

      ​ transformers 中有tokenizer和model类还有很多其他的函数功能,这里只是bert预训练中文语言模型的使用,可以在model(经过tokenizer处理后分词数据输入)的带有语义的隐藏层输出后面,灵活添加后续处理层,实现自己特定的任务。

  2. Transformer常用model架构(带head)接口输出

    ​ transformer库有很多带有不同预设输出的model架构,针对预训练模型输出结果后续处理的层,称之为head层。head将transformer network(多头注意力机制)最终隐藏层输出的高维特征向量作为输入,并将他们投影到不同的维度上,head通常由一个或几个线性层组成。
    在这里插入图片描述

    1. AutoModel架构的输出(通用类,不带head部分)

      ​ In many cases, the architecture you want to use can be guessed from the name or the path of the pretrained model you are supplying to the from_pretrained() method. AutoClasses are here to do this job for you so that you automatically retrieve the relevant model given the name/path to the pretrained weights/config/vocabulary. – 官方原文

      大概意思 AutoModel是个通用类,能从输入的预训练模型名称中或预训练模型存储路径中,自动生成相应模型的architecture(架构)并自动加载checkpoint(可以理解为对应层的权重参数)

      – BertModel 专用于加载BERT架构模型的基础类。

      from transformers import (
          AutoTokenizer,
          AutoModel,
          AutoConfig,
          AutoModelForMaskedLM,
          AutoModelForSequenceClassification,
          AutoModelForTokenClassification)
      
      # 记载预训练模型
      auto_model = AutoModel.from_pretrained(model_path)
      bert_model = BertModel.from_pretrained(model_path)
      tokenizer = AutoTokenizer.from_pretrained(model_path)
      
      # 验证AutoModel和BertModel加载同一个模型输出结果
      data = tokenizer(text=['我爱你'],return_tensors='pt')
      auto_model(data.input_ids).last_hidden_state
      bert_model(data.input_ids).last_hidden_state
      
      '''
      tensor([[[ 0.0963,  0.0306, -0.0745,  ..., -0.6741,  0.0229, -0.3951],
               [ 0.8193, -0.4155,  0.4848,  ..., -0.7079,  0.5251, -0.2706],
               [ 0.2164,  0.2476, -0.2831,  ..., -0.1583,  0.1191, -1.0851],
               [ 0.8606, -0.5950,  0.8120,  ..., -0.4619,  0.1180, -0.4674],
               [ 0.0963,  0.0306, -0.0745,  ..., -0.6741,  0.0229, -0.3951]]],
             grad_fn=<NativeLayerNormBackward>)
             
      tensor([[[ 0.0963,  0.0306, -0.0745,  ..., -0.6741,  0.0229, -0.3951],
               [ 0.8193, -0.4155,  0.4848,  ..., -0.7079,  0.5251, -0.2706],
               [ 0.2164,  0.2476, -0.2831,  ..., -0.1583,  0.1191, -1.0851],
               [ 0.8606, -0.5950,  0.8120,  ..., -0.4619,  0.1180, -0.4674],
               [ 0.0963,  0.0306, -0.0745,  ..., -0.6741,  0.0229, -0.3951]]],
             grad_fn=<NativeLayerNormBackward>)
      '''
      
      

      AutoModel类输出:

      1. 输出为BaseModelOutputWithPoolingAndCrossAttentions。
      2. 包含’last_hidden_state’和’pooler_output’两个元素。
      3. 'last_hidden_state’的形状是(batch size,sequence length,768)
      data = tokenizer(text=['我爱你'],return_tensors='pt')
      model = AutoModel.from_pretrained(model_path)
      outputs = model(**data)
      
      outputs.keys()
      outputs.last_hidden_state.shape # 最后一层隐藏层输出
      outputs.pooler_output.shape # pooler output是取[CLS]标记处对应的向量后面接个全连接再接tanh激活后的输出
      
      '''
      odict_keys(['last_hidden_state', 'pooler_output'])
      torch.Size([1, 5, 768]) (batch,sequence_len,word_embedding_szie)
      torch.Size([1, 768]) (batch,word_embedding_szie)
      '''
      
    2. AutoModelForMaskedLM 架构的输出(with a masked language modeling head,可用于文本填空任务)

      AutoModelForMaskedLM输出:

      1. 输出为MaskedLMOutput
      2. 包含’logits’元素,形状为[batch size,sequence length,21128],21128是’vocab_size’。
      model = AutoModelForMaskedLM.from_pretrained(model_path)
      outputs = model(**data)
      outputs.keys()
      outputs.logits.shape
      
      '''
      odict_keys(['logits'])
      torch.Size([1, 5, 21128])
      '''
      
    3. AutoModelForSequenceClassification架构的输出(with a sequence classification head,文本分类型任务)

      data = tokenizer(text=['我爱你'],return_tensors='pt')
      model = AutoModelForSequenceClassification.from_pretrained(model_path)
      outputs = model(**data)
      
      outputs.keys()
      outputs.logits.shape
      
      '''
      odict_keys(['logits'])
      torch.Size([1, 2])
      '''
      
    4. AutoModelForTokenClassification架构的输出(with a token classification head,命名实体识别任务)

      AutoModelForTokenClassification输出:

      1. 输出为TokenClassifierOutput
      2. 包含’logits’元素,形状为[batch size,sequence length,2]。
      model = AutoModelForTokenClassification.from_pretrained(model_path)
      outputs = model(**data)
      
      outputs.keys()
      outputs.logits.shape
      
      
      '''
      odict_keys(['logits'])
      torch.Size([1, 5, 2])
      '''
      
    5. 模型输出logits概率处理

      ​ logits,即模型最后一层输出的原始的、非标准化的分数。要转换为概率,它们需要经过softmax(所有

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hugging Face 中文预训练模型使用介绍及情感分析项目实战 的相关文章

  • k8s yml 样例

    文章目录 db deploy yml db service yml app deploy yml app service yml db deploy yml apiVersion apps v1beta1 kind Deployment m
  • linux报错 /bin/bash^M:解释器错误:没有那个文件或目录

    在Linux中运行脚本时 会出现linux报错 bin bash M 解释器错误 没有那个文件或目录 这是因为我们将在Windows下编写的脚本拷贝到Linux环境中运行时会出现运行不了的情况 主要还是Windows的换行符为 r n 而L
  • 2023电赛思路 E题:运动目标控制与自动追踪系统

    1 E题 运动目标控制与自动追踪系统 基本思路 1 1 实现步骤 设计红色光斑位置控制系统 选择合适的红色激光笔 并将其固定在一个二维电控云台上 使用电机和编码器来控制电控云台的水平和垂直运动 设计一个控制电路 可以通过输入控制信号来控制电
  • unity3d学习笔记-动画(3.导入动画)

    一 配置动画类型 在准备要导入 Unity 的动画时 动画师可以为每个单独的动画创建不同的文件 或者在一个文件中为所有内容制作动画 将包含多个动画的单个文件导入 Unity 时 可以在 剪辑 部分的导入设置中对其进行拆分 在这里 您可以定义
  • uniapp如何应用onNeedPrivacyAuthorization实现微信小程序隐私政策

    前言 微信小程序要求9 15日前实现隐私政策弹窗 但是uniapp文档一直没有更新 尝试直接使用wx onNeedPrivacyAuthorization 是可以生效的 步骤 在 微信小程序后台 的 设置 服务内容与声明 设置好小程序所需要
  • 【python】爬虫实战流程

    一 采集步骤 1 网页解析 2 引入第三方模块 import requests 请求数据 import json 数据解析 from jsonpath import jsonpath 数据解析 import pandas as pd 数据处

随机推荐

  • maven本地仓库已经有了所需的jar包,为什么还要去请求远程仓库

    问题 IDEA 中的maven 项目 一个jar包一直导入不进来 reimport 无效 从另一仓库把这个jar包拷贝到当前仓库 还是无效 mvn clean install e U 发现加载这个jar包时直接访问远程仓库 都没有从本地查找
  • win11安装xshell提示缺少mfc110.dll问题

    Download Visual C Redistributable for Visual Studio 2012 Update 4 from Official Microsoft Download Center
  • 微信 "{"errcode":-1,"errmsg":"system error"}"

    报这个json问题是因为你有一些参数没有 而产生的 例你没有写appid secret等的原因做成的 这个并不是微信服务器的问题 不要被其字面的意思混乱 唉 微信的提示 我也是醉了
  • Linux PCIe驱动框架分析(第三章)

    目录 项目背景 1 概述 2 流程分析 2 1 Device Tree 2 2 probe流程 2 3 中断处理 2 4 总结 项目背景 Kernel版本 4 14 ARM64处理器 使用工具 Source Insight 3 5 Visi
  • Qt基础:二、Qt4和Qt5兼容部分

    在pro中加入下面一句 greaterThan QT MAJOR VERSION 4 QT widgets 这句话的意思是QT版本超过4 就需要加上widgets
  • Angular ActivatedRoute 用法(官方文档

    允许访问与某出口中加载的组件关联路由信息 用于遍历 RouterState 树并从节点提取信息 查看 说明 class ActivatedRoute snapshot ActivatedRouteSnapshot url Observabl
  • printf()的用法

    http baike baidu com view 1427555 htm 原来做事情不仔细 每次看printf的用法都没懂过 但是也算蒙混过关 现在自己终于懂得生活 所以好好找了下 这篇文章确实不错 和大家分享一下 printf 函数 p
  • 【mmdetection】工具tools试用

    1 日志分析 analyze logs py https blog csdn net jy1023408440 article details 105701705 2 可视化数据集 browse dataset py python tool
  • JAVA上机题(3道)

    题目一 从控制台中读入一个文件名 判断该文件是否存在你的某个盘下 如果该文件存在 则在原文件相同路径下创建一个文件名为 copy 原文件名 的新文件 该文件内容为原文件的拷贝 首先肯定是要判断该文件名到底存不存在 我们定义一个方法 用来判断
  • NoClassDefFoundError: com/google/common/collect/Maps

    Error Exception in thread main java lang NoClassDefFoundError com google common collect Maps I believe you are missing g
  • Lua基础

    目录 Lua5 3参考手册 软件版本 日志及soc下载工具 os date函数说明 os date格式化符号 示例 显示效果 希望实现 实现思路 关于汉字显示的说明 编辑编译方法可参考 示例代码 运行log记录 PS eink 墨水屏操作库
  • Ubuntu报terminals database is inaccessible

    目录 方法一 1 执行以下命令 2 再次运行clear命令 3 执行以下命令 方法二 参考网址 在Ubuntu的命令行窗口中使用clear命令的时候报terminals database is inaccessible错误 clear te
  • Mac上实时网速、内存等显示

    对我这种有强迫症的 要监控各种参数 比如实时网速显示 这里给大家推荐 iStat Menus 1 官网下载 https bjango com mac istatmenus 2 注册码 仅供学习研究 误作商业用途 xxxx xxxx xxxx
  • Ubuntu 系统中安装htpasswd

    htpasswd是Apache附带的程序 htpasswd生成包含用户名和密码的文本文件 每行内容格式为 用户名 密码 用于用户文件的基本身份认证 当用户浏览某些网页的时候 浏览器会提示输入用户名和密码 比如awstats的日志报表 你肯定
  • LightGBM 直方图优化算法

    给出下面这个广泛使用 直方图优化算法的ppt 本文是对该张ppt的解释 直方图优化算法需要在训练前预先把特征值转化为bin 也就是对每个特征的取值做个分段函数 将所有样本在该特征上的取值划分到某一段 bin 中 最终把特征取值从连续值转化成
  • 两种类型的变量

    在java中你会像下面那样声明变量 String s Hello int i 42 Person p new Person hello 每个变量声明都包含了类型 相比之下 在scala中有两种类型的变量 val创建一个不可变的变量 跟jav
  • 【计算机网络】湖科大微课堂笔记 p33-35 MAC地址、IP地址以及ARP协议

    MAC地址 为什么要有MAC地址 原因如图 MAC地址与帧 MAC地址也被称为物理地址 硬件地址 因为它被固化在网卡上 总览 IEEE 802局域网的MAC地址格式 MAC地址发送顺序 举例 单播 广播 多播 单播 主机B想给C发一个单播帧
  • hive get_json_object json_tuple json解析详解

    1 hive中处理json的两个函数 json是常见的数据接口形式 实际中使用也很广泛 下面我们看看怎么在hive中解析json格式 hive中常用的解析json格式的函数有两个 先看看get json object gt desc fun
  • 【Golang】数据结构-slice类型

    slice底层数据结构 一个指针 指向内存地址 len存储当前的内存使用量 cap存储预留的内存最大容量 type slice struct array unsafe Pointer len int cap int 新建slice make
  • Hugging Face 中文预训练模型使用介绍及情感分析项目实战

    Hugging Face 中文预训练模型使用介绍及情感分析项目实战 Hugging Face 一直致力于自然语言处理NLP技术的平民化 democratize 希望每个人都能用上最先进 SOTA state of the art 的NLP技
Powered by Hwhale