SBERT дает одинаковый результат независимо от того, что

У меня есть тестовый скрипт для 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]]

Это происходит независимо от того, какое второе предложение. Я изменил его на «Столица Франции — Париж», и он по-прежнему давал мне тот же результат, поэтому очевидно, что я неправильно передаю/преобразую данные.

Что я делаю не так?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Была пара крошечных модификаций, чтобы разобраться. Имейте в виду, что для кластеризации предложений вам нужно поймать только первое/последнее вложение для предложения. Кроме того, 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]]

Спасибо. Использовал бы я тот же метод, если бы хотел сделать это в масштабе? (т.е. сравнить большой текст с другим большим текстом).

reallymemorable 28.11.2022 15:08

Для масштабирования по количеству образцов текста есть утилита пакетной обработки. Но когда дело доходит до увеличения размера текста, следует помнить о некоторых соображениях. Каждая модель может обрабатывать текст до определенной длины, но есть и такие, которые подходят для длинного текста (правда, не гигантского). Вам нужно найти правильный и соответствующим образом изменить настройки.

meti 29.11.2022 06:36

Другие вопросы по теме