keras学习-nlp (1)
书籍《Python深度学习》——笔记小结
与其他所有神经网络一样,深度学习模型不会接收原始文本作为输入,它只能处理数值张量。
文本向量化(vectorize)是指将文本转换为数值张量的过程。它有多种实现方法。
� 将文本分割为单词,并将每个单词转换为一个向量。
� 将文本分割为字符,并将每个字符转换为一个向量。
� 提取单词或字符的 n-gram,并将每个 n-gram 转换为一个向量。n-gram 是多个连续单词
或字符的集合(n-gram 之间可重叠)
将文本分解而成的单元(单词、字符或 n-gram)叫作标记(token),将文本分解成标记的
过程叫作分词(tokenization)。所有文本向量化过程都是应用某种分词方案,然后将数值向量
与生成的标记相关联。这些向量组合成序列张量,被输入到深度神经网络中。
有两种方式:one-hot方式,embedding方式。
单词级
import numpy as np
samples = ['The cat sat on the mat.','The dog ate my homework.']
token_index = {}# 构建数据中所有标记的索引
for sample in samples:
for word in sample.split():
if word not in token_index:
token_index[word] = len(token_index)+1 # 标记序号持续+1
max_length = 10
results = np.zeros(shape=(len(samples),max_length,max(token_index.values())+1)) # 只考虑前多少个单词
# 每个样本由单词数个(或者max_length)个one_hot向量组成。
#每个样本:max_length × max(token_index.values())+1
#token_index.values() 序号依次增加 max(token_index.values())+1:序号最大的+1 (感觉是了len+1的值)(这个+1看起来并不必要)
for i,sample in enumrate(samples):
for j,word in list(enumrate(sample.split()))[:max_length]:
index = token_index.get(word)
results[i,j,index] = 1 #[i,j] 第i个sample,第j个单词
字符级
import string
import numpy as np
samples = ['The cat sat on the mat.','The dog ate my homework.']
characters = string.printable
token_index = dict(zip(characters, range(1, len(characters) + 1)))
#zip:把两个列表包装成元组。 dict:把元祖列表转化成字典。
print()
max_length = 50
results = np.zeros((len(samples), max_length, max(token_index.values()) + 1))
for i, sample in enumerate(samples):
for j, character in enumerate(sample[:max_length]):
# print(j,character)
index = token_index.get(character)
results[i, j, index] = 1.
embedding层
最好将 Embedding 层理解为一个字典,将整数索引(表示特定单词)映射为密集向量。它 接收整数作为输入,并在内部字典中查找这些整数,然后返回相关联的向量。 Embedding 层实 际上是一种字典查找。 单词索引-》 Embedding层 -》对应的词向量。
Embedding 层的输入是一个二维整数张量,其形状为 (samples, sequence_length) ,每个元素是一个整数序列。它能够嵌入长度可变的序列,例如,对于前一个例子中的Embedding 层,你可以输入形状为 (32, 10) (32 个长度为 10 的序列组成的批量)或 (64,15) (64 个长度为 15 的序列组成的批量)的批量。不过一批数据中的所有序列必须具有相同的长度(因为需要将它们打包成一个张量),所以较短的序列应该用 0 填充,较长的序列应该被截断。 这 个 Embedding 层 返 回 一 个 形 状 为 (samples, sequence_length, embedding_dimensionality) 的三维浮点数张量。然后可以用 RNN 层或一维卷积层来处理这个三维张量(二者都会在后面介绍)。 将一个 Embedding 层实例化时,它的权重(即标记向量的内部字典)最开始是随机的,与其他层一样。在训练过程中,利用反向传播来逐渐调节这些词向量,改变空间结构以便下游模型可以利用。一旦训练完成,嵌入空间将会展示大量结构,这种结构专门针对训练模型所要解决的问题。
利用本节前面介绍过的概念,我们对文本进行分词,并将其划分为训练集和验证集。
因为预训练的词嵌入对训练数据很少的问题特别有用(否则,针对于具体任务的嵌入可能效果更好),
【是这样的吗?但是之前很多时候并没有注意】
所以我们又添加了以下限制:将训练数据限定为前 200 个样本。
因此,你需要在读取 200 个样本之后学习对电影评论进行分类。
【以下:验证集远超训练集数目】
【以下:示例代码】
glove_dir = '/home/ubuntu/data/'
embeddings_index = {}
f = open(os.path.join(glove_dir,'glove.6B.100d.txt'))
for line in f:
value = line.split()
word = values[0]
coefs = np.asarray(values[1:],dtype = 'float32')
embeddings_index[word] = coefs
f.close()
#coef是词向量吧
print('Found %s word vectors.' % len(embeddings_index))
#Found 400000 word vectors
embedding_dim = 100
embedding_matrix = np.zeros((max_words,embedding_dim))#初始化词向量矩阵
for word,i in word_index.items():
embedding_vector = embeddings_index.get(word)
if i < max_words:
if embedding_vector is not None:
embedding_matrix[i] = embedding_vector#word_index中的i,得到对应的vector,词向量
from keras.models import Sequential
from keras.layers import Embedding, Flatten, Dense
model = Sequential()
model.add(Embedding(max_words, embedding_dim, input_length=maxlen))
model.add(Flatten())
model.add(Dense(32, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.summary()
model.layers[0].set_weights([embedding_matrix])#指定embedding层的矩阵
model.layers[0].trainable = False#embedding层不再进行额外的训练
网友评论