You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

tutorial_8_modules_models.rst 9.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. ======================================
  2. 使用Modules和Models快速搭建自定义模型
  3. ======================================
  4. :mod:`~fastNLP.modules` 和 :mod:`~fastNLP.models` 用于构建 fastNLP 所需的神经网络模型,它可以和 torch.nn 中的模型一起使用。
  5. 下面我们会分三节介绍编写构建模型的具体方法。
  6. 使用 models 中的模型
  7. ----------------------
  8. fastNLP 在 :mod:`~fastNLP.models` 模块中内置了如 :class:`~fastNLP.models.CNNText` 、
  9. :class:`~fastNLP.models.SeqLabeling` 等完整的模型,以供用户直接使用。
  10. 以 :class:`~fastNLP.models.CNNText` 为例,我们看一个简单的文本分类的任务的实现过程。
  11. 首先是数据读入和处理部分,这里的代码和 :doc:`快速入门 </user/quickstart>` 中一致。
  12. .. code-block:: python
  13. from fastNLP.io import CSVLoader
  14. from fastNLP import Vocabulary, CrossEntropyLoss, AccuracyMetric
  15. loader = CSVLoader(headers=('raw_sentence', 'label'), sep='\t')
  16. dataset = loader.load("./sample_data/tutorial_sample_dataset.csv")
  17. dataset.apply(lambda x: x['raw_sentence'].lower(), new_field_name='sentence')
  18. dataset.apply_field(lambda x: x.split(), field_name='sentence', new_field_name='words', is_input=True)
  19. dataset.apply(lambda x: int(x['label']), new_field_name='target', is_target=True)
  20. train_dev_data, test_data = dataset.split(0.1)
  21. train_data, dev_data = train_dev_data.split(0.1)
  22. vocab = Vocabulary(min_freq=2).from_dataset(train_data, field_name='words')
  23. vocab.index_dataset(train_data, dev_data, test_data, field_name='words', new_field_name='words')
  24. 然后我们从 :mod:`~fastNLP.models` 中导入 ``CNNText`` 模型,用它进行训练
  25. .. code-block:: python
  26. from fastNLP.models import CNNText
  27. from fastNLP import Trainer
  28. model_cnn = CNNText((len(vocab),50), num_classes=5, padding=2, dropout=0.1)
  29. trainer = Trainer(model=model_cnn, train_data=train_data, dev_data=dev_data,
  30. loss=CrossEntropyLoss(), metrics=AccuracyMetric())
  31. trainer.train()
  32. 在 iPython 环境输入 `model_cnn` ,我们可以看到 ``model_cnn`` 的网络结构
  33. .. parsed-literal::
  34. CNNText(
  35. (embed): Embedding(
  36. 169, 50
  37. (dropout): Dropout(p=0.0)
  38. )
  39. (conv_pool): ConvMaxpool(
  40. (convs): ModuleList(
  41. (0): Conv1d(50, 3, kernel_size=(3,), stride=(1,), padding=(2,))
  42. (1): Conv1d(50, 4, kernel_size=(4,), stride=(1,), padding=(2,))
  43. (2): Conv1d(50, 5, kernel_size=(5,), stride=(1,), padding=(2,))
  44. )
  45. )
  46. (dropout): Dropout(p=0.1)
  47. (fc): Linear(in_features=12, out_features=5, bias=True)
  48. )
  49. FastNLP 中内置的 models 如下表所示,您可以点击具体的名称查看详细的 API:
  50. .. csv-table::
  51. :header: 名称, 介绍
  52. :class:`~fastNLP.models.CNNText` , 使用 CNN 进行文本分类的模型
  53. :class:`~fastNLP.models.SeqLabeling` , 简单的序列标注模型
  54. :class:`~fastNLP.models.AdvSeqLabel` , 更大网络结构的序列标注模型
  55. :class:`~fastNLP.models.ESIM` , ESIM 模型的实现
  56. :class:`~fastNLP.models.StarTransEnc` , 带 word-embedding的Star-Transformer模 型
  57. :class:`~fastNLP.models.STSeqLabel` , 用于序列标注的 Star-Transformer 模型
  58. :class:`~fastNLP.models.STNLICls` ,用于自然语言推断 (NLI) 的 Star-Transformer 模型
  59. :class:`~fastNLP.models.STSeqCls` , 用于分类任务的 Star-Transformer 模型
  60. :class:`~fastNLP.models.BiaffineParser` , Biaffine 依存句法分析网络的实现
  61. :class:`~fastNLP.models.BiLSTMCRF`, 使用BiLSTM与CRF进行序列标注
  62. 使用 nn.torch 编写模型
  63. ----------------------------
  64. FastNLP 完全支持使用 pyTorch 编写的模型,但与 pyTorch 中编写模型的常见方法不同,
  65. 用于 fastNLP 的模型中 forward 函数需要返回一个字典,字典中至少需要包含 ``pred`` 这个字段。
  66. 下面是使用 pyTorch 中的 torch.nn 模块编写的文本分类,注意观察代码中标注的向量维度。
  67. 由于 pyTorch 使用了约定俗成的维度设置,使得 forward 中需要多次处理维度顺序
  68. .. code-block:: python
  69. import torch
  70. import torch.nn as nn
  71. class LSTMText(nn.Module):
  72. def __init__(self, vocab_size, embedding_dim, output_dim, hidden_dim=64, num_layers=2, dropout=0.5):
  73. super().__init__()
  74. self.embedding = nn.Embedding(vocab_size, embedding_dim)
  75. self.lstm = nn.LSTM(embedding_dim, hidden_dim, num_layers=num_layers, bidirectional=True, dropout=dropout)
  76. self.fc = nn.Linear(hidden_dim * 2, output_dim)
  77. self.dropout = nn.Dropout(dropout)
  78. def forward(self, words):
  79. # (input) words : (batch_size, seq_len)
  80. words = words.permute(1,0)
  81. # words : (seq_len, batch_size)
  82. embedded = self.dropout(self.embedding(words))
  83. # embedded : (seq_len, batch_size, embedding_dim)
  84. output, (hidden, cell) = self.lstm(embedded)
  85. # output: (seq_len, batch_size, hidden_dim * 2)
  86. # hidden: (num_layers * 2, batch_size, hidden_dim)
  87. # cell: (num_layers * 2, batch_size, hidden_dim)
  88. hidden = torch.cat((hidden[-2, :, :], hidden[-1, :, :]), dim=1)
  89. hidden = self.dropout(hidden)
  90. # hidden: (batch_size, hidden_dim * 2)
  91. pred = self.fc(hidden.squeeze(0))
  92. # result: (batch_size, output_dim)
  93. return {"pred":pred}
  94. 我们同样可以在 iPython 环境中查看这个模型的网络结构
  95. .. parsed-literal::
  96. LSTMText(
  97. (embedding): Embedding(169, 50)
  98. (lstm): LSTM(50, 64, num_layers=2, dropout=0.5, bidirectional=True)
  99. (fc): Linear(in_features=128, out_features=5, bias=True)
  100. (dropout): Dropout(p=0.5)
  101. )
  102. 使用 modules 编写模型
  103. ----------------------------
  104. 下面我们使用 :mod:`fastNLP.modules` 中的组件来构建同样的网络。由于 fastNLP 统一把 ``batch_size`` 放在第一维,
  105. 在编写代码的过程中会有一定的便利。
  106. .. code-block:: python
  107. from fastNLP.modules import Embedding, LSTM, MLP
  108. class Model(nn.Module):
  109. def __init__(self, vocab_size, embedding_dim, output_dim, hidden_dim=64, num_layers=2, dropout=0.5):
  110. super().__init__()
  111. self.embedding = Embedding((vocab_size, embedding_dim))
  112. self.lstm = LSTM(embedding_dim, hidden_dim, num_layers=num_layers, bidirectional=True)
  113. self.mlp = MLP([hidden_dim*2,output_dim], dropout=dropout)
  114. def forward(self, words):
  115. embedded = self.embedding(words)
  116. _,(hidden,_) = self.lstm(embedded)
  117. pred = self.mlp(torch.cat((hidden[-1],hidden[-2]),dim=1))
  118. return {"pred":pred}
  119. 我们自己编写模型的网络结构如下
  120. .. parsed-literal::
  121. Model(
  122. (embedding): Embedding(
  123. 169, 50
  124. (dropout): Dropout(p=0.0)
  125. )
  126. (lstm): LSTM(
  127. (lstm): LSTM(50, 64, num_layers=2, batch_first=True, bidirectional=True)
  128. )
  129. (mlp): MLP(
  130. (hiddens): ModuleList()
  131. (output): Linear(in_features=128, out_features=5, bias=True)
  132. (dropout): Dropout(p=0.5)
  133. )
  134. )
  135. FastNLP 中包含的各种模块如下表,您可以点击具体的名称查看详细的 API,也可以通过 :doc:`/fastNLP.modules` 进行了解。
  136. .. csv-table::
  137. :header: 名称, 介绍
  138. :class:`~fastNLP.modules.ConvolutionCharEncoder` , char级别的卷积 encoder
  139. :class:`~fastNLP.modules.LSTMCharEncoder` , char级别基于LSTM的 encoder
  140. :class:`~fastNLP.modules.ConvMaxpool` , 结合了Convolution和Max-Pooling于一体的模块
  141. :class:`~fastNLP.modules.LSTM` , LSTM模块, 轻量封装了PyTorch的LSTM
  142. :class:`~fastNLP.modules.StarTransformer` , Star-Transformer 的encoder部分
  143. :class:`~fastNLP.modules.TransformerEncoder` , Transformer的encoder模块,不包含embedding层
  144. :class:`~fastNLP.modules.VarRNN` , Variational Dropout RNN 模块
  145. :class:`~fastNLP.modules.VarLSTM` , Variational Dropout LSTM 模块
  146. :class:`~fastNLP.modules.VarGRU` , Variational Dropout GRU 模块
  147. :class:`~fastNLP.modules.MaxPool` , Max-pooling模块
  148. :class:`~fastNLP.modules.MaxPoolWithMask` , 带mask矩阵的max pooling。在做 max-pooling的时候不会考虑mask值为0的位置。
  149. :class:`~fastNLP.modules.AvgPool` , Average-pooling模块
  150. :class:`~fastNLP.modules.AvgPoolWithMask` , 带mask矩阵的average pooling。在做 average-pooling的时候不会考虑mask值为0的位置。
  151. :class:`~fastNLP.modules.MultiHeadAttention` , MultiHead Attention 模块
  152. :class:`~fastNLP.modules.MLP` , 简单的多层感知器模块
  153. :class:`~fastNLP.modules.ConditionalRandomField` , 条件随机场模块
  154. :class:`~fastNLP.modules.viterbi_decode` , 给定一个特征矩阵以及转移分数矩阵,计算出最佳的路径以及对应的分数 (与 :class:`~fastNLP.modules.ConditionalRandomField` 配合使用)
  155. :class:`~fastNLP.modules.allowed_transitions` , 给定一个id到label的映射表,返回所有可以跳转的列表(与 :class:`~fastNLP.modules.ConditionalRandomField` 配合使用)
  156. :class:`~fastNLP.modules.TimestepDropout` , 简单包装过的Dropout 组件