RNN 情感分类问题实战
#RNN 情感分类问题实战
#import os
import tensorflow as tf
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers, losses, optimizers, Sequential
tf.random.set_seed(22)
np.random.seed(22)
batchsz = 512 # 批量大小
total_words = 10000 # 词汇表大小N_vocab
max_review_len = 80 # 句子最大长度s,大于的句子部分将截断,小于的将填充
embedding_len = 100 # 词向量特征长度f
# 加载IMDB数据集,此处的数据采用数字编码,一个数字代表一个单词
#(x_train, y_train), (x_test, y_test) = keras.datasets.imdb.load_data(num_words=total_words)
# 将数据保存到本地文件
#np.savez_compressed('data/ch12DL/imdb_data.npz', x_train=x_train, y_train=y_train, x_test=x_test, y_test=y_test)
#上面的代码将 IMDb 数据集下载并保存为一个名为 imdb_data.npz 的压缩文件。在这个文件中,你将包含训练集和测试集的输入数据 (x_train, x_test) 以及相应的标签数据 (y_train, y_test)。
#当你需要加载这些本地数据时,可以使用以下代码:
data = np.load('imdb_data.npz',allow_pickle=True)
x_train, y_train, x_test, y_test = data['x_train'], data['y_train'], data['x_test'], data['y_test']
print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
#查看样本数据
id=20
#此处的数据采用数字编码,一个数字代表一个单词
####参考教材内容,补全关键代码,重新运行#####
print(x_train(id))
#word_index = keras.datasets.imdb.get_word_index()
# 保存 word_index 字典到本地文件
#np.save("data/ch12DL/imdb_word_index.npy", word_index)
# 从本地文件重新加载 word_index 字典
word_index = np.load("imdb_word_index.npy", allow_pickle=True).item()
####参考教材内容,补全关键代码,重新运行#####
word_index=keras.datasets.imdb.get_word_index()
print(word_index)
word_index = {k:(v+3) for k,v in word_index.items()}
word_index["<PAD>"] = 0
word_index["<START>"] = 1
word_index["<UNK>"] = 2 # unknown
word_index["<UNUSED>"] = 3
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
#print(reverse_word_index)
def decode_data(text):
return ' '.join([reverse_word_index.get(i, '?') for i in text])
#查看样本数据
id=20
#此处的数据采用数字编码,一个数字代表一个单词
print(x_train[id])
# #查看样本数据:变换后
####参考教材内容,补全关键代码,重新运行#####
print(decode_data(x_train[id]))
# 截断和填充句子,使得等长,此处长句子保留句子后面的部分,短句子在前面填充
x_train = keras.preprocessing.sequence.pad_sequences(x_train, maxlen=max_review_len)
####参考教材内容,补全关键代码,重新运行#####
x_test= keras.preprocessing.sequence.pad_sequences(x_test, maxlen=max_review_len)
# 构建数据集,打散,批量,并丢掉最后一个不够batchsz的batch
db_train = tf.data.Dataset.from_tensor_slices((x_train, y_train))
db_train = db_train.shuffle(1000).batch(batchsz, drop_remainder=True)
####参考教材内容,补全关键代码,重新运行#####
db_test=tf.data.Dataset.from_tensor_slices((x_test,y_test))
db_test=db_test.batch(batchsz,drop_remainder=True)
print('x_train shape:', x_train.shape, tf.reduce_max(y_train), tf.reduce_min(y_train))
print('x_test shape:', x_test.shape)
#查看样本数据
####参考教材内容,补全关键代码,重新运行#####
decode_data(x_train[id])
class RNN_Model(keras.Model):
# Cell方式构建多层网络
def __init__(self, units):
super(RNN_Model, self).__init__()
# 词向量编码 [b, 80] => [b, 80, 100]
####参考教材内容,补全关键代码,重新运行#####
self.embedding=layers.Embedding(total_words,embedding_len,input_length=max_review_len)
# 构建RNN ,SimpleRNN方式
####参考教材内容,补全关键代码,重新运行#####
self.rnn=keras.Sequential([
layers.SimpleRNN(units,dropout=0.5,return_sequences=True),
layers.SimpleRNN(units,dropout=0.5)
])
# 构建分类网络,用于将CELL的输出特征进行分类,2分类
# [b, 80, 100] => [b, 64] => [b, 1]
####参考教材内容,补全关键代码,重新运行#####
self.outlayer=sequential([
layers.Dense(32),
layers.Dropout(rate=0.5),
layers.ReLU(),
layers.Dense(1)])
def call(self, inputs, training=None):
x = inputs # [b, 80]
# embedding: [b, 80] => [b, 80, 100]
x = self.embedding(x)
# rnn cell compute,[b, 80, 100] => [b, 64]
x = self.rnn(x)
# 末层最后一个输出作为分类网络的输入: [b, 64] => [b, 1]
x = self.outlayer(x,training)
# p(y is pos|x)
prob = tf.sigmoid(x)
return prob
if __name__ == '__main__':
units = 64 # RNN状态向量长度f
epochs = 6 #50 # 训练epochs
model = RNN_Model(units)
# 装配
####参考教材内容,补全关键代码,重新运行#####
model.compile(optimizer=optimizers.Adam(0.0001),loss=losses.BinaryCrossentropy(),metrics=['accuracy'])
# 训练和验证
####参考教材内容,补全关键代码,重新运行#####
model.fit(db_train,epochs=epochs,validation_data=db_test)
# 测试
model.evaluate(db_test)