docstr: 原有的两次BN层需要消耗的两块显存空间，
  通过使用checkpoint，实现了只开辟一块空间用来存储中间特征
docstr_tok: ["\u539f\u6709\u7684\u4e24\u6b21BN\u5c42\u9700\u8981\u6d88\u8017\u7684\u4e24\u5757\u663e\u5b58\u7a7a\u95f4\uff0c","\u901a\u8fc7\u4f7f\u7528checkpoint\uff0c\u5b9e\u73b0\u4e86\u53ea\u5f00\u8f9f\u4e00\u5757\u7a7a\u95f4\u7528\u6765\u5b58\u50a8\u4e2d\u95f4\u7279\u5f81"]
code: def forward(self, *prev_features):
      """原有的两次BN层需要消耗的两块显存空间，
      通过使用checkpoint，实现了只开辟一块空间用来存储中间特征
      """
      bn_function = _bn_function_factory(
          self.norm1, self.relu1, self.conv1
      )
      # requires_grad is True means that model is in train status
      # checkpoint implement shared memory storage function
  
      if self.efficient and any(
          prev_feature.requires_grad for prev_feature in prev_features
      ):
          bottleneck_output = cp.checkpoint(bn_function, *prev_features)
      else:
          bottleneck_output = bn_function(*prev_features)
  
      new_features = self.conv2(
          self.relu2(self.norm2(bottleneck_output))
      )
  
      if self.drop_rate > 0:
          new_features = F.dropout(
              new_features, p=self.drop_rate, training=self.training
          )
      return new_features
  
imports: import re
  from collections import OrderedDict
  import torch
  import torch.nn
  import torch.nn.functional
  import torch.utils.checkpoint
  import torch.utils.model_zoo
  from .se_module import SELayer
label_desc: Use image node_id 2 for calling the _DenseLayer obj's underlying member method code with example usage: obj.forward() and returns: new_features