class_docstr: 集合了 **Convolution** 和 **Max-Pooling** 于一体的层。给定一个 ``[batch_size, max_len, input_size]`` 的输入，返回
  ``[batch_size, sum(output_channels)]`` 大小的 matrix。在内部，是先使用 ``CNN`` 给输入做卷积，然后经过 activation 
  激活层，在通过在长度(max_len)这一维进行 ``max_pooling`` 。最后得到每个 sample 的一个向量表示。
  
  :param in_channels: 输入 channel 的大小，一般是 embedding 的维度，或 ``encoder``的 output 维度
  :param out_channels: 输出 channel 的数量。如果为 :class:`list`，则需要与 ``kernel_sizes`` 的数量保持一致
  :param kernel_sizes: 输出 channel 的 kernel 大小。
  :param activation: **卷积** 后的结果将通过该 ``activation`` 后再经过 ``max-pooling``。支持 ``['relu', 'sigmoid', 'tanh']``。
code: def __init__(
      self,
      in_channels: int,
      out_channels: Union[int, List[int]],
      kernel_sizes: Union[int, List[int]],
      activation: str = "relu",
  ):
      super(ConvMaxpool, self).__init__()
  
      for kernel_size in kernel_sizes:
          assert (
              kernel_size % 2 == 1
          ), "kernel size has to be odd numbers."
  
      # convolution
      if isinstance(kernel_sizes, (list, tuple, int)):
          if isinstance(kernel_sizes, int) and isinstance(
              out_channels, int
          ):
              out_channels = [out_channels]
              kernel_sizes = [kernel_sizes]
          elif isinstance(kernel_sizes, (tuple, list)) and isinstance(
              out_channels, (tuple, list)
          ):
              assert len(out_channels) == len(kernel_sizes), (
                  "The number of out_channels should be equal to the number"
                  " of kernel_sizes."
              )
          else:
              raise ValueError(
                  "The type of out_channels and kernel_sizes should be the same."
              )
  
          self.convs = nn.ModuleList(
              [
                  nn.Conv1d(
                      in_channels=in_channels,
                      out_channels=oc,
                      kernel_size=ks,
                      stride=1,
                      padding=ks // 2,
                      dilation=1,
                      groups=1,
                      bias=False,
                  )
                  for oc, ks in zip(out_channels, kernel_sizes)
              ]
          )
  
      else:
          raise Exception(
              "Incorrect kernel sizes: should be list, tuple or int"
          )
  
      # activation function
      if activation == "relu":
          self.activation = F.relu
      elif activation == "sigmoid":
          self.activation = F.sigmoid
      elif activation == "tanh":
          self.activation = F.tanh
      else:
          raise Exception(
              "Undefined activation function: choose from: relu, tanh, sigmoid"
          )
  
imports: from typing import Union, List
  import torch
  import torch.nn
  import torch.nn.functional
label_desc: Use image node_id 1 to create a new ConvMaxpool object from inherited base classes: nn with example: obj = ConvMaxpool(in_channels, out_channels, kernel_sizes, activation)