文章目录
代码展示
import pandas as pd
import tensorflow as tf
# 构建RNN神经网络
tf.random.set_seed(1)
df = pd.read_csv("../data/Clothing Reviews.csv")
print(df.info())
df['Review Text'] = df['Review Text'].astype(str)
x_train = df['Review Text']
y_train = df['Rating']
from tensorflow.keras.preprocessing.text import Tokenizer
# 创建词典的索引,默认词典大小20000
dict_size = 14848
tokenizer = Tokenizer(num_words=dict_size)
# jieba: 停用词,标点符号,词性.....
tokenizer.fit_on_texts(x_train)
print(len(tokenizer.word_index), tokenizer.index_word)
# # 把评论的文本转化序列编码
x_train_tokenized = tokenizer.texts_to_sequences(x_train)
# # 通过指定长度,把不等长list转化为等长
from tensorflow.keras.preprocessing.sequence import pad_sequences
max_comment_length = 120
x_train = pad_sequences(x_train_tokenized, maxlen=max_comment_length)
for v in x_train[:10]:
print(v, len(v))
# 构建RNN神经网络
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, SimpleRNN, Embedding
import tensorflow as tf
rnn = Sequential()
# 对于rnn来说首先进行词向量的操作
rnn.add(Embedding(input_dim=dict_size, output_dim=60, input_length=max_comment_length))
rnn.add(SimpleRNN(units=100)) # 第二层构建了100个RNN神经元
rnn.add(Dense(units=10, activation=tf.nn.relu))
rnn.add(Dense(units=6, activation=tf.nn.softmax)) # 输出分类的结果
rnn.compile(loss='sparse_categorical_crossentropy', optimizer="adam", metrics=['accuracy'])
print(rnn.summary())
result = rnn.fit(x_train, y_train, batch_size=64, validation_split=0.3, epochs=1)
print(result)
print(result.history)
代码意图
该代码的主要目的是构建一个简单的RNN(循环神经网络)来对"Clothing Reviews.csv"中的评论进行分类。评论文本被转换为数值序列,然后使用这些序列来训练RNN模型,以预测评论的评分。
流程描述:
-
设置随机种子:确保结果的可重复性。
tf.random.set_seed(1)
-
读取数据:使用pandas读取"Clothing Reviews.csv"文件,并打印数据信息。
df = pd.read_csv("../data/Clothing Reviews.csv") print(df.info())
-
数据预处理:
- 将’Review Text’列转换为字符串类型。
- 从数据框中提取训练数据
x_train
和标签y_train
。df['Review Text'] = df['Review Text'].astype(str) x_train = df['Review Text'] y_train = df['Rating']
-
文本标记化:
-
使用
Tokenizer
进行文本标记,创建一个字典来将每个词映射到一个整数值。 -
通过调用
fit_on_texts
方法对评论文本进行学习。dict_size = 14848 tokenizer = Tokenizer(num_words=dict_size) tokenizer.fit_on_texts(x_train)
-
将评论文本转换为整数序列。
x_train_tokenized = tokenizer.texts_to_sequences(x_train)
-
-
序列填充:为了确保所有序列长度相同,使用
pad_sequences
对序列进行填充或截断。max_comment_length = 120 x_train = pad_sequences(x_train_tokenized, maxlen=max_comment_length)
-
构建RNN模型:
- 初始化一个序贯模型
Sequential
。 - 添加一个
Embedding
层,将词汇转换为固定大小的向量。 - 添加一个
SimpleRNN
层,含有100个神经元。 - 添加两个全连接层
Dense
,用于分类任务。 - 编译模型,设置损失函数、优化器和评估标准。
rnn = Sequential() rnn.add(Embedding(input_dim=dict_size, output_dim=60, input_length=max_comment_length)) rnn.add(SimpleRNN(units=100)) rnn.add(Dense(units=10, activation=tf.nn.relu)) rnn.add(Dense(units=6, activation=tf.nn.softmax)) rnn.compile(loss='sparse_categorical_crossentropy', optimizer="adam", metrics=['accuracy'])
模型结构
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding (Embedding) (None, 120, 60) 890880 simple_rnn (SimpleRNN) (None, 100) 16100 dense (Dense) (None, 10) 1010 dense_1 (Dense) (None, 6) 66
- 初始化一个序贯模型
-
模型摘要:打印模型的摘要,显示各层的细节。
print(rnn.summary())
-
训练模型:使用提取的数据训练RNN模型,并将30%的数据用作验证集。训练1个epoch。
result = rnn.fit(x_train, y_train, batch_size=64, validation_split=0.3, epochs=1)
-
打印结果:显示模型的训练历史。
print(result) print(result.history)
总之,这段代码首先进行数据预处理,然后构建和训练一个RNN模型来对评论进行分类。
代码解读
当然可以!下面是逐行解读的代码:
-
tf.random.set_seed(1):
- 设置全局随机种子为1,确保随机过程的可重复性。
-
df = pd.read_csv(“…/data/Clothing Reviews.csv”):
- 使用pandas读取CSV文件,并将其内容赋值给
df
。
- 使用pandas读取CSV文件,并将其内容赋值给
-
print(df.info()):
- 打印
df
的简要摘要,包括每列的非空值数量、数据类型等信息。
- 打印
-
df[‘Review Text’] = df[‘Review Text’].astype(str):
- 将DataFrame中的’Review Text’列转换为字符串类型。
-
x_train = df[‘Review Text’]:
- 从
df
中提取’Review Text’列的内容,并将其赋值给x_train
。
- 从
-
y_train = df[‘Rating’]:
- 从
df
中提取’Rating’列的内容,并将其赋值给y_train
。
- 从
-
from tensorflow.keras.preprocessing.text import Tokenizer:
- 从TensorFlow库中导入文本标记化工具。
-
dict_size = 14848:
- 设置词汇表的大小为14848。
-
tokenizer = Tokenizer(num_words=dict_size):
- 初始化一个Tokenizer对象,其最大词汇数为
dict_size
。
- 初始化一个Tokenizer对象,其最大词汇数为
-
tokenizer.fit_on_texts(x_train):
- 根据
x_train
中的文本内容为tokenizer对象构建词汇表。
- print(len(tokenizer.word_index), tokenizer.index_word):
- 打印词汇表的大小和具体的词-索引映射。
- x_train_tokenized = tokenizer.texts_to_sequences(x_train):
- 将
x_train
中的文本转换为整数序列,并赋值给x_train_tokenized
。
- from tensorflow.keras.preprocessing.sequence import pad_sequences:
- 从TensorFlow库中导入序列填充工具。
- max_comment_length = 120:
- 设置评论的最大长度为120。
- x_train = pad_sequences(x_train_tokenized, maxlen=max_comment_length):
- 将
x_train_tokenized
中的序列填充或截断为统一的长度(120)。
- for v in x_train[:10]: print(v, len(v)):
- 打印
x_train
中前10个序列及其长度。
- from tensorflow.keras.models import Sequential 和其他导入语句:
- 从TensorFlow库中导入所需的模型和层。
- rnn = Sequential():
- 初始化一个Sequential模型对象,并赋值给
rnn
。
- rnn.add(Embedding(…)):
- 向模型中添加一个Embedding层。
- rnn.add(SimpleRNN(units=100)):
- 添加一个包含100个神经元的SimpleRNN层。
- rnn.add(Dense(units=10, activation=tf.nn.relu)):
- 添加一个全连接层,包含10个神经元并使用ReLU激活函数。
- rnn.add(Dense(units=6, activation=tf.nn.softmax)):
- 添加输出层,包含6个神经元,并使用Softmax激活函数。
- rnn.compile(…):
- 编译模型,指定损失函数、优化器和评估标准。
- print(rnn.summary()):
- 打印模型的摘要,展示每层的参数数量。
- result = rnn.fit(…):
- 使用指定的训练数据和验证数据集进行模型训练,并将训练结果赋值给
result
。
- print(result):
- 打印训练过程的结果。
- print(result.history):
- 打印训练过程中的历史数据,如每个周期的损失和准确率。
该代码的主要目的是使用Recurrent Neural Network (RNN)来对"Clothing Reviews.csv"中的评论进行分类。
知识点介绍
当然可以!以下是对每个重要函数的详细介绍:
-
tf.random.set_seed(1):
- 功能:设置全局随机种子,确保随机过程的可重复性。
-
pd.read_csv(“…/data/Clothing Reviews.csv”):
- 功能:使用pandas库读取CSV文件,并返回一个DataFrame对象。
-
df[‘Review Text’].astype(str):
- 功能:将DataFrame中的’Review Text’列转换为字符串类型。
-
Tokenizer(num_words=dict_size):
- 功能:初始化一个Tokenizer对象,该对象可以将文本转换为整数序列。
- 参数:num_words表示Tokenizer对象将使用的最大单词数。这意味着只有出现频率最高的
dict_size
个词将被考虑。
-
tokenizer.fit_on_texts(x_train):
- 功能:根据提供的文本数据,为Tokenizer对象构建词汇表。
-
tokenizer.texts_to_sequences(x_train):
- 功能:将文本列表转换为整数序列列表,其中整数是词汇表中词的索引。
-
pad_sequences(x_train_tokenized, maxlen=max_comment_length):
- 功能:将整数序列列表转换为2D Numpy数组,长度不足的序列将被填充,长度超出的序列将被截断。
- 参数:maxlen定义了序列的最大长度。
-
Sequential():
- 功能:初始化一个线性堆叠模型,允许按顺序添加层。
-
Embedding(input_dim=dict_size, output_dim=60, input_length=max_comment_length):
- 功能:将整数标记转换为密集向量。
- 参数:input_dim是词汇表的大小,output_dim是嵌入向量的维度,input_length是输入序列的长度。
-
SimpleRNN(units=100):
- 功能:添加一个SimpleRNN层,它是RNN的一个简化版本。
- 参数:units定义了RNN单元的数量。
- Dense(units=10, activation=tf.nn.relu) 和 Dense(units=6, activation=tf.nn.softmax):
- 功能:添加一个全连接层。
- 参数:units定义了层中神经元的数量,activation是激活函数。
- rnn.compile(…):
- 功能:编译模型,准备进行训练。
- 参数:loss定义了损失函数,optimizer定义了优化算法,metrics定义了模型评估的标准。
- rnn.fit(x_train, y_train, batch_size=64, validation_split=0.3, epochs=1):
- 功能:训练模型。
- 参数:batch_size定义了每次梯度更新使用的样本数量,validation_split定义了用于验证的数据的比例,epochs定义了训练周期的数量。
这些函数共同完成了数据处理、模型构建和训练的过程。希望这些详细的介绍能够帮助您更好地理解代码!
模型结构的参数计算
rnn = Sequential()
rnn.add(Embedding(input_dim=dict_size, output_dim=60, input_length=max_comment_length))
rnn.add(SimpleRNN(units=100))
rnn.add(Dense(units=10, activation=tf.nn.relu))
rnn.add(Dense(units=6, activation=tf.nn.softmax))
rnn.compile(loss='sparse_categorical_crossentropy', optimizer="adam", metrics=['accuracy'])
模型结构
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding (Embedding) (None, 120, 60) 890880
simple_rnn (SimpleRNN) (None, 100) 16100
dense (Dense) (None, 10) 1010
dense_1 (Dense) (None, 6) 66
图中红框标记的是神经网络各层的参数数量。每一层的参数数量是根据层的输入和输出大小以及层的类型计算出来的。这里是如何计算每一层参数的:
1. 嵌入层(Embedding Layer)
参数数量是词汇表大小(input_dim
)乘以嵌入维度(output_dim
)。如果词汇表有 20,000 个词,每个词被映射到 60 维空间,则参数数量是 20,000 * 60 = 1,200,000。图中显示的是 898,880,这暗示词汇表大小可能约为 14,981(因为 898,880 / 60 ≈ 14,981)。
(None, 120, 60) 是输入RNN的矩阵,None代表评论的数量,每条评论长短不一(我们统一为120,因为最大为120),每个词的特征都是60。
(None, 120, 60) – 》 【评论数, 每条评论的长度, 词向量】 --》【评论数,词向量】
循环神经网络它是一个序列结构,每条评论有120个词,这120个词,会逐个进入神经网络中,每个词都有60个特征。假设该神经网络每秒处理一个词,120个词需要2分钟,每个词进来的时候,都有60个特征。在时序神经网络中,这120个词是随着时间的推移一个一个进去的,但是每一个词最后的结构,【评论数,词向量】(到神经网络的就是这个东西
2. 简单RNN层(SimpleRNN Layer)
一个简单的 RNN 层的参数数量由三部分组成:输入到隐藏状态的权重(input_dim * units
),隐藏状态到隐藏状态的权重(units * units
),以及偏置项(units
)。计算公式是 (input_dim + units) * units + units
。如果输入维度是 60(从嵌入层来),单元数是 100,则参数数量是 (60 + 100) * 100 + 100 = 16,100。
3. 全连接层(Dense Layer)
全连接层的参数数量是输入单元数乘以输出单元数,再加上输出单元数的偏置项。如果前一层有 100 个单元,这一层有 10 个单元,则参数数量是 100 * 10 + 10 = 1,010。
4. 第二个全连接层(Dense Layer)
同上,如果前一层有 10 个单元,这一层有 6 个单元,则参数数量是 10 * 6 + 6 = 66。
参数计算是构建和训练神经网络时考虑计算成本和模型容量的一个重要因素。每个参数都需要通过训练数据来学习,因此参数的数量直接影响模型的学习能力和训练时间。