MindSpore【nn.LSTMCell】自定义网络如果设置batch_size,h和c参数如何初始化

基于nn.Cell 自定义了一个LSTM网络,代码如下:

import math
import numpy as orinp
import mindspore.numpy as np
from mindspore import nn,ops
from mindspore import Tensor,Parameter
from models import w2vutils
import common
import mindspore

class ScaleL2Loss(nn.LossBase):
    '''
    自定义loss函数,会放大
    '''
    def __init__(self,max_len=30):
        super(ScaleL2Loss, self).__init__("mean")
        self.abs = ops.Abs()
        self.square = ops.Square()
        self.max_len = max_len

    def construct(self, base, target):
        factor = self.abs(base -1) * (self.max_len - 1) + 1 #放大因子,放大负采样数据
        loss = factor * ( base - target )
        loss = self.square(loss)/self.max_len
        return self.get_loss(loss)

class LSTMScorer(nn.Cell):
    def __init__(self,vocab_size,embedding_dim,embedding_table,lstm_kernel_size=128,seq_len=30,device_type:str=common._device_choices[2]):
        super(LSTMScorer,self).__init__()
        self.embedding = nn.Embedding(vocab_size,embedding_dim,embedding_table=embedding_table,padding_idx=0)
        if device_type == common._device_choices[2]:
            self.lstm = nn.LSTMCell(input_size=embedding_dim,hidden_size=lstm_kernel_size,has_bias=True,batch_first=True,dropout=0.2,bidirectional=True)
        else:
            self.lstm = nn.LSTM(input_size=embedding_dim,hidden_size=lstm_kernel_size,has_bias=True,batch_first=True,dropout=0.2,bidirectional=True)
        self.flatten = nn.Flatten()
        self.dense = nn.Dense(embedding_dim*seq_len,seq_len)
        stdv = 1 / math.sqrt(lstm_kernel_size)
        lstm_weight_size =int((embedding_dim+lstm_kernel_size)*2*lstm_kernel_size*4 + 2*lstm_kernel_size*4)
        self.lstm.weight = Parameter(orinp.random.uniform(-stdv, stdv, (lstm_weight_size, 1, 1)).astype(orinp.float32),name="LSTMPARAMS")

    def construct(self,x):
        batch_size = 1
        if len(x.shape) == 1:
            x = x.reshape((1, x.shape[0]))
        else:
            batch_size = x.shape[0]
        h = Tensor(np.ones([2, batch_size, 128]).astype(np.float32))
        c = Tensor(np.ones([2, batch_size, 128]).astype(np.float32))
        x = self.embedding(x)
        x, h, c, _, _ = self.lstm(x, h, c, self.lstm.weight)
        x = self.flatten(x)
        y = self.dense(x)
        return y

在GRAPH_MODE 下出错,原因是GRAPH_MODE 模式下不能生产Tensor类型数据。

那么,h和c要在哪里创建呢。因为batch_size的问题,一轮迭代最后一批数据很难保证和预设的batchsize一致。所以h,c 动态创建是不可避免的。应该怎么做呢。

解答:

@constexprdef _init_state(shape, dtype, is_lstm):
    hx = Tensor(np.zeros(shape), dtype)
    cx = Tensor(np.zeros(shape), dtype)
    if is_lstm:
        return (hx, cx)
    return hx

参考实现:https://gitee.com/mindspore/mindspore/blob/master/mindspore/nn/layer/rnns.py#L361

所有的h,c初始化都是0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这些代码是一个 PyTorch 模型的实现,该模型是一个基于 LSTM 的序列预测模型。具体解释如下: - `class LSTM(nn.Module):` 定义了一个 LSTM 模型类,继承自 PyTorch 的 nn.Module 类。 - `def __init__(self, input_size, hidden_size, num_layers, output_size, batch_size):` 定义了模型的构造函数,接收五个参数:输入特征维度 `input_size`、隐藏层特征维度 `hidden_size`、LSTM 层数 `num_layers`、输出特征维度 `output_size`、batch 大小 `batch_size`。 - `super().__init__():` 调用父类的构造函数,初始化模型的基本属性。 - `self.input_size = input_size`、`self.hidden_size = hidden_size`、`self.num_layers = num_layers`、`self.output_size = output_size`、`self.batch_size = batch_size` 分别初始化模型的输入特征维度、隐藏层特征维度、LSTM 层数、输出特征维度和 batch 大小等属性。 - `self.lstm = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True)` 定义了一个 LSTM 层,接收四个参数:输入特征维度,隐藏层特征维度,LSTM 层数和 batch_first 的值为 True,表示输入数据的维度顺序为 (batch_size, seq_len, input_size)。 - `self.linear = nn.Linear(self.hidden_size, self.output_size)` 定义了一个全连接层,用于将 LSTM 层的输出特征映射到指定的输出维度。 - `def forward(self, input_seq):` 定义了模型的前向传播函数,接收一个参数 `input_seq`,表示输入的序列数据。 - `batch_size, seq_len = input_seq[0], input_seq[1]` 解析输入数据的 batch 大小和序列长度。 - `h_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(device)` 和 `c_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(device)` 初始化 LSTM 层的初始隐藏状态和细胞状态,使用随机生成的张量,并将它们移动到指定的设备上。 - `output, _ = self.lstm(input_seq, (h_0, c_0))` 将输入序列和初始状态输入到 LSTM 层中,得到 LSTM 层的输出和最后一个时间步的隐藏状态。 - `pred = self.linear(output)` 将 LSTM 层的输出特征映射到指定的输出维度。 - `pred = pred[:, -1, :]` 取最后一个时间步的输出特征作为预测结果。 总的来说,这段代码实现了一个基于 LSTM 的序列预测模型,可以用于对时序数据进行预测。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值