自然语言处理概述
自然语言处理(Nature language Processing, NLP)研究的主要是通过计算机算法来理解自然语言。对 于自然语言来说,处理的数据主要就是人类的语言,例如:汉语、英语、法语等,该类型的数据不像我们前面接触的过的结构化数据、或者图像数据可以很方便的进行数值化
![](https://i-blog.csdnimg.cn/blog_migrate/29bce0179549ccdca8930aeccbd37dca.png)
词嵌入层
词嵌入层的作用就是将文本转换为向量。
词嵌入层首先会根据输入的词的数量构建一个
词向量矩阵
,例如: 我们有 100 个词,每个词希望转换成 128 维度的向量 ,那么构建的矩阵形状即为: 100*128,输入的每个词都对应了一个该矩阵中的一个向量。
PyTorch 中,
使用 nn.Embedding 词嵌入层来实现输入词的向量化
。
nn.Embedding 对象构建时,最主要有两个参数:
1. num_embeddings 表示
词的数量
2. embedding_dim 表示
用多少维的向量来表示每个词
接下来,我们将会学习如何将词转换为词向量,其步骤如下:
1. 先将语料进行分词,构建词与索引的映射,我们可以把这个映射叫做词表,词表中每个词都
对应了一个唯一的索引
2. 然后使用 nn.Embedding 构建词嵌入矩阵,词索引对应的向量即为该词对应的数值化后的向
量表示。
例如,我们的文本数据为: "北京冬奥的进度条已经过半,不少外国运动员在完成自己的比赛后踏
上归途。" ,
代码示例
import torch
import torch.nn as nn
import jieba
# 文本语料
text = '北京冬奥的进度条已经过半,不少外国运动员在完成自己的比赛后踏上归途。'
# 分词
words = jieba.lcut(text)
print(words)
# 去重
u_words = list(set(words))
print(u_words)
# 去重后语料的个数
words_num = len(u_words)
print(words_num)
# 词嵌入层 词的数量,多少维的向量表示每个词
embs = nn.Embedding(num_embeddings=words_num,embedding_dim=10)
print(embs)
for i,word in enumerate(u_words):
word_emb = embs(torch.tensor(i)) # 索引转为张量 提取词向量
print(word)
print(word_emb)
循环网络层
文本数据是具有序列特性的
例如: "我爱你", 这串文本就是具有序列关系的,"爱" 需要在 "我" 之后,"你" 需要在 "爱" 之后, 如果颠倒了顺序,那么可能就会表达不同的意思。
为了表示出数据的序列关系,需要使用循环神经网络(Recurrent Nearal Networks, RNN) 来对数据进行建模,RNN 是一个作用于处理带有序列特点的样本数据。
RNN
是如何计算过程是什么样的呢?
![](https://i-blog.csdnimg.cn/blog_migrate/75101c2f59fa35a3cb35496d6e2eb70e.png)
h 表示隐藏状态,
每一次的输入都会包含两个值: 上一个时间步的隐藏状态、当前状态的输入值,输出当前时间步的隐藏状态和当前时间步的预测结果。
上图画了 3 个神经元, 但是实际上只有一个神经元,"我爱你" 三个字是重复输入到同一个神经元中
我们举个例子来理解上图的工作过程,假设我们要实现文本生成,也就是输入 "我爱" 这两个字,来预测出 "你",其如下图所示
![](https://i-blog.csdnimg.cn/blog_migrate/ea7d6ebc3c3c6e817cb7b68e8375414a.png)
将上图展开成不同时间步的形式,如下图所示:
首先初始化出第一个隐藏状态
h0
,一般都是全
0
的一个向量,然后将
"
我
"
进行词嵌入,转换为向量的表示形式,送入到第一个时间步,然后输出隐藏状态 h1
,然后将
h1
和
"
爱
"
输入到第二个时间步,得到隐藏状态
h2,
将
h2
送入到全连接网络,得到 "
你
"
的预测概率
API
介绍
RNN = torch.nn.RNN(input_size,hidden_size,num_layer)
参数意义是:
1. input_size:输入数据的维度,一般设为词向量的维度;
2. hidden_size:隐藏层h的维数,也是当前层神经元的输出维度;
3. num_layer: 隐藏层h的层数,默认为1.
将
RNN
实例化就可以将数据送入其中进行处理,处理的方式如下所示:
输入数据:
输入主要包括词嵌入的
x
、初始的隐藏层h0
x: seq_len 句子长度 , batch 的大小, input_size 词向量的维度
h0: num_layers 隐藏层的层数 , batch 的大小 , hidden_size 隐藏向量的维度
x: seq_len 句子长度 , batch 的大小, input_size 词向量的维度
h0: num_layers 隐藏层的层数 , batch 的大小 , hidden_size 隐藏向量的维度
输出结果:主要包括输出结果
output,
最后一层的
hn
output : seq_len 句子的长度, batch 的大小 , hidden_size 输出(隐藏)向量的维度
hn : num_layers 隐藏层的层数, batch 的大小 , hidden_size 隐藏向量的维度
output : seq_len 句子的长度, batch 的大小 , hidden_size 输出(隐藏)向量的维度
hn : num_layers 隐藏层的层数, batch 的大小 , hidden_size 隐藏向量的维度
代码示例
import torch
import torch.nn as nn
# input_size词向量的维度 hidden_size隐藏向量的维度
rnn = nn.RNN(input_size=64,hidden_size=32,num_layers=2)
# 输入数据
# seq_len 句子长度 , batch 的大小, input_size 词向量的维度
inputs= torch.randn(18,5,64)
# num_layers 隐藏层的层数 , batch 的大小 , hidden_size 隐藏向量的维度
h0 = torch.zeros(2,5,32)
# 输出结果
output,hn = rnn(inputs,h0)
# seq_len 句子的长度, batch 的大小 , hidden_size 输出(隐藏)向量的维度
print(output.shape)
# num_layers 隐藏 层的层数, batch 的大小 , hidden_size 隐藏向量的维度
print(hn.shape)