Модель BERT можно использовать для нескольких задач, и это также необходимый метод для текущей модели НЛП. В текстовой классификации мы будем использовать [CLS]
соответствующий вывод для завершения текстовой классификации, конечно, есть и другие методы.
Это позволяет использовать каждый token
соответствующий результат pooling
и затем классифицировать после прохождения. В этой статье будут представлены несколько распространенных методов построения и использования BERT.
Метод 1: средний пул
token
Рассчитайте среднее значение каждого соответствующего выхода, который необходимо учитывать здесь attention_mask
, то есть эффективный ввод необходимо учитывать token
.
class MeanPooling(nn.Module): def __init__(self): super(MeanPooling, self).__init__() def forward(self, last_hidden_state, attention_mask): input_mask_expanded = attention_mask.unsqueeze(-1).expand(last_hidden_state.size()).float() sum_embeddings = torch.sum(last_hidden_state * input_mask_expanded, 1) sum_mask = input_mask_expanded.sum(1) sum_mask = torch.clamp(sum_mask, min = 1e-9) mean_embeddings = sum_embeddings/sum_mask return mean_embeddings
Способ 2: Макспулинг
Вычислите максимальное значение каждого token
соответствующего выхода, который необходимо учитывать здесь attention_mask
, то есть эффективный вход необходимо учитывать token
.
class MaxPooling(nn.Module): def __init__(self): super(MaxPooling, self).__init__() def forward(self, last_hidden_state, attention_mask): input_mask_expanded = attention_mask.unsqueeze(-1).expand(last_hidden_state.size()).float() embeddings = last_hidden_state.clone() embeddings[input_mask_expanded == 0] = -1e4 max_embeddings, _ = torch.max(embeddings, dim = 1) return max_embeddings
Способ 3: MinPooling
Вычислите минимальное значение каждого token
соответствующего выхода, который необходимо учитывать здесь attention_mask
, то есть эффективный вход необходимо учитывать token
.
class MinPooling(nn.Module): def __init__(self): super(MinPooling, self).__init__() def forward(self, last_hidden_state, attention_mask): input_mask_expanded = attention_mask.unsqueeze(-1).expand(last_hidden_state.size()).float() embeddings = last_hidden_state.clone() embeddings[input_mask_expanded == 0] = 1e-4 min_embeddings, _ = torch.min(embeddings, dim = 1) return min_embeddings
Метод 4: взвешенное объединение
Подсчитайте вес каждого token
соответствующего выхода. Вес здесь может быть рассчитан по характеристикам, либо вес может быть рассчитан по IDF.
class WeightedLayerPooling(nn.Module): def __init__(self, num_hidden_layers, layer_start: int = 4, layer_weights = None): super(WeightedLayerPooling, self).__init__() self.layer_start = layer_start self.num_hidden_layers = num_hidden_layers self.layer_weights = layer_weights if layer_weights is not None \ else nn.Parameter( torch.tensor([1] * (num_hidden_layers+1 - layer_start), dtype=torch.float) ) def forward(self, ft_all_layers): all_layer_embedding = torch.stack(ft_all_layers) all_layer_embedding = all_layer_embedding[self.layer_start:, :, :, :] weight_factor = self.layer_weights.unsqueeze(-1).unsqueeze(-1).unsqueeze(-1).expand(all_layer_embedding.size()) weighted_average = (weight_factor*all_layer_embedding).sum(dim=0) / self.layer_weights.sum() return weighted_average
Метод 5: Объединение внимания
Добавьте каждый token
feature в слой отдельно для расчета внимания и увеличения возможностей моделирования модели.
class AttentionPooling(nn.Module): def __init__(self, in_dim): super().__init__() self.attention = nn.Sequential( nn.Linear(in_dim, in_dim), nn.LayerNorm(in_dim), nn.GELU(), nn.Linear(in_dim, 1), ) def forward(self, last_hidden_state, attention_mask): w = self.attention(last_hidden_state).float() w[attention_mask==0]=float('-inf') w = torch.softmax(w,1) attention_embeddings = torch.sum(w * last_hidden_state, dim=1) return attention_embeddings
Подведем итог
От сложности модели: AttentionPooling › WeightedLayerPooling › MeanPooling / MinPooling / MaxPooling
Из точности модели: AttentionPooling › WeightedLayerPooling › MeanPooling › MaxPooling › MinPooling
Целью использования различных пулов является увеличение разнообразия модели BERT и рассмотрение возможности ее использования при интеграции моделей.
Нравится статья? Станьте участником Medium, чтобы продолжить обучение, читая без ограничений. Если вы воспользуетесь этой ссылкой, чтобы стать участником, вы поддержите меня без каких-либо дополнительных затрат с вашей стороны. Заранее спасибо и до встречи!
Повышение уровня кодирования
Спасибо, что являетесь частью нашего сообщества! Перед тем, как ты уйдешь:
- 👏 Хлопайте за историю и подписывайтесь на автора 👉
- 📰 Смотрите больше контента в публикации Level Up Coding
- 🔔 Подписывайтесь на нас: Twitter | ЛинкедИн | "Новостная рассылка"
🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите прекрасную работу