人工智能--Embedding层

Posted Abro.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了人工智能--Embedding层相关的知识,希望对你有一定的参考价值。

学习目标:

  1. 理解Embedding层的用法。
  2. 掌握利用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()

 源码下载


学习产出:

  1. 理解了利用Embedding层对单词进行向量化的方法。

以上是关于人工智能--Embedding层的主要内容,如果未能解决你的问题,请参考以下文章

Keras官方中文文档:嵌入层Embedding

keras的Embedding层

Embedding层实现

搜广推 召回层主流策略 (多路召回Embedding召回)

embedding层作用

使用 Embedding 层创建 Keras 深度学习模型,但在训练时返回错误