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

如何在Sentence Transformer之上添加线性层实现小样本学习微调?

解决方案:基于Sentence Transformer的小样本适配网络构建

核心问题说明

Sentence Transformer的model.encode()是封装好的推理方法,默认不会保留计算图,因此无法触发参数更新。要实现可训练的适配网络,需要自定义模型类,直接调用其内部前向逻辑并添加线性层。

自定义可训练模型实现

以下是完整的代码示例,包含模型定义、训练流程:

import torch
import torch.nn as nn
from sentence_transformers import SentenceTransformer

class STAdapterModel(nn.Module):
    def __init__(self, st_model_name='all-MiniLM-L6-v2', output_dim=2):
        super().__init__()
        # 加载预训练Sentence Transformer
        self.st_backbone = SentenceTransformer(st_model_name)
        # 先冻结预训练模型参数(小样本场景下优先训练适配层)
        for param in self.st_backbone.parameters():
            param.requires_grad = False
        # 添加适配线性层,维度对应ST的输出嵌入维度
        self.adapter_layer = nn.Linear(
            self.st_backbone.get_sentence_embedding_dimension(), 
            output_dim
        )

    def forward(self, input_sentences):
        # 获取ST的句子嵌入(convert_to_tensor=True保留计算图)
        sentence_embeds = self.st_backbone.encode(
            input_sentences, 
            convert_to_tensor=True, 
            device=self.adapter_layer.weight.device
        )
        # 经过适配层得到最终输出
        outputs = self.adapter_layer(sentence_embeds)
        return outputs

# 实例化模型(根据任务调整output_dim,比如分类任务设为类别数)
model = STAdapterModel(output_dim=2)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
# 初始只优化适配层参数
optimizer = torch.optim.Adam(model.adapter_layer.parameters(), lr=1e-3)

# 训练循环示例
model.train()
for epoch in range(10):
    # 示例数据:句子列表+对应标签
    train_sentences = ["这是正面评价", "这是负面评价", "产品质量很棒", "体验很差"]
    train_labels = torch.tensor([0, 1, 0, 1])
    
    optimizer.zero_grad()
    # 前向传播
    logits = model(train_sentences)
    # 计算损失
    loss = criterion(logits, train_labels)
    # 反向传播+参数更新
    loss.backward()
    optimizer.step()
    
    print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")

进阶:微调Sentence Transformer部分参数

如果训练几轮后想微调ST的部分层以提升效果,可以解冻特定层的参数并调整优化器:

# 解冻ST的最后两层(以MiniLM为例,根据模型结构调整层名)
for name, param in model.st_backbone.named_parameters():
    if 'encoder.layer.10' in name or 'encoder.layer.11' in name:
        param.requires_grad = True

# 更新优化器,同时优化适配层和解冻的ST参数
optimizer = torch.optim.Adam([
    {'params': model.adapter_layer.parameters(), 'lr': 1e-3},
    {'params': [p for n, p in model.st_backbone.named_parameters() if p.requires_grad], 'lr': 5e-5}
])

关键细节

  • 必须在自定义模型的forward方法中调用encode()并设置convert_to_tensor=True,这样才能保留计算图,让适配层的参数参与反向传播。
  • 小样本场景下优先冻结预训练模型,避免过拟合,待适配层收敛后再微调部分层效果更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 03:37:29