У меня есть тестовый скрипт для SBERT:
import torch
from transformers import BertTokenizer, BertModel
from sklearn.cluster import KMeans
# 1. Use SBERT to compare two sentences for semantic similarity.
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
input_ids_1 = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
input_ids_2 = torch.tensor(tokenizer.encode("Hello, my cat is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
outputs_1 = model(input_ids_1)
outputs_2 = model(input_ids_2)
last_hidden_states_1 = outputs_1[0] # The last hidden-state is the first element of the output tuple
last_hidden_states_2 = outputs_2[0] # The last hidden-state is the first element of the output tuple
# 2. Take SBERT embeddings for both sentences and cluster them.
kmeans = KMeans(n_clusters=2, random_state=0).fit(last_hidden_states_1.detach().numpy()[0], last_hidden_states_2.detach().numpy()[0])
# 3. Print the clusters.
print(kmeans.labels_)
print(kmeans.cluster_centers_)
Результат:
[0 0 0 0 0 0 0 1]
[[-0.2281394 0.29968688 0.3390873 ... -0.40648264 0.2930719
0.41721284]
[ 0.6079925 0.26097086 -0.3130729 ... 0.03109726 -0.6282735
-0.19942412]]
Это происходит независимо от того, какое второе предложение. Я изменил его на «Столица Франции — Париж», и он по-прежнему давал мне тот же результат, поэтому очевидно, что я неправильно передаю/преобразую данные.
Что я делаю не так?
Была пара крошечных модификаций, чтобы разобраться. Имейте в виду, что для кластеризации предложений вам нужно поймать только первое/последнее вложение для предложения. Кроме того, KMeans
ожидает получить 2D-массив для кластеризации.
import torch
from transformers import BertTokenizer, BertModel
from sklearn.cluster import KMeans
import numpy as np
# 1. Use SBERT to compare two sentences for semantic similarity.
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
input_ids_1 = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0) # Batch size 1
input_ids_2 = torch.tensor(tokenizer.encode("The capital of France is Paris", add_special_tokens=True)).unsqueeze(0) # Batch size 1
outputs_1 = model(input_ids_1)
outputs_2 = model(input_ids_2)
last_hidden_states_1 = outputs_1[0][0, 0, :] # The last hidden-state is the first element of the output tuple
last_hidden_states_2 = outputs_2[0][0, 0, :] # The last hidden-state is the first element of the output tuple
# 2. Take SBERT embeddings for both sentences and cluster them.
kmeans = KMeans(n_clusters=2, random_state=0).fit([last_hidden_states_1.detach().numpy(), last_hidden_states_2.detach().numpy()])
# 3. Print the clusters.
print(kmeans.labels_)
print(kmeans.cluster_centers_)
выход:
[0 1]
[[-0.11437159 0.19371444 0.1249602 ... -0.38269117 0.21065859
0.54070717]
[-0.06510071 0.06050608 -0.10048206 ... -0.27256876 0.36847278
0.57706201]]
Для масштабирования по количеству образцов текста есть утилита пакетной обработки. Но когда дело доходит до увеличения размера текста, следует помнить о некоторых соображениях. Каждая модель может обрабатывать текст до определенной длины, но есть и такие, которые подходят для длинного текста (правда, не гигантского). Вам нужно найти правильный и соответствующим образом изменить настройки.
Спасибо. Использовал бы я тот же метод, если бы хотел сделать это в масштабе? (т.е. сравнить большой текст с другим большим текстом).