将BERT句嵌入作为Support Vector Regression输入时的报错问询
问题解决:BERT嵌入用于SVR回归的格式错误
错误核心原因
你遇到的ValueError: setting an array element with a sequence本质问题是:
- BERT返回的
output[0]是单条文案中每个token的嵌入,形状为(1, 序列长度, 768),不同Instagram文案的长度不一致,导致ravel()后每个样本的特征维度不统一,而sklearn模型要求输入的特征矩阵必须是每行维度相同的二维数组 np.vectorize(np.float_)属于多余操作,detach().numpy()已经输出float类型数组,这个操作反而可能引发不必要的类型转换异常
修复方案
要得到固定长度的句子嵌入,以下两种常用方法二选一即可:
方法1:使用<[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]>token的嵌入(推荐)
BERT的<[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]>token对应整个句子的聚合嵌入,直接提取该token的输出就能得到固定768维的句子嵌入:
from transformers import BertTokenizer, BertModel import numpy as np tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased') model = BertModel.from_pretrained("bert-base-multilingual-cased") caption_embeddings = [] for caption in Captions[:10]: # 开启padding和truncation,确保序列长度统一(可选,避免极端长文本) encoded_input = tokenizer(caption, return_tensors='pt', padding=True, truncation=True) output = model(**encoded_input) # 提取<[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]>token的嵌入,形状为(1,768) cls_embedding = output.last_hidden_state[:, 0, :] caption_embeddings.append(cls_embedding.detach().numpy()) # 转换为二维numpy数组,形状为(n_samples, 768) X = np.concatenate(caption_embeddings, axis=0)
方法2:对所有token嵌入做平均池化
如果不想依赖<[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]>token,也可以对单条文案的所有token嵌入做平均,得到固定768维的嵌入:
from transformers import BertTokenizer, BertModel import numpy as np tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased') model = BertModel.from_pretrained("bert-base-multilingual-cased") caption_embeddings = [] for caption in Captions[:10]: encoded_input = tokenizer(caption, return_tensors='pt', padding=True, truncation=True) output = model(**encoded_input) # 对序列维度做平均,得到形状为(1,768)的嵌入 avg_embedding = output.last_hidden_state.mean(axis=1) caption_embeddings.append(avg_embedding.detach().numpy()) # 转换为二维numpy数组,形状为(n_samples, 768) X = np.concatenate(caption_embeddings, axis=0)
后续标准化与模型训练
得到统一维度的特征矩阵后,再执行标准化和模型训练就不会报错了:
from sklearn.preprocessing import StandardScaler from sklearn.svm import SVR sc_X = StandardScaler() sc_y = StandardScaler() # 标准化特征矩阵 X_scaled = sc_X.fit_transform(X) # 目标变量需要转为二维数组后再标准化,最后ravel为一维适配SVR y_scaled = sc_y.fit_transform(ytrain.reshape(-1, 1)).ravel() regr = SVR() regr.fit(X_scaled, y_scaled)
内容的提问来源于stack exchange,提问作者Tara van Mierlo
相关产品推荐
相关产品推荐

