Project: s41467-024-55594-z | Function: forward (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Forward pass of ResFPN network that processes 3D CT images through residual blocks and FPN layers, extracting multi-scale features for lung cancer diagnosis

**KEY TERMS:** {
  "c1-c5": "feature maps at different scales",
  "p2-p5": "pyramid feature maps",
  "toplayer": "top-down pathway start",
  "latlayer": "lateral connections",
  "smooth": "feature smoothing convolutions"
}

**CONTEXT CODE:** import torch
import torch.nn as nn
import torch.nn.functional as F
import math
from functools import partial

def conv3x3x3(in_planes, out_planes, stride=1):
    # 3x3x3 convolution with padding
    return nn.Conv3d(
        in_planes,
        out_planes,
        kernel_size=3,
        stride=stride,
        padding=1,
        bias=False)

def downsample_basic_block(x, planes, stride):
    out = F.avg_pool3d(x, kernel_size=1, stride=stride)
    zero_pads = torch.Tensor(
        out.size(0), planes - out.size(1), out.size(2), out.size(3),
        out.size(4)).zero_()
    if isinstance(out.data, torch.cuda.FloatTensor):
        zero_pads = zero_pads.cuda()

    out = torch.cat([out.data, zero_pads], dim=1)
    return out

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3x3(inplanes, planes, stride)
        self.bn1 = nn.BatchNorm3d(planes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3x3(planes, planes)
        self.bn2 = nn.BatchNorm3d(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

class ResFPN(nn.Module):

    def __init__(self,
                 block,
                 layers,
                 shortcut_type='B',
                 n_classes=2,
                 in_channels=1,
                 fc_num = 128):

        super(ResFPN, self).__init__()
        self.fc_num = fc_num
        self.num_classes = n_classes
        #first_features = 64 if in_channels == 3 else 32
        first_features = 64
        self.inplanes = first_features
        self.conv1 = nn.Conv3d(
            in_channels,
            first_features,
            kernel_size=7,
            stride=(1, 2, 2),
            padding=(3, 3, 3),
            bias=False)
        self.bn1 = nn.BatchNorm3d(first_features)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool3d(kernel_size=(3, 3, 3), stride=2, padding=1)
        self.layer1 = self._make_layer(block, first_features, layers[0], shortcut_type)
        self.layer2 = self._make_layer(block, 128, layers[1], shortcut_type, stride=2)
        self.layer3 = self._make_layer(block, 256, layers[2], shortcut_type, stride=2)
        self.layer4 = self._make_layer(block, 512, layers[3], shortcut_type, stride=2)
        
        self.toplayer=nn.Conv3d(512,first_features,1,stride=(1, 1, 1),bias=False)
        
        #横向连接，保证通道数相同
        self.latlayer1=nn.Conv3d(256,first_features,1,stride=(1, 1, 1),bias=False)
        self.latlayer2=nn.Conv3d(128,first_features,1,stride=(1, 1, 1),bias=False)
        self.latlayer3=nn.Conv3d(first_features,first_features,1,stride=(1, 1, 1),bias=False)
        #3x3卷积融合特征
        self.smooth1=nn.Conv3d(first_features,first_features,3,1,1)
        self.smooth2=nn.Conv3d(first_features,first_features,3,1,1)
        self.smooth3=nn.Conv3d(first_features,first_features,3,1,1)
        
        #for p in self.parameters():
        #    p.requires_grad = False

        self.fc1 = nn.Sequential(nn.Linear(first_features, first_features),
                                 nn.BatchNorm1d(first_features),
                                 nn.ReLU())
        self.fc2 = nn.Sequential(nn.Linear(first_features, first_features),
                                 nn.BatchNorm1d(first_features),
                                 nn.ReLU())
        self.fc3 = nn.Sequential(nn.Linear(first_features, first_features),
                                 nn.BatchNorm1d(first_features),
                                 nn.ReLU())
        self.fc4 = nn.Sequential(nn.Linear(first_features, first_features),
                                 nn.BatchNorm1d(first_features),
                                 nn.ReLU())
        
        self.classify_add = nn.Sequential(nn.Linear(first_features, self.fc_num),
                                 nn.BatchNorm1d(self.fc_num),
                                 nn.ReLU(),
                                 nn.Linear(self.fc_num, 2)) 
        
        self.classify_con = nn.Sequential(nn.Linear(first_features*4, self.fc_num),
                                 nn.BatchNorm1d(self.fc_num),
                                 nn.ReLU(),
                                 nn.Linear(self.fc_num, 2))
        
        for m in self.modules():
            if isinstance(m, nn.Conv3d):
                m.weight = nn.init.kaiming_normal_(m.weight, mode='fan_out')
            elif isinstance(m, nn.BatchNorm3d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
    #自上而下的采样模块
    def _upsample_add(self,x,y):
        raise NotImplementedError("Function implementation has been masked")
    
    def _make_layer(self, block, planes, blocks, shortcut_type, stride=1):
        downsample = None
        if stride != 1 or self.inplanes != planes * block.expansion:
            if shortcut_type == 'A':


Complete the function implementation replacing "raise NotImplementedError".