对RNN网络的预操作:
因为我们如果要看数据在经过各个网络结构的维度变化,所以 就需要将每一层变化后的输入输出值打印出来(在模型构建的时候)。
代码
def construct(self, inputs):
embedded = self.embedding(inputs) #将input放入嵌入层
print(embedded.shape) #打印数据经过嵌入层的形状,以此作为下一层的输入值
_, (hidden, _) = self.rnn(embedded)#将经过嵌入层的数据传入隐藏层,这里存在正向和反向两个隐藏层以增强特征
print(hidden.shape) #打印单个隐藏层的形状
hidden = ops.concat((hidden[-2, :, :], hidden[-1, :, :]), axis=1)
#将正向反向隐藏层合并
print(hidden.shape) #打印合并后的形状,以此作为全连接层的输入
output = self.fc(hidden) #将合并后的数据传入全连接层层
print(output.shape) #打印最终数据的形状
return output
各层作用
-
嵌入层(
self.embedding(inputs))将输入的离散整数序列(如文本的词索引)转换为连续的低维稠密向量(词向量)。这些向量通过学习获得,能够捕捉词与词之间的语义关联(如近义词的向量更相似),将离散的符号信息转化为模型可理解的连续特征。 -
RNN 层(
self.rnn(embedded))以嵌入层输出的词向量序列为输入,通过循环神经网络(RNN)提取序列的时序特征。由于代码中涉及正向和反向隐藏状态,推测为双向 RNN—— 既从序列开头到结尾(前向)、也从结尾到开头(后向)处理序列,从而同时捕捉两个方向的时序依赖关系(如上下文语义),增强对整个序列的理解。 -
拼接操作(
ops.concat(...))将双向 RNN 最后一层的前向隐藏状态和后向隐藏状态进行融合。前向状态捕捉了从左到右的序列信息,后向状态捕捉了从右到左的序列信息,拼接后可综合两种视角的特征,得到更全面的序列全局表示。 -
全连接层(
self.fc(hidden))以拼接后的融合特征为输入,通过全连接层将高维特征映射到具体任务的输出空间。在分类任务中(如文本情感分析),其作用是将融合后的序列特征转换为对应类别的预测结果(如二分类中的 “正面 / 负面” 分数)。
批次数据的提取
思路
实例化迭代器使用next()方法将imdb_train一个批次的数据提取出来
代码
model = RNN(embeddings, hidden_size, output_size, num_layers, bidirectional, pad_idx)
#^模型的实例化
one_batch = next(iter(imdb_train)) #实例化迭代器将第一批次的数据取出,这里一个批次为64
input,label = one_batch #将数据的输入和标签分离
model(dataw) #将数据丢入模型查看数据经过各层的维度变化
输出
输出内容

对输出内容的解释
输入数据 input(输入)(64*500)
64:批次大小,即当前批次包含64个文本。
500:序列长度(sequence length),每个文本样本被截断 / 填充为 500 个词(每个词用整数索引表示,如 “3” 代表词典中第 3 个词)。
经过embedding(嵌入层)(64*500*100)
64:批次。
500:序列长度。
100:嵌入维度(embedding dimension),即每个词的整数索引被映射为 100 维的稠密向量(通过嵌入层学习到的语义向量,捕捉词与词之间的关联)。
两个隐藏层(向前&向后)(4,64,256)
4:表示 “层数 × 方向数”。结合形状推测为2 层双向 RNN(2 层 × 2 方向(前向 / 后向)= 4)。
64:批次
256:RNN 隐藏层维度(每个 RNN 单元的输出特征维度)。
隐藏层合并(64,512)
64:批次
512:即 “64 个样本,每个样本用 512 维向量表示(融合了最后一层双向 RNN 的全局时序信息)”。
全连接层(64,1)
64:批次
1:结果,通常是概率(0~1)

被折叠的 条评论
为什么被折叠?



