Project: s41467-025-60898-9 | Function: GCN.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 Graph Convolutional Network (GCN) for node classification in spatial transcriptomics. Processes node features through multiple GCN layers followed by MLP layers to predict cell types.

**KEY TERMS:** {
  "x": "node features",
  "edge_index": "graph adjacency",
  "edge_weight": "edge attributes",
  "GCNConv": "Graph Convolutional layer"
}

**CONTEXT CODE:** 
        self.gcn_layer_dims = [n_features] + list(gcn_hidden_layer_dims)
        self.mlp_layer_dims = list(mlp_hidden_layer_dims) + [n_classes]
        
        self.gcn_n_layers = len(self.gcn_layer_dims)
        self.mlp_n_layers = len(self.mlp_layer_dims)

        self.gcn_layers = nn.Sequential(
            collections.OrderedDict(
                [
                    (
                        f"Layer_GCN {i}",
                        nn.Sequential(
                            GCNConv(n_in, n_out),
                            BatchNorm(n_out),
                            nn.ReLU(),
                            nn.Dropout(p = dropout_rate)
                        ),
                    )
                    for i, (n_in, n_out) in enumerate(
                        zip(self.gcn_layer_dims[:-1], self.gcn_layer_dims[1:])
                    )
                ]   
            )
        )

        self.mlp_layers = nn.Sequential(
            collections.OrderedDict(
                [
                    (
                        f"Layer_FC {i}",
                        nn.Sequential(
                            nn.Linear(n_in, n_out),
                            BatchNorm(n_out),
                            nn.ReLU(),
                        ),
                    )
                    for i, (n_in, n_out) in enumerate(
                        zip(self.mlp_layer_dims[:-1], self.mlp_layer_dims[1:])
                    )
                ]   
            )
        )

        # self.mlp = MLP(
        #     self.mlp_layer_dims, 
        #     act = 'relu',
        #     norm = 'batch_norm'
        # )

    def forward(self, data):
        '''
        Forward pass of Graph Convolutional Network (GCN) for node classification in spatial transcriptomics.
        Processes node features through multiple GCN layers followed by MLP layers to predict cell types.
        '''
        # MASKED: Forward pass of Graph Convolutional Network (GCN) for node classification in spatial transcriptomics by processing node features through multiple GCN layers followed by MLP layers to predict cell types implementation
        raise NotImplementedError("This function is masked for testing purposes.")

    @torch.no_grad()
    def get_latent(self, data, num_mlp_layers = 1):
        '''
        Get the latent representation of the model from the input data

        Parameters
        ----------
        data
            Input data
        num_mlp_layers
            Number of MLP layers to use to get the latent representation
        '''
        x, edge_index, edge_weight = data.x, data.edge_index, data.edge_attr
        for i, layers in enumerate(self.gcn_layers):
            for layer in layers:
                if isinstance(layer, GCNConv):
                    x = layer(x, edge_index, edge_weight)
                else:
                    x = layer(x)
        
        for i, layers in enumerate(self.mlp_layers):
            if i < num_mlp_layers:
                for layer in layers:
                    if isinstance(layer, Linear):
                        x = layer(x)
                    else:
                        x = layer(x)
        return x

Complete the function implementation replacing "raise NotImplementedError".