人工智能--Embedding层
Posted Abro.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了人工智能--Embedding层相关的知识,希望对你有一定的参考价值。
学习目标:
- 理解Embedding层的用法。
- 掌握利用Embedding层对单词进行向量化。
学习内容:
对如下中文词语,利用Embedding层训练,得到向量化的特征,并在二维平面上把词语显示出来,分析相应的结果。
docs = ['非常 好','很 棒','真 漂亮','真 好','做得 好','好 极了','很 差','不 行','太 差','做得 差','非常 恶心','坏 极了']
labels = array([1,1,1,1,1,1,0,0,0,0,0,0])
学习过程:
不足三个单词的中文词语用0补充, 第一个词语训练之前对应的单词向量:
第一个词语训练之后对应的单词向量:
每个中文词语对应的单词向量:
在二维平面上显示每个单词编码的位置图,如下图所示:
训练的样本量太少,中文词语的分布从上图中看不出有啥规律。
源码:
# In[2]: 利用Tokenizer类进行编码
from keras.preprocessing.text import Tokenizer
def oneHotEncode(samples):
#只考虑最常使用的前1000个单词
tokenizer = Tokenizer(num_words = 1000)
tokenizer.fit_on_texts(samples)
#把句子分解成单词数组
sequences = tokenizer.texts_to_sequences(samples)
return sequences
samples = ['The cat jump over the dog', 'The dog ate my homework']
vecs = oneHotEncode(samples)
#print(vecs) # [[1, 3, 4, 5, 1, 2], [1, 2, 6, 7, 8]]
# 如果要独热编码,则可以构造1000个元素的全0向量,然后把对应编号处的元素设为1即可
# In[3]: 使用Keras的 Embedding层 对单词的编码进行训练
from numpy import array
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
# 定义一系列简单文本,前一半表示赞美,后一半表示批判
#docs = ['Well done',
#'Good work',
#'Great effort',
#'nice work',
#'Excellent',
#'Weak',
#'Poor effort',
#'quit bad',
#'it is terrible',
#'like a shit']
docs = ['非常 好','很 棒','真 漂亮','真 好','做得 好','好 极了','很 差',
'不 行','太 差','做得 差','非常 恶心','坏 极了']
# 属于赞美性质的文本用1表示,属于批评性质的文本用0表示
#labels = array([1,1,1,1,1,0,0,0,0,0])
labels = array([1,1,1,1,1,1,0,0,0,0,0,0])
# 假定单词量有50个
vocab_size = 50
encoded_docs = oneHotEncode(docs)
print(encoded_docs)
# 规定每个文本3个单词,不足3个的用0补足
max_length = 3
padded_docs = pad_sequences(encoded_docs, maxlen=max_length, padding='post')
print(padded_docs)
model = Sequential()
'''
Embedding层本质上是一个矩阵,高为vocab_size, 宽为8,矩阵的每一行对应每个单词向量
由于我们设定每篇文本的单词量为4个,每个单词对应一个8元素的向量,
因此我们把一篇文本对应的向量也就是一个含有4个元素的向量输入Embedding层后,
得到4*8的一个二维矩阵,其中的4对应输入文本向量中元素个数,8对应每个单词的向量维度
'''
# Embedding类将正整数(索引)转换为固定大小的密集向量,通过矩阵乘法进行数据降维。
emebdding_layer = Embedding(vocab_size, 8, input_length=max_length)
model.add(emebdding_layer)
print("vector for word Well before train is:")
print(emebdding_layer.get_weights()[0][0])
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
print(model.summary())
# 训练网络
model.fit(padded_docs, labels, epochs=50, verbose=0)
print("vector for word Well after train is:")
print(emebdding_layer.get_weights()[0][0])
# In[4]:
#建立单词与编号之间的对应关系
word2Num =
for idx, doc in enumerate(docs):
words = doc.split()
for i, word in enumerate(words):
print("0 => 1".format(word, encoded_docs[idx][i]))
word2Num[word] = encoded_docs[idx][i]
embeddings = emebdding_layer.get_weights()[0]
#建立单词与向量之间的连续
vectors = []
words = []
for word, num in word2Num.items():
print("0 => 1".format(word, embeddings[num]))
words.append(word)
vectors.append(embeddings[num])
# In[5]: 在二维平面上显示每个单词编码的位置图
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus'] = False #显示负号
tsne_model = TSNE(perplexity=40, n_components=2, init='pca', n_iter=2500, random_state=23)
new_values = tsne_model.fit_transform(vectors)
x = []
y = []
for value in new_values:
x.append(value[0])
y.append(value[1])
plt.figure(figsize=(10, 10))
plt.title('单词编码位置图')
for i in range(len(x)):
plt.scatter(x[i], y[i])
plt.annotate(words[i], xy=(x[i], y[i]), xytext=(5,2), textcoords='offset points',
ha='right',va='bottom')
plt.show()
学习产出:
- 理解了利用Embedding层对单词进行向量化的方法。
以上是关于人工智能--Embedding层的主要内容,如果未能解决你的问题,请参考以下文章