Reference: Deep Pyramid Convolutional Neural Networks for Text Categorization
| 20 | |
| 21 | |
| 22 | class DPCNN(Classifier): |
| 23 | """ |
| 24 | Reference: |
| 25 | Deep Pyramid Convolutional Neural Networks for Text Categorization |
| 26 | """ |
| 27 | |
| 28 | def __init__(self, dataset, config): |
| 29 | super(DPCNN, self).__init__(dataset, config) |
| 30 | self.num_kernels = config.DPCNN.num_kernels |
| 31 | self.pooling_stride = config.DPCNN.pooling_stride |
| 32 | self.kernel_size = config.DPCNN.kernel_size |
| 33 | self.radius = int(self.kernel_size / 2) |
| 34 | assert self.kernel_size % 2 == 1, "DPCNN kernel should be odd!" |
| 35 | self.convert_conv = torch.nn.Sequential( |
| 36 | torch.nn.Conv1d( |
| 37 | config.embedding.dimension, self.num_kernels, |
| 38 | self.kernel_size, padding=self.radius) |
| 39 | ) |
| 40 | |
| 41 | self.convs = torch.nn.ModuleList([torch.nn.Sequential( |
| 42 | torch.nn.ReLU(), |
| 43 | torch.nn.Conv1d( |
| 44 | self.num_kernels, self.num_kernels, |
| 45 | self.kernel_size, padding=self.radius), |
| 46 | torch.nn.ReLU(), |
| 47 | torch.nn.Conv1d( |
| 48 | self.num_kernels, self.num_kernels, |
| 49 | self.kernel_size, padding=self.radius) |
| 50 | ) for _ in range(config.DPCNN.blocks + 1)]) |
| 51 | |
| 52 | self.linear = torch.nn.Linear(self.num_kernels, len(dataset.label_map)) |
| 53 | |
| 54 | def get_parameter_optimizer_dict(self): |
| 55 | params = super(DPCNN, self).get_parameter_optimizer_dict() |
| 56 | params.append({'params': self.convert_conv.parameters()}) |
| 57 | params.append({'params': self.convs.parameters()}) |
| 58 | params.append({'params': self.linear.parameters()}) |
| 59 | return params |
| 60 | |
| 61 | def forward(self, batch): |
| 62 | if self.config.feature.feature_names[0] == "token": |
| 63 | embedding = self.token_embedding( |
| 64 | batch[cDataset.DOC_TOKEN].to(self.config.device)) |
| 65 | else: |
| 66 | embedding = self.char_embedding( |
| 67 | batch[cDataset.DOC_CHAR]).to(self.config.device) |
| 68 | embedding = embedding.permute(0, 2, 1) |
| 69 | conv_embedding = self.convert_conv(embedding) |
| 70 | conv_features = self.convs[0](conv_embedding) |
| 71 | conv_features = conv_embedding + conv_features |
| 72 | for i in range(1, len(self.convs)): |
| 73 | block_features = F.max_pool1d( |
| 74 | conv_features, self.kernel_size, self.pooling_stride) |
| 75 | conv_features = self.convs[i](block_features) |
| 76 | conv_features = conv_features + block_features |
| 77 | doc_embedding = F.max_pool1d( |
| 78 | conv_features, conv_features.size(2)).squeeze() |
| 79 | return self.dropout(self.linear(doc_embedding)) |
nothing calls this directly
no outgoing calls
no test coverage detected