【NLP】关于Word2Vec词向量与keras的Embedding层的学习总结

目录

1、Keras 嵌入层

2、在keras的嵌入层中学习词嵌入

2.1、one_hot

2.2、pad_sequences

2.3学习嵌入实例

3、使用预训练的词向量进行嵌入学习

1、Keras 嵌入层

Keras的嵌入层使用随机权重初始化,并将学习所有数据集中词的嵌入。

它是一个灵活的层,可以以各种方式使用,如:

1.它可以单独使用来学习一个字嵌入,以后可以在另一个模型中使用。

2.它可以用作深度学习模型的一部分,其中嵌入与模型本身一起被学习。

3.它可以用于加载预训练的词嵌入模型,是种迁移学习,将词嵌入模型转换为权重矩阵输入keras的Embedding层

keras.layers.Embedding(input_dim, output_dim, embeddings_initializer='uniform', embeddings_regularizer=None, activity_regularizer=None, embeddings_constraint=None, mask_zero=False, input_length=None) 

 

输入尺寸

尺寸为 (样本数, sequence_length(句子长度,句子的词长度需要人为统一)) 的 2D 张量。

输出尺寸

尺寸为 (样本数, sequence_length, output_dim(嵌入后的设定向量维度)) 的 3D 张量。

如果希望连接密集(dense)层直接到嵌入层,必须首先将y和z压缩到一行,形成一个(x,yz)的2D矩

2、在keras的嵌入层中学习词嵌入

keras embeding设置初始值有两种方式:随机初始化Embedding,使用weights参数指明embedding初始值

这里是随机初始化Embedding,对数据集中的word进行词嵌入学习

2.1、one_hot

将文本编码为大小为 n 的单词索引列表,将文本单词映射为数字。

2.2、pad_sequences

Keras需要输入具有相同的长度。keras只能接受长度相同的序列输入。因此句子具有不同的长度,这时需要使用pad_sequences()。该函数是将序列转化为经过填充以后的一个长度相同的新序列新序列。

keras.preprocessing.sequence.pad_sequences(sequences, 
	maxlen=None,
	dtype='int32',
	padding='pre',
	truncating='pre', 
	value=0.)

参数说明

返回值

返回的是个2维张量,长度为maxlen

实例 

>>>list_1 = [[2,3,4]]
>>>keras.preprocessing.sequence.pad_sequences(list_1, maxlen=10)
array([[0, 0, 0, 0, 0, 0, 0, 2, 3, 4]], dtype=int32)

>>>list_2 = [[1,2,3,4,5]]
>>>keras.preprocessing.sequence.pad_sequences(list_2, maxlen=10)
array([[0, 0, 0, 0, 0, 1, 2, 3, 4, 5]], dtype=int32)

2.3学习嵌入实例

from keras.preprocessing.text import one_hot
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.embeddings import Embedding
# define documents
docs = ['Well done!',
		'Good work',
		'Great effort',
		'nice work',
		'Excellent!',
		'Weak',
		'Poor effort!',
		'not good',
		'poor work',
		'Could have done better.']
# define class labels
labels = [1,1,1,1,1,0,0,0,0,0]
# integer encode the documents
vocab_size = 50
encoded_docs = [one_hot(d, vocab_size) for d in docs]
print(encoded_docs)
# pad documents to a max length of 4 words
'''该嵌入具有50词汇及输入长度为4,我们将选择8尺寸的小嵌入空间。
该模型是一个简单的二进制分类模型。重要的是,嵌入层的输出将是4个向量,每个向量8个维度,每个单词一个。将其平坦化为一个32维度的向量,以传递到Dense输出层。'''
max_length = 4
padded_docs = pad_sequences(encoded_docs, maxlen=max_length, padding='post')
print(padded_docs)
# define the model
model = Sequential()
model.add(Embedding(vocab_size, 8, input_length=max_length))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
# summarize the model
print(model.summary())
# fit the model
model.fit(padded_docs, labels, epochs=50, verbose=0)
# evaluate the model
loss, accuracy = model.evaluate(padded_docs, labels, verbose=0)
print('Accuracy: %f' % (accuracy*100))

3、使用预训练的词向量进行嵌入学习

使用weights参数指明embedding初始值

1、将整个GloVe字嵌入文件作为字嵌入数组的字典加载到内存中。

将单词映射到整数以及整数到单词。Keras提供了一个标记生成器类,可以配合训练数据,可以将文本转换为序列,通过调用texts_to_sequences()的方法标记生成器的类,并提供访问字的字典映射到整数在word_index属性。

2、 为训练数据集中的每个单词创建一个嵌入矩阵。

通过枚举Tokenizer.word_index中的所有唯一的字,并从加载的GloVe嵌入中定位嵌入权重向量。

3、定义模型,训练和评估。

关键区别是嵌入层可以用GloVe字嵌入权重进行迁移。我们选择了100维版本,因此嵌入层必须用output_dim定义为100。最后,我们不更新此模型中学习的单词权重,因此我们将将模型的可训练属性设置为False。

鼓励尝试使用固定的预训练嵌入学习

from numpy import asarray
from numpy import zeros
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers import Embedding
# define documents
docs = ['Well done!',
		'Good work',
		'Great effort',
		'nice work',
		'Excellent!',
		'Weak',
		'Poor effort!',
		'not good',
		'poor work',
		'Could have done better.']
# define class labels
labels = [1,1,1,1,1,0,0,0,0,0]
# prepare tokenizer
t = Tokenizer()
t.fit_on_texts(docs)
vocab_size = len(t.word_index) + 1
# integer encode the documents
encoded_docs = t.texts_to_sequences(docs)
print(encoded_docs)
# pad documents to a max length of 4 words
max_length = 4
padded_docs = pad_sequences(encoded_docs, maxlen=max_length, padding='post')
print(padded_docs)
# load the whole embedding into memory
embeddings_index = dict()
f = open('../glove_data/glove.6B/glove.6B.100d.txt')
for line in f:
	values = line.split()
	word = values[0]
	coefs = asarray(values[1:], dtype='float32')
	embeddings_index[word] = coefs
f.close()
print('Loaded %s word vectors.' % len(embeddings_index))
# create a weight matrix for words in training docs
embedding_matrix = zeros((vocab_size, 100))
for word, i in t.word_index.items():
	embedding_vector = embeddings_index.get(word)
	if embedding_vector is not None:
		embedding_matrix[i] = embedding_vector
# define model
model = Sequential()
e = Embedding(vocab_size, 100, weights=[embedding_matrix], input_length=4, trainable=False)
model.add(e)
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
# summarize the model
print(model.summary())
# fit the model
model.fit(padded_docs, labels, epochs=50, verbose=0)
# evaluate the model
loss, accuracy = model.evaluate(padded_docs, labels, verbose=0)
print('Accuracy: %f' % (accuracy*100))

两个小例子带你词嵌入层学习入门

Keras—embedding嵌入层的用法详解

猜你喜欢

转载自blog.csdn.net/m0_51933492/article/details/127291529