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])
输出结果: