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


    1 stackingGRUCell

    1. class StackingGRUCell(nn.Module):
    2. """
    3. Multi-layer CRU Cell
    4. """
    5. def __init__(self, input_size, hidden_size, num_layers, dropout):
    6. super(StackingGRUCell, self).__init__()
    7. self.num_layers = num_layers
    8. self.grus = nn.ModuleList()
    9. self.dropout = nn.Dropout(dropout)
    10. self.grus.append(nn.GRUCell(input_size, hidden_size))
    11. for i in range(1, num_layers):
    12. self.grus.append(nn.GRUCell(hidden_size, hidden_size))
    1. def forward(self, input, h0):
    2. """
    3. Input:
    4. input (batch, input_size): input tensor
    5. h0 (num_layers, batch, hidden_size): initial hidden state
    6. ---
    7. Output:
    8. output (batch, hidden_size): the final layer output tensor
    9. hn (num_layers, batch, hidden_size): the hidden state of each layer
    10. """
    11. hn = []
    12. output = input
    13. for i, gru in enumerate(self.grus):
    14. hn_i = gru(output, h0[i])
    15. #在每一次循环中,输入output会经过一个GRU单元并更新隐藏状态
    16. hn.append(hn_i)
    17. if i != self.num_layers - 1:
    18. output = self.dropout(hn_i)
    19. else:
    20. output = hn_i
    21. #如果不是最后一层,输出会经过一个dropout层。
    22. hn = torch.stack(hn)
    23. #将hn列表转变为一个张量
    24. return output, hn
    • nn.GRU中,hn表示每层的最后一个时间步的隐藏状态。这意味着,对于一个具有seq_len的输入序列,hn会包含每层的seq_len时间步中的最后一个时间步的隐藏状态。
    • StackingGRUCell中,hn是通过每层的GRUCell为给定的单一时间步计算得到的。
    • 所以,如果seq_len为1,那么nn.GRUhnStackingGRUCellhn应该是相同的?output更应是如此

    2 作为对比的普通GRU

    啥也没有的一个普通GRU:

    1. class StackingGRU_tst(nn.Module):
    2. def __init__(self, input_size, hidden_size, num_layers, dropout):
    3. super(StackingGRU_tst, self).__init__()
    4. self.gru = nn.GRU(input_size, hidden_size, num_layers=num_layers, dropout=dropout, batch_first=True)
    5. def forward(self, input, h0):
    6. output, hn = self.gru(input, h0)
    7. return output, hn
    1. input_size = 5
    2. hidden_size = 10
    3. num_layers = 3
    4. dropout = 0.1
    5. batch_size = 7

    3 二者对比前的一些工作

    3.1 创建模型 

    1. gru_cell_model = StackingGRUCell(input_size, hidden_size, num_layers, dropout)
    2. gru_cell_model
    3. '''
    4. StackingGRUCell(
    5. (grus): ModuleList(
    6. (0): GRUCell(5, 10)
    7. (1): GRUCell(10, 10)
    8. (2): GRUCell(10, 10)
    9. )
    10. (dropout): Dropout(p=0.1, inplace=False)
    11. )
    12. '''
    13. gru_model = nn.GRU(input_size, hidden_size, num_layers, dropout=dropout)
    14. gru_model
    15. '''
    16. GRU(5, 10, num_layers=3, dropout=0.1)
    17. '''

    3.2 参数复制: 

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

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

    1. input_data = torch.randn(batch_size, input_size)
    2. h0_cell = torch.randn(num_layers, batch_size, hidden_size)
    3. h0_gru = h0_cell.clone() # 确保从相同的初始状态开始

    3.4 分别生成输出结果

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

    1. torch.manual_seed(1215)
    2. output_cell, hn_cell = gru_cell_model(input_data, h0_cell)
    3. torch.manual_seed(1215)
    4. output_gru, hn_gru = gru_model(input_data.unsqueeze(0), h0_gru)

    4 比较结果

    1. torch.allclose(output_cell, output_gru.squeeze(0)),torch.allclose(hn_cell, hn_gru)
    2. #(True, True)

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

  • 相关阅读:
    中国石油大学(北京)-《 完井工程》第一阶段在线作业
    PostgreSQL 认证方式
    【Godot】给不规则的 TileMap 划分子区域块部分代码
    南卡和益博思哪个电容笔比较好?国产电容笔全方位对比
    php的错误机制
    推荐几款实用的项目进度管理软件
    【GIT】常用操作总结
    SqlBulkCopy与临时表、普通Sql操作配合使用
    Tomcat漏洞
    OpenSSF发布npm 最佳实践指南,应对开源依赖风险
  • 原文地址:https://blog.csdn.net/qq_40206371/article/details/134171059