论文辅助笔记:T2VEC一个疑虑:stackingGRUCell和GRU的区别在哪里?

1 stackingGRUCell

python 复制代码
class StackingGRUCell(nn.Module):
    """
    Multi-layer CRU Cell
    """
    def __init__(self, input_size, hidden_size, num_layers, dropout):
        super(StackingGRUCell, self).__init__()
        self.num_layers = num_layers
        self.grus = nn.ModuleList()
        self.dropout = nn.Dropout(dropout)

        self.grus.append(nn.GRUCell(input_size, hidden_size))
        for i in range(1, num_layers):
            self.grus.append(nn.GRUCell(hidden_size, hidden_size))
python 复制代码
    def forward(self, input, h0):
        """
        Input:
        input (batch, input_size): input tensor
        h0 (num_layers, batch, hidden_size): initial hidden state
        ---
        Output:
        output (batch, hidden_size): the final layer output tensor
        hn (num_layers, batch, hidden_size): the hidden state of each layer
        """
        hn = []
        output = input
        for i, gru in enumerate(self.grus):
            hn_i = gru(output, h0[i])
            #在每一次循环中,输入output会经过一个GRU单元并更新隐藏状态

            hn.append(hn_i)
            if i != self.num_layers - 1:
                output = self.dropout(hn_i)
            else:
                output = hn_i
            #如果不是最后一层,输出会经过一个dropout层。

        hn = torch.stack(hn)
        #将hn列表转变为一个张量
        return output, hn
  • nn.GRU中,hn表示每层的最后一个时间步的隐藏状态。这意味着,对于一个具有seq_len的输入序列,hn会包含每层的seq_len时间步中的最后一个时间步的隐藏状态。
  • StackingGRUCell中,hn是通过每层的GRUCell为给定的单一时间步计算得到的。
  • 所以,**如果seq_len为1,那么nn.GRU的hn和StackingGRUCell的hn应该是相同的?**output更应是如此

2 作为对比的普通GRU

啥也没有的一个普通GRU:

python 复制代码
class StackingGRU_tst(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, dropout):
        super(StackingGRU_tst, self).__init__()
        self.gru = nn.GRU(input_size, hidden_size, num_layers=num_layers, dropout=dropout, batch_first=True)

    def forward(self, input, h0):
        output, hn = self.gru(input, h0)
        return output, hn
python 复制代码
input_size = 5
hidden_size = 10
num_layers = 3
dropout = 0.1
batch_size = 7

3 二者对比前的一些工作

3.1 创建模型

python 复制代码
gru_cell_model = StackingGRUCell(input_size, hidden_size, num_layers, dropout)
gru_cell_model
'''
StackingGRUCell(
  (grus): ModuleList(
    (0): GRUCell(5, 10)
    (1): GRUCell(10, 10)
    (2): GRUCell(10, 10)
  )
  (dropout): Dropout(p=0.1, inplace=False)
)
'''

gru_model = nn.GRU(input_size, hidden_size, num_layers, dropout=dropout)
gru_model
'''
GRU(5, 10, num_layers=3, dropout=0.1)
'''

3.2 参数复制:

python 复制代码
with torch.no_grad():
    for i in range(num_layers):
        # 对于每一层,复制权重和偏置
        getattr(gru_model, 'weight_ih_l' + str(i)).copy_(gru_cell_model.grus[i].weight_ih)
        getattr(gru_model, 'weight_hh_l' + str(i)).copy_(gru_cell_model.grus[i].weight_hh)
        getattr(gru_model, 'bias_ih_l' + str(i)).copy_(gru_cell_model.grus[i].bias_ih)
        getattr(gru_model, 'bias_hh_l' + str(i)).copy_(gru_cell_model.grus[i].bias_hh)

3.3 设置输入和相同的初始hidden state

python 复制代码
input_data = torch.randn(batch_size, input_size)
h0_cell = torch.randn(num_layers, batch_size, hidden_size)
h0_gru = h0_cell.clone()  # 确保从相同的初始状态开始

3.4 分别生成输出结果

由于有dropping的存在,所以每次前向传播之前,都需要设置相同的随机种子

python 复制代码
torch.manual_seed(1215)
output_cell, hn_cell = gru_cell_model(input_data, h0_cell)
torch.manual_seed(1215)
output_gru, hn_gru = gru_model(input_data.unsqueeze(0), h0_gru)

4 比较结果

python 复制代码
torch.allclose(output_cell, output_gru.squeeze(0)),torch.allclose(hn_cell, hn_gru)

#(True, True)

结果是一样的的,所以似乎论文代码里的stackingGRUCell可以被GRU平替?

相关推荐
幽兰的天空1 分钟前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
网易独家音乐人Mike Zhou3 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
安静读书3 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
----云烟----5 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024065 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
小二·5 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic5 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it5 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康6 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud