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

如何使用Huggingface BERT输出作为输入搭建二分类CNN模型

基于BERT输出实现可变长度输入的二分类CNN模型(PyTorch实现)

前置处理优化

你当前逐句调用tokenizer的方式仅适合单样本推理,实际训练时可以在调用tokenizer时添加padding='max_length'、truncation=True、max_length=32参数,直接将所有输入补全/截断到统一长度,此时BERT输出的序列维度固定,是最通用的训练方案。
如果确实需要支持完全无截断的可变长度输入,CNN本身的卷积+池化结构天然可以适配,不需要固定序列长度。

适配可变长度输入的CNN实现代码

import torch
import torch.nn as nn
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModel

class BertEinsteinClassifier(nn.Module):
    def __init__(self, embed_dim=768, num_classes=2, filter_sizes=[2,3,4], num_filters=100, dropout=0.5):
        super().__init__()
        # 定义不同尺寸的卷积核,提取不同粒度的文本特征
        self.convs = nn.ModuleList([
            nn.Conv2d(in_channels=1, out_channels=num_filters, kernel_size=(fs, embed_dim)) 
            for fs in filter_sizes
        ])
        self.dropout = nn.Dropout(dropout)
        self.classifier = nn.Linear(len(filter_sizes) * num_filters, num_classes)

    def forward(self, bert_last_hidden_state):
        # bert_last_hidden_state输入形状:[batch_size, seq_len, embed_dim],seq_len为任意长度
        # 新增通道维度适配Conv2d输入要求:[batch_size, 1, seq_len, embed_dim]
        x = bert_last_hidden_state.unsqueeze(1)
        
        conv_results = []
        for conv in self.convs:
            # 卷积后过ReLU激活,去掉最后一个冗余维度
            conv_out = F.relu(conv(x)).squeeze(3)
            # *最大池化是适配可变长度的核心:无论序列长度多少,每个卷积核在整个序列维度取最大值,得到固定长度输出*
            pool_out = F.max_pool1d(conv_out, conv_out.size(2)).squeeze(2)
            conv_results.append(pool_out)
        
        # 拼接所有卷积核的特征,得到固定长度的全局特征向量
        concat_feature = torch.cat(conv_results, dim=1)
        concat_feature = self.dropout(concat_feature)
        # 输出二分类logits
        return self.classifier(concat_feature)

调用测试示例

# 初始化组件
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
bert_model = AutoModel.from_pretrained("bert-base-uncased")
classifier = BertEinsteinClassifier()

# 测试输入
test_texts = [
    "Hello World", 
    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe."
]

bert_model.eval()
classifier.eval()
with torch.no_grad():
    for text in test_texts:
        model_input = tokenizer(text, return_tensors="pt")
        bert_out = bert_model(**model_input).last_hidden_state
        logits = classifier(bert_out)
        # 预测结果:1=爱因斯坦所说,0=非爱因斯坦所说
        pred = torch.argmax(logits, dim=1).item()
        print(f"文本:{text}\n预测结果:{pred}\n")

训练注意事项

  • 批量训练时建议统一输入长度,可大幅提升训练效率,避免逐句计算的性能损耗
  • 可以选择冻结BERT参数只训练CNN分类头,或者微调BERT+CNN整体参数,根据你的数据集规模决定

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:27:03