NLP的第一步:如何将文本变为embedding输入向量[N,T]

目录

1.分词(Tokenization):

2.索引映射(Index Mapping):

3.添加特殊标记(Add Special Tokens):

4.padding(填充):

5.批量(Batching):


让我们来看一个具体的例子。假设您有这样一个中文句子:

"我爱学习自然语言处理"

将它输入到embedding层之前,需要经过以下步骤:

1.分词(Tokenization):

将整个句子分割成一个个单词(或字符)的序列,比如['我', '爱', '学习', '自然语言', '处理']

(在中文的分词中经常会使用jieba库)

2.索引映射(Index Mapping):

将每个单词映射成词表中的索引值,假设词表为:

vocab = {'我':0, '爱':1, '学习':2, '自然语言':3, '处理':4, '...'}

那么上面的单词序列就变成了索引序列: [0, 1, 2, 3, 4]

3.添加特殊标记(Add Special Tokens):

有时需要在序列首尾添加特殊标记,如<start> 和 <end>

4.padding(填充):

由于每个句子长度不同,我们需要将它们填充到同样长度。假设最大长度为10,那么上面序列就变成[0, 1, 2, 3, 4, 0, 0, 0, 0, 0] (后面添加了5个填充索引0)

通过以上步骤,一个长度为T的句子变成了一个形状为[1, T]的索引序列(批次大小为1)

5.批量(Batching):

对多句话重复上述步骤并堆叠,得到[N, T]的索引矩阵,其中N是批次大小

最后,将这个[N, T]的索引矩阵输入到embedding层,就可以得到[N, T, embedding_dim]的词嵌入表示了。

        所以[N, T]中的N表示批次大小(有多少个句子),T表示每个句子的最大长度(经过padding)。这种表示方式可最大化利用批量计算的并行加速能力。

接下来用代码表示:

import torch
import jieba

# 原始句子
raw_text = "我爱学习自然语言处理"

# 1. 分词
tokens = jieba.lcut(raw_text)
# tokens = ['我', '爱', '学习', '自然语言', '处理']

# 2. 构建词表
vocab = {}
for token in tokens:
    if token not in vocab:
        vocab[token] = len(vocab)
# vocab = {'我': 0, '爱': 1, '学习': 2, '自然语言': 3, '处理': 4}

# 3. 索引映射
ids = [vocab[token] for token in tokens]
# ids = [0, 1, 2, 3, 4]

# 4. 添加特殊标记
pad_id = len(vocab)  # pad_id = 5, 代表[PAD]标记
ids = [pad_id] + ids + [pad_id]  # 加入[PAD]作为开始和结束标记
# ids = [5, 0, 1, 2, 3, 4, 5]

# 5. padding
max_len = 10
padded_ids = ids + [pad_id] * (max_len - len(ids))
# padded_ids = [5, 0, 1, 2, 3, 4, 5, 5, 5, 5]

# 6. 转为张量
input_ids = torch.tensor([padded_ids])
# input_ids.shape = [1, 10]  形状为[N, T]

# 可以重复上述步骤,并在最后一步将多个张量堆叠起来得到批量表示
# batch_input_ids = torch.cat((input_ids, other_input_ids), dim=0)

# 最终输入到embedding层
embeddings = embedding_layer(input_ids)
# embeddings.shape = [1, 10, embedding_dim]

在这个例子中:

  1. 使用jieba分词器将原始文本分词,得到词元(token)序列。
  2. 构建词表,将每个词元映射为一个索引值。
  3. 将词元序列转换为对应的索引序列。
  4. 在序列首尾添加[PAD]标记,其索引值为词表大小。
  5. 将序列padding到固定长度max_len
  6. 将padding后的索引序列转换为PyTorch张量,形状为[N, T]
  7. 最后可以输入到embedding_layer得到[N, T, embedding_dim]的词嵌入表示。

bert分词器

import torch

# 原始句子
raw_text = "我爱学习自然语言处理"

# 1. 分词
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
tokens = tokenizer.tokenize(raw_text)
# tokens = ['我', '爱', '学习', '自然', '语言', '处理']

# 2. 索引映射
ids = tokenizer.convert_tokens_to_ids(tokens)
# ids = [1416, 4610, 1103, 6210, 7273, 3346]

# 3. 添加特殊标记
ids = [101] + ids + [102]  # 加入[CLS]和[SEP]标记
# ids = [101, 1416, 4610, 1103, 6210, 7273, 3346, 102]

# 4. padding
max_len = 10
pad_id = tokenizer.pad_token_id  # 0 对应的是[PAD]标记
padded_ids = ids + [pad_id] * (max_len - len(ids))
# padded_ids = [101, 1416, 4610, 1103, 6210, 7273, 3346, 102, 0, 0]

# 5. 转为张量
input_ids = torch.tensor([padded_ids])
# input_ids.shape = [1, 10]  形状为[N, T]

# 可以重复上述步骤,并在最后一步将多个张量堆叠起来得到批量表示
# batch_input_ids = torch.cat((input_ids, other_input_ids), dim=0)

# 最终输入到embedding层
embeddings = embedding_layer(input_ids)
# embeddings.shape = [1, 10, embedding_dim]

在这个例子中:

  1. 我使用了BERT的分词器来将原始文本分词,获得词元(token)序列。
  2. 将词元映射为词表中对应的索引值。
  3. 添加了BERT模型需要的特殊标记[CLS][SEP]
  4. 将序列padding到固定长度max_len
  5. 将padding后的索引序列转换为PyTorch张量,形状为[N, T]
  6. 最后可以输入到embedding_layer得到[N, T, embedding_dim]的词嵌入表示。
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值