Embedding实现1pre1
1.Embedding -- 一种编码方法
- 为什么使用Embedding?
独热码:独热码的位宽要与词汇量一致,如果词汇量增大时,非常浪费资源。数据量大、 过于稀疏,映射之间是独立的,没有表现出关联性 。
Embedding:是一种单词编码方法,用低维向量实现了编码。 这种编码通过神经网络训练优化, 能表达出单词间的相关性。
- Tensorflow2 中的词向量空间编码层:


2.Embedding实现1pre1
与独热编码不同的是因为需要把输入特征变成 Embedding 层期待的形状: 第一个维度是送入样本数、第二个维度是循环核时间展开步数

在模型部分相比于独热编码形式多了一个 Embedding 层对输入数据进行编码,这一层会生成一个五行两列的可训练参数矩阵,实现编码可训练。

只需要将读到的输入字母直接查找表示它的ID 值,然后调整为 Embedding 层希望的形状输入网络进行预测即可。

predict(输入数据, batch_size=整数) 返回前向传播计算结果
注: predict 参数详解。
(1)x: 输入数据, Numpy 数组(或者 Numpy 数组的列表,如果模型有多个输出);
(2)batch_size: 整数,由于 GPU 的特性, batch_size最好选用 8, 16, 32, 64……, 如果未指定,默认为 32;
(3)verbose: 日志显示模式, 0 或 1;
(4)steps: 声明预测结束之前的总步数(批次样本), 默认值 None;
(5)返回:预测的 Numpy 数组(或数组列表)
#! /usr/bin/env python
# -*- coding:utf-8 -*-
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dense, SimpleRNN, Embedding
import matplotlib.pyplot as plt
import os
input_word = 'abcde'
# 单词映射到数值id的字典
w_to_id = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4}
x_train = [w_to_id['a'], w_to_id['b'], w_to_id['c'], w_to_id['d'], w_to_id['e']]
y_train = [w_to_id['b'], w_to_id['c'], w_to_id['d'], w_to_id['e'], w_to_id['a']]
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
tf.random.set_seed(7)
# 使x_train符合Embedding输入要求:[送入样本数, 循环核时间展开步数]。
# 此处整个数据集送入,送入样本数为len(x_train);输入1个字母出结果,循环核时间展开步数为1;
x_train = np.reshape(x_train, (len(x_train), 1))
y_train = np.array(y_train)
# 逐层搭建网络,设计一个3个记忆体的循环层+一个全连接层
# Embedding(5, 2)词汇表大小是5,每个字母用两个数字表示,编码维度是2
model = tf.keras.Sequential([
Embedding(5, 2),
SimpleRNN(3),
Dense(5, activation='softmax')
])
# 配置训练方法
model.compile(
optimizer=tf.keras.optimizers.Adam(0.01),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy']
)
# 设置模型保存路径
checkpoint_save_path = "./checkpoint/rnn_embedding_1pre1.ckpt"
# 判断保存的模型是否存在
if os.path.exists(checkpoint_save_path + '.index'):
print('------------------load the model-------------------')
# 读取模型
model.load_weights(checkpoint_save_path)
# 保存模型,借助tensorflow给出的回调函数,直接保存参数和网络
'''
monitor 配合 save_best_only 可以保存最优模型,包括:训练损失最小模型、测试损失最小模型、训练准确率最高模型、测试准确率最高模型等。
'''
cp_callback = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_save_path,
save_weights_only=True,
save_best_only=True,
monitor='loss' # 由于fit没有给出测试集,不计算测试集准确率,根据loss,保存最优模型
)
# 执行训练过程
history = model.fit(x_train, y_train, batch_size=32, epochs=100, callbacks=[cp_callback])
# 对网络结构参数的统计
model.summary()
# 参数提取,写到weights.txt文本中
file = open('./weights.txt', 'w')
# model.trainable_variables 返回模型中可训练的参数
for v in model.trainable_variables:
file.write(str(v.name) + '\n')
file.write(str(v.shape) + '\n')
file.write(str(v.numpy()) + '\n')
file.close()
############################################### show ###############################################
# 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
loss = history.history['loss']
plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.title('Training Accuracy') # 图标题
plt.legend() # 图例
plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.title('Training Loss') # 图标题
plt.legend() # 图例
plt.show()
############### predict #############
preNum = int(input('input the number of test alphbet:'))
for i in range(preNum):
alphabet1 = input("input test alphabet:")
# 变成模型需要的输入
alphabet = [w_to_id[alphabet1]]
# 使alphabet符合Embedding输入要求:[送入样本数, 循环核时间展开步数]。
# 此处验证效果送入了1个样本,送入样本数为1;输入1个字母出结果,所以循环核时间展开步数为1;
alphabet = np.reshape(alphabet, (1, 1))
result = model.predict(alphabet)
pred = tf.argmax(result, axis=1)
pred = int(pred)
tf.print(alphabet1 + '->' + input_word[pred])
输出结果:



浙公网安备 33010602011771号