【Pytorch】模型中buffer的使用

感觉就是将一个常量赋值给了一个张量。

总说

我们知道,pytorch一般情况下,是将网络中的参数保存成OrderedDict形式的。这里额参数其实包括2种:一种是模型中各种 module含的参数,即nn.Parameter,我们当然可以在网络中定义其他的nn.Parameter参数。另外一种是buffer。前者每次optim.step会得到更新,而不会更新后者。

例子

第一个例子

class myModel(nn.Module):
    def __init__(self, kernel_size=3):
        super(Depth_guided1, self).__init__()
        self.kernel_size = kernel_size
        self.back_end = torch.nn.Sequential(
            torch.nn.Conv2d(3, 32, 3, padding=1),
            torch.nn.ReLU(True),
            torch.nn.Conv2d(3, 64, 3, padding=1),
            torch.nn.ReLU(True),
            torch.nn.Conv2d(64, 3, 3, padding=1),
            torch.nn.ReLU(True),
        )

        mybuffer = np.arange(1,10,1)
        self.mybuffer_tmp = np.randn((len(mybuffer), 1, 1, 10), dtype='float32')
        self.mybuffer_tmp = torch.from_numpy(self.mybuffer_tmp)
        # register preset variables as buffer
        # So that, in testing , we can use buffer variables.
        self.register_buffer('mybuffer', self.mybuffer_tmp)

        # Learnable weights
        self.conv_weights = nn.Parameter(torch.FloatTensor(64, 10).normal_(mean=0, std=0.01))
        # Other code
        def forward(self):
            ...
            # 这里使用 self.mybuffer!

知识点

I. 定义Parameter和buffer都只需要传入 Tensor即可。也不需要将其转成gpu。这是因为,当网络进行 .cuda()时候,会自动将里面的层的参数,buffer等转换成相应的GPU上。

II. self.register_buffer可以将tensor注册成buffer,在forward中使用self.mybuffer, 而不是self.mybuffer_tmp.

III. 网络存储时也会将buffer存下,当网络load模型时,会将存储的模型的buffer也进行赋值。

IV. buffer的更新在forward中,optim.step只能更新nn.Parameter类型的参数。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用PyTorch实现Transformer模型的完整代码示例: ```python import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F class PositionalEncoding(nn.Module): def __init__(self, d_model, max_len=5000): super(PositionalEncoding, self).__init__() self.dropout = nn.Dropout(p=0.1) pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model)) pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) pe = pe.unsqueeze(0).transpose(0, 1) self.register_buffer('pe', pe) def forward(self, x): x = x + self.pe[:x.size(0), :] return self.dropout(x) class TransformerModel(nn.Module): def __init__(self, ntoken, d_model, nhead, dim_feedforward, num_layers, dropout=0.5): super(TransformerModel, self).__init__() self.model_type = 'Transformer' self.embedding = nn.Embedding(ntoken, d_model) self.pos_encoder = PositionalEncoding(d_model) encoder_layer = nn.TransformerEncoderLayer(d_model, nhead, dim_feedforward, dropout) self.transformer_encoder = nn.TransformerEncoder(encoder_layer, num_layers) self.fc = nn.Linear(d_model, ntoken) self.init_weights() def _generate_square_subsequent_mask(self, sz): mask = torch.triu(torch.ones(sz, sz)) == 1 mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0)) return mask def init_weights(self): initrange = 0.1 self.embedding.weight.data.uniform_(-initrange, initrange) self.fc.bias.data.zero_() self.fc.weight.data.uniform_(-initrange, initrange) def forward(self, src): src = self.embedding(src) src = self.pos_encoder(src) mask = self._generate_square_subsequent_mask(src.size(0)).to(src.device) output = self.transformer_encoder(src, mask) output = self.fc(output) return F.log_softmax(output, dim=-1) # 使用示例: ntoken = 1000 # 词汇表大小 d_model = 512 # 模型维度 nhead = 8 # 多头注意力头数 dim_feedforward = 2048 # 前馈神经网络隐藏层维度 num_layers = 6 # Transformer编码器层数 dropout = 0.5 model = TransformerModel(ntoken, d_model, nhead, dim_feedforward, num_layers, dropout) criterion = nn.NLLLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # 训练过程 def train(): model.train() total_loss = 0. for batch in training_data: optimizer.zero_grad() src, tgt = batch output = model(src) loss = criterion(output.view(-1, ntoken), tgt.view(-1)) loss.backward() optimizer.step() total_loss += loss.item() return total_loss / len(training_data) # 测试过程 def evaluate(): model.eval() total_loss = 0. with torch.no_grad(): for batch in test_data: src, tgt = batch output = model(src) total_loss += criterion(output.view(-1, ntoken), tgt.view(-1)).item() return total_loss / len(test_data) ``` 请注意,上述代码的`training_data`和`test_data`是训练和测试数据的例子,需要根据实际情况进行替换。此外,还需要根据任务的具体要求调整模型的超参数和其他设置。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值