class_docstr: HAN layer.
  
  Arguments
  ---------
  num_metapath : number of metapath based sub-graph
  in_size : input feature dimension
  out_size : output feature dimension
  layer_num_heads : number of attention heads
  dropout : Dropout probability
  
  Inputs
  ------
  g : DGLGraph
      The heterogeneous graph
  h : tensor
      Input features
  
  Outputs
  -------
  tensor
      The output feature
class_docstr_tok: ["HAN","layer",".","Arguments","--","--","--","--","-","num_metapath",":","number","of","metapath","based","sub-graph","in_size",":","input","feature","dimension","out_size",":","output","feature","dimension","layer_num_heads",":","number","of","attention","heads","dropout",":","Dropout","probability","Inputs","--","--","--","g",":","DGLGraph","The","heterogeneous","graph","h",":","tensor","Input","features","Outputs","--","--","--","-","tensor","The","output","feature"]
code: def forward(self, block_list, h_list):
      semantic_embeddings = []
  
      for i, block in enumerate(block_list):
          semantic_embeddings.append(
              self.gat_layers[i](block, h_list[i]).flatten(1)
          )
      semantic_embeddings = torch.stack(
          semantic_embeddings, dim=1
      )  # (N, M, D * K)
  
      return self.semantic_attention(semantic_embeddings)
  
imports: import argparse
  import dgl
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from dgl.nn.pytorch import GATConv
  from dgl.sampling import RandomWalkNeighborSampler
  from model_hetero import SemanticAttention
  from sklearn.metrics import f1_score
  from torch.utils.data import DataLoader
  from utils import EarlyStopping, set_random_seed
label_desc: Use image node_id 2 for calling the HANLayer obj's underlying member method code with example usage: obj.forward(block_list, h_list) and returns: self