You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将自定义特征输入BERT模型进行推特分类微调?

解决BERT融合自定义特征的推特分类器微调方案

要在BertForSequenceClassification中加入自定义特征(脏话数量、正向表情数、负向表情数、推文长度),核心是自定义模型结构,将BERT的文本表征与自定义特征拼接后再进行分类。以下是具体实现步骤:

1. 数据预处理补充

除了常规的文本tokenize(生成input_ids、attention_mask、token_type_ids),还需要将自定义特征转换为张量,并建议做归一化处理(消除数值范围差异,比如推文长度除以最大长度,脏话数量等按比例缩放):

import torch
import pandas as pd
from transformers import BertTokenizer

# 加载自定义特征DataFrame
df = pd.DataFrame({
    "脏话数量": [2,0,1],
    "正向表情数": [1,0,0],
    "负向表情数": [0,1,1],
    "推文长度": [123,52,87]
})

# 归一化自定义特征
df["推文长度"] = df["推文长度"] / df["推文长度"].max()
df[["脏话数量", "正向表情数", "负向表情数"]] = df[["脏话数量", "正向表情数", "负向表情数"]] / df[["脏话数量", "正向表情数", "负向表情数"]].max()

# 转换为张量
custom_features = torch.tensor(df.values, dtype=torch.float32)

2. 自定义融合特征的BERT分类模型

继承BertPreTrainedModel,在原有BERT结构基础上,加入自定义特征的拼接逻辑:

from transformers import BertPreTrainedModel, BertModel

class BertWithCustomFeatures(BertPreTrainedModel):
    def __init__(self, config):
        super().__init__(config)
        self.bert = BertModel(config)
        self.dropout = torch.nn.Dropout(config.hidden_dropout_prob)
        # 自定义特征维度是4,BERT池化输出维度是config.hidden_size(默认768)
        self.classifier = torch.nn.Linear(config.hidden_size + 4, config.num_labels)
        self.init_weights()

    def forward(self, input_ids=None, attention_mask=None, token_type_ids=None, custom_features=None):
        # 获取BERT的<[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]>token池化输出
        outputs = self.bert(input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)
        pooled_output = outputs[1]
        pooled_output = self.dropout(pooled_output)
        
        # 拼接自定义特征与BERT输出
        combined_output = torch.cat([pooled_output, custom_features], dim=1)
        logits = self.classifier(combined_output)
        
        return logits

3. 模型初始化与训练

加载预训练模型权重,并在训练循环中传入自定义特征:

from transformers import AdamW, get_linear_schedule_with_warmup

# 初始化模型
model_name = "bert-base-uncased"
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertWithCustomFeatures.from_pretrained(model_name, num_labels=2) # 假设是二分类

# 训练配置(示例)
optimizer = AdamW(model.parameters(), lr=2e-5)
epochs = 3
total_steps = len(train_dataloader) * epochs
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=0, num_training_steps=total_steps)

# 训练循环(需结合你的数据加载逻辑,确保每个batch包含文本输入和自定义特征)
model.train()
for epoch in range(epochs):
    for batch in train_dataloader:
        input_ids = batch["input_ids"]
        attention_mask = batch["attention_mask"]
        labels = batch["labels"]
        custom_feats = batch["custom_features"]
        
        optimizer.zero_grad()
        logits = model(input_ids=input_ids, attention_mask=attention_mask, custom_features=custom_feats)
        loss = torch.nn.CrossEntropyLoss()(logits, labels)
        loss.backward()
        optimizer.step()
        scheduler.step()

关键注意要点

  • 特征归一化:自定义特征数值范围差异大(比如推文长度远大于脏话数量),必须归一化,否则模型会偏向数值大的特征。
  • 维度匹配:确保自定义特征的维度是(batch_size, num_custom_features),与BERT池化输出的(batch_size, hidden_size)在batch维度一致,才能拼接。
  • 数据加载:在构建DataLoader时,要将自定义特征与文本输入的张量打包成同一个batch,方便训练时传入模型。

内容的提问来源于stack exchange,提问作者BashMocha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 05:25:12