class_docstr: Motion compensation model.
  
  After applying optical flow, there remain residual errors. This model
  corrects for the errors based on the input image, the transformed image,
  and the optical flow field.
  
  Args:
      in_channels: Number of input channels. The ``forward`` function takes
          as input two 3-channel images, plus an optical flow field, so by
          default this is 8 channels.
      model_channels: Number of channels for convolution kernels.
      out_channels: Number of channels for output motion-compensated image.
      kernel_size: Size of convolution kernels.
      num_levels: Number of convolution levels.
class_docstr_tok: ["Motion","compensation","model",".","After","applying","optical","flow",",","there","remain","residual","errors",".","This","model","corrects","for","the","errors","based","on","the","input","image",",","the","transformed","image",",","and","the","optical","flow","field",".","Args",":","in_channels",":","Number","of","input","channels",".","The","``","forward","``","function","takes","as","input","two","3-channel","images",",","plus","an","optical","flow","field",",","so","by","default","this","is","8","channels",".","model_channels",":","Number","of","channels","for","convolution","kernels",".","out_channels",":","Number","of","channels","for","output","motion-compensated","image",".","kernel_size",":","Size","of","convolution","kernels",".","num_levels",":","Number","of","convolution","levels","."]
code: def __init__(
      self,
      in_channels: int = 8,
      model_channels: int = 64,
      out_channels: int = 3,
      kernel_size: int = 3,
      num_levels: int = 3,
  ):
      super().__init__()
      padding = kernel_size // 2
  
      # simple input layer
      input_layer = nn.Conv2d(
          in_channels=in_channels,
          out_channels=model_channels,
          kernel_size=kernel_size,
          padding=padding,
          bias=True,
      )
  
      # build the autoencoder portion from the ground up
      child = None
      for _ in range(num_levels):
          child = _MotionCompensationLayer(
              child,
              in_channels=model_channels,
              out_channels=model_channels,
          )
      unet = child
  
      # make sure we turn on bias for the output
      output_layer = nn.Sequential(
          nn.Conv2d(
              in_channels=model_channels,
              out_channels=model_channels,
              kernel_size=kernel_size,
              padding=padding,
              bias=True,
          ),
          nn.ReLU(),
          nn.Conv2d(
              in_channels=model_channels,
              out_channels=out_channels,
              kernel_size=kernel_size,
              padding=padding,
              bias=True,
          ),
      )
  
      assert unet is not None
      self.model = nn.Sequential(input_layer, unet, output_layer)
  
imports: from typing import Any, List, NamedTuple, Optional, Sequence, Tuple
  import torch
  import torch.nn.functional
  from compressai.entropy_models import EntropyBottleneck
  from torch import Tensor, nn
  import neuralcompression.functional
  from neuralcompression.layers import SimplifiedGDN, SimplifiedInverseGDN
label_desc: Use image node_id 1 to create a new DVCMotionCompensationModel object from inherited base classes: nn with example: obj = DVCMotionCompensationModel(in_channels, model_channels, out_channels, kernel_size, num_levels)