task6 transformer情感分析

本文档记录了datawhale团队使用BERT模型进行情感分析的步骤,包括数据预处理(如使用bert-base-uncased分词,处理max_input_length,定义标签字段),构建模型(导入预训练模型,创建GRU模型),训练模型并进行模型验证的过程。
摘要由CSDN通过智能技术生成

该文档为datawhale情感分析组队学习的笔记
Github地址:team-learning-nlp/Emotional_Analysis at master · datawhalechina/team-learning-nlp (github.com)

1. 数据预处理

import torch

import random
import numpy as np

SEED = 1234

random.seed(SEED)
np.random.seed(SEED)
torch.manual_seed(SEED)
torch.backends.cudnn.deterministic = True

1.1 bert-base-uncased

Transformer 已经用特定的词汇进行了训练,这意味着我们需要使用完全相同的词汇进行训练,并以与 Transformer 最初训练时相同的方式标记我们的数据。

幸运的是,transformers 库为每个提供的transformer 模型都有分词器。 在这种情况下,我们使用忽略大小写的 BERT 模型(即每个单词都会小写)。 我们通过加载预训练的“bert-base-uncased”标记器来实现这一点。

from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
  • tokenizer 有一个 vocab 属性,它包含我们将使用的实际词汇。 我们可以通过检查其长度来检查其中有多少单词。
len(tokenizer.vocab)

# 30522
  • 使用tokenizer.tokenize方法对字符串进行分词,并统一大小写。
tokens = tokenizer.tokenize('Hello WORLD how ARE yoU?')

print(tokens)

# ['hello', 'world', 'how', 'are', 'you', '?']
  • 我们可以使用我们的词汇表使用 tokenizer.convert_tokens_to_ids 来数字化标记。下面的tokens是我们之前上面进行了分词和统一大小写之后的list。
indexes = tokenizer.convert_tokens_to_ids(tokens)

print(indexes)

# [7592, 2088, 2129, 2024, 2017, 1029]

1.2 特殊token

  • cls:放在第一个句子的首位,经过BERT得到的表征向量C可以用于后续的分类任务(可以理解为用于下游的分类任务)
init_token = tokenizer.cls_token
eos_token = tokenizer.sep_token
pad_token = tokenizer.pad_token
unk_token = tokenizer.unk_token

print(init_token, eos_token, pad_token, unk_token)
  • 我们可以通过反转词汇表来获得特殊tokens的索引
init_token_idx = tokenizer.convert_tokens_to_ids(init_token)
eos_token_idx = tokenizer.convert_tokens_to_ids(eos_token)
pad_token_idx = tokenizer.convert_tokens_to_ids(pad_token)
unk_token_idx = tokenizer.convert_tokens_to_ids(unk_token)

print(init_token_idx, eos_token_idx, pad_token_idx, unk_token_idx)
  • 或者通过tokenizer的方法直接获取
init_token_idx = tokenizer.cls_token_id
eos_token_idx = tokenizer.sep_token_id
pad_token_idx = tokenizer.pad_token_id
unk_token_idx = tokenizer.unk_token_id

print(init_token_idx, eos_token_idx, pad_token_idx, unk_token_idx)

# 101 102 0 100

1.3 max_input_length

  • 我们需要处理的另一件事是模型是在具有定义的最大长度的序列上训练的——它不知道如何处理比训练更长的序列。 我们可以通过检查我们想要使用的转换器版本的 max_model_input_sizes 来获得这些输入大小的最大长度。
max_input_length = tokenizer.max_model_input_sizes['bert-base-uncased']

print(max_input_length)

# 512

1.4 tokenize_and_cut()

  • 之前我们使用了 spaCy 标记器来标记我们的示例。 然而,我们现在需要定义一个函数,我们将把它传递给我们的 TEXT 字段,它将为我们处理所有的标记化。 它还会将token的数量减少到最大长度。 请注意,我们的最大长度比实际最大长度小 2。 这是因为我们需要向每个序列附加两个标记,一个在开头,一个在结尾。
def tokenize_and_cut(sentence):
    tokens = tokenizer.tokenize(sentence) 
    tokens = tokens[:max_input_length-2]
    return tokens

1.5 定义标签字段

  • 现在我们开始定义我们的字段
  1. transformer期望将batch维度放在第一维上,所以我们设置了 batch_first = True
  2. 现在我们已经有了文本的词汇数据,由transformer提供,我们设置 use_vocab = False 来告诉 torchtext 已经不需要切分数据了。
  3. 我们将 tokenize_and_cut 函数作为标记器传递。
  4. preprocessing 参数是一个函数,这是我们将token转换为其索引的地方。
  5. 最后,我们定义特殊的token——注意我们将它们定义为它们的索引值而不是它们的字符串值,即“100”而不是“[UNK]”这是因为序列已经被转换为索引。
from torchtext.legacy import data

TEXT = data.Field(batch_first = True,
                  use_vocab = False,
                  tokenize = tokenize_and_cut,
                  preprocessing = tokenizer.convert_tokens_to_ids,
                  init_token = init_token_idx,
                  eos_token = eos_token_idx,
                  pad_token = pad_token_idx,
                  unk_token = unk_token_idx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值