class_docstr: 使用 ``CNN`` 生成 ``character embedding``。``CNN`` 的结构为：char_embed(x) -> Dropout(x) -> CNN(x) -> activation(x) -> pool -> fc -> Dropout.
  不同的 ``kernel`` 大小的 ``fitler`` 结果是拼起来然后通过一层 **全连接层** 然后输出 ``word`` 的表示。
  
  Example::
  
      >>> import torch
      >>> from fastNLP import Vocabulary
      >>> from fastNLP.embeddings.torch import CNNCharEmbedding
      >>> vocab = Vocabulary().add_word_lst("The whether is good .".split())
      >>> embed = CNNCharEmbedding(vocab, embed_size=50)
      >>> words = torch.LongTensor([[vocab.to_index(word) for word in "The whether is good .".split()]])
      >>> outputs = embed(words)
      >>> outputs.size()
      torch.Size([1, 5，50])
  
  :param vocab: 词表
  :param embed_size: 该 :class:`CNNCharEmbedding` 的输出维度大小。
  :param char_emb_size: character 的 embed 的维度。character 是从 ``vocab`` 中生成的。
  :param word_dropout: 按照一定概率随机将 word 设置为 ``unk_index`` ，这样可以使得 ``<UNK>`` 这个 token 得到足够的训练，
      且会对网络有一定的 regularize 作用。
  :param dropout: 以多大的概率 drop 分布式表示与 char embedding 的输出。
  :param filter_nums: filter 的数量。长度需要和 ``kernel_sizes`` 一致。
  :param kernel_sizes: kernel 的大小。
  :param pool_method: character 的表示在合成一个表示时所使用的 pool 池化方法，支持 ``['avg', 'max']`` 。
  :param activation: CNN 之后使用的激活方法，支持 ``['relu', 'sigmoid', 'tanh']`` 或者自定义函数。
  :param min_char_freq: character 的最少出现次数。
  :param pre_train_char_embed: 可以有两种方式调用预训练好的 :class:`CNNCharEmbedding` ：
  
          1. 传入 embedding 文件夹（文件夹下应该只有一个以 **.txt** 作为后缀的文件）或文件路径；
          2. 传入 embedding 的名称，第二种情况将自动查看缓存中是否存在该模型，没有的话将自动下载；
          3. 如果输入为 ``None`` 则使用 ``embedding_dim`` 的维度随机初始化一个 embedding；
  :param requires_grad: 是否更新权重
  :param include_word_start_end: 是否在每个 word 开始的 character 前和结束的 character 增加特殊标示符号
docstr: 输入 ``words`` 的 index 后，生成对应的 ``words`` 的表示。
  
  :param words: 形状为 ``[batch_size, max_len]``
  :return: 形状为 ``[batch_size, max_len, embed_size]`` 的结果
docstr_tok: ["\u8f93\u5165","``","words","``","\u7684","index","\u540e\uff0c\u751f\u6210\u5bf9\u5e94\u7684","``","words","``","\u7684\u8868\u793a\u3002",":","param","words",":","\u5f62\u72b6\u4e3a","``","[","batch_size",",","max_len","]","``",":","return",":","\u5f62\u72b6\u4e3a","``","[","batch_size",",","max_len",",","embed_size","]","``","\u7684\u7ed3\u679c"]
code: def forward(self, words):
      r"""
      输入 ``words`` 的 index 后，生成对应的 ``words`` 的表示。
  
      :param words: 形状为 ``[batch_size, max_len]``
      :return: 形状为 ``[batch_size, max_len, embed_size]`` 的结果
      """
      words = self.drop_word(words)
      batch_size, max_len = words.size()
      chars = self.words_to_chars_embedding[
          words
      ]  # batch_size x max_len x max_word_len
      word_lengths = self.word_lengths[words]  # batch_size x max_len
      max_word_len = word_lengths.max()
      chars = chars[:, :, :max_word_len]
      # 为1的地方为mask
      chars_masks = chars.eq(
          self.char_pad_index
      )  # batch_size x max_len x max_word_len 如果为0, 说明是padding的位置了
      chars = self.char_embedding(
          chars
      )  # batch_size x max_len x max_word_len x embed_size
      chars = self.dropout(chars)
      reshaped_chars = chars.reshape(
          batch_size * max_len, max_word_len, -1
      )
      reshaped_chars = reshaped_chars.transpose(1, 2)  # B' x E x M
      conv_chars = [
          conv(reshaped_chars)
          .transpose(1, 2)
          .reshape(batch_size, max_len, max_word_len, -1)
          for conv in self.convs
      ]
      conv_chars = torch.cat(
          conv_chars, dim=-1
      ).contiguous()  # B x max_len x max_word_len x sum(filters)
      conv_chars = self.activation(conv_chars)
      if self.pool_method == "max":
          conv_chars = conv_chars.masked_fill(
              chars_masks.unsqueeze(-1), float("-inf")
          )
          chars, _ = torch.max(
              conv_chars, dim=-2
          )  # batch_size x max_len x sum(filters)
      else:
          conv_chars = conv_chars.masked_fill(
              chars_masks.unsqueeze(-1), 0
          )
          chars = (
              torch.sum(conv_chars, dim=-2)
              / chars_masks.eq(False).sum(dim=-1, keepdim=True).float()
          )
      chars = self.fc(chars)
      return self.dropout(chars)
  
file_path: fastNLP/fastNLP/embeddings/torch/char_embedding.py
imports: from typing import List
  from ...envs.imports import _NEED_IMPORT_TORCH
  from .embedding import TokenEmbedding
  from .static_embedding import StaticEmbedding
  from .utils import _construct_char_vocab_from_vocab
  from .utils import get_embeddings
  from ...core import logger
  from ...core.vocabulary import Vocabulary
label_desc: Use image node_id 2 for calling the CNNCharEmbedding obj's underlying member method code with example usage: obj.forward(words) and returns: self