前言

之前读研的时候一直都是自己构建模型,从零训练模型,这几天打算微调一个NLP模型做一些任务练练手,在操作的过程中总是把微调跟之前的从零训练弄混,于是就打算整理一篇笔记记录一下二者区别

微调与从零训练

微调是指在已经预训练好的模型基础上,使用特定领域或任务的数据进行二次训练的过程。

从零训练则是不依赖任何预训练模型或已有权重,完全从随机初始化的模型参数开始,仅基于目标任务的数据集,对神经网络的所有层、所有参数进行完整训练的方式。

举个例子来通俗点解释:假如你买了一辆已经组装好的自行车,微调就是根据你的身高、体重等个人情况,调整座椅高度、把手角度等细节。

而从零训练就是从原材料和零件生产开始,设计完整的自行车结构,一步步组装所有部件,最终完全定制一辆适合你身高体重的自行车。

从代码层面分析

从代码实现的角度,微调和直接训练在模型初始化、参数处理、优化器设置和训练策略等方面存在明显差异

模型初始化差异

例如,如下一个简单的CNN网络的代码,从零训练需要自定义网络结构所有参数随机初始化:

# 从头定义网络架构class CustomCNN(nn.Module):    def __init__(self):        super(CustomCNN, self).__init__()        self.conv1 = nn.Conv2d(3, 16, 3, padding=1)        self.conv2 = nn.Conv2d(16, 32, 3, padding=1)        self.conv3 = nn.Conv2d(32, 64, 3, padding=1)        self.pool = nn.MaxPool2d(2, 2)        self.fc1 = nn.Linear(64 * 4 * 4, 512)        self.fc2 = nn.Linear(512, 10)        self.relu = nn.ReLU()        self.dropout = nn.Dropout(0.5)    def forward(self, x):        x = self.pool(self.relu(self.conv1(x)))        x = self.pool(self.relu(self.conv2(x)))        x = self.pool(self.relu(self.conv3(x)))        x = x.view(-1, 64 * 4 * 4)        x = self.dropout(self.relu(self.fc1(x)))        x = self.fc2(x)        return x# 创建模型实例 - 完全从头开始model = CustomCNN()

而微调需要加载预训练模型,使用在大规模数据集上训练好的权重

# 加载预训练模型 - 使用已有权重model = models.resnet18(pretrained=True)# 修改最后的全连接层 - 适应新任务num_ftrs = model.fc.in_featuresmodel.fc = nn.Sequential(    nn.Linear(num_ftrs, 512),    nn.ReLU(),    nn.Dropout(0.5),    nn.Linear(512, 10)  # 假设是10分类任务)

参数冻结

从零训练的模型的所有参数都参与训练和更新,不需要冻结操作

# 所有参数默认都参与训练# 不需要额外的冻结操作model = CustomCNN()# 所有参数都在优化器中optimizer = optim.Adam(    model.parameters(),  # 所有参数    lr=0.001)

微调则需要通过设置 requires_grad=False 冻结部分参数,只训练特定层

# 加载预训练模型model = models.resnet18(pretrained=True)# 冻结部分层 - 只训练最后几层ct = 0for child in model.children():    ct += 1    if ct < 7:  # 冻结前7个层组        for param in child.parameters():            param.requires_grad = False            print(f"冻结层组 {ct}: {child.__class__.__name__}")# 只优化未冻结的参数optimizer = optim.Adam(    filter(lambda p: p.requires_grad, model.parameters()),    lr=0.001)

优化器设置

  • 从零训练通常所有参数使用相同的学习率
# 所有参数使用相同的学习率optimizer = optim.Adam(    model.parameters(),    lr=0.001,  # 单一学习率    betas=(0.9, 0.999),    eps=1e-08,    weight_decay=0,    amsgrad=False)
  • 微调常使用分层学习率,新层用较大学习率,预训练层用较小学习率
# 不同层使用不同学习率optimizer = optim.Adam([    # 倒数第二层使用较小学习率    {'params': model.layer4.parameters(), 'lr': 0.001},        # 新的全连接层使用较大学习率    {'params': model.fc.parameters(), 'lr': 0.01}], lr=0.0001)  # 默认学习率# 或者使用学习率调度器scheduler = optim.lr_scheduler.ReduceLROnPlateau(    optimizer,     mode='min',     factor=0.1,     patience=10,    verbose=True)

训练策略

  • 从零训练需要更多训练轮次,使用较大学习率
# 训练配置batch_size = 64epochs = 50  # 更多轮次learning_rate = 0.001# 训练循环for epoch in range(epochs):    model.train()    running_loss = 0.0        for inputs, labels in train_loader:        inputs, labels = inputs.to(device), labels.to(device)                optimizer.zero_grad()        outputs = model(inputs)        loss = criterion(outputs, labels)        loss.backward()        optimizer.step()                running_loss += loss.item()        print(f'Epoch {epoch+1}/{epochs}, Loss: {running_loss/len(train_loader):.4f}')
  • 微调常采用分阶段训练,总轮次更少,学习率更小
# 微调配置batch_size = 32epochs = 10  # 更少轮次learning_rate = 0.0001  # 更小学习率# 第一阶段:只训练新层for epoch in range(5):    model.train()    # 训练代码...# 第二阶段:解冻部分层继续微调for param in model.layer4.parameters():    param.requires_grad = True# 使用更小的学习率optimizer = optim.Adam(    filter(lambda p: p.requires_grad, model.parameters()),    lr=0.00001  # 进一步减小学习率)for epoch in range(5, 10):    model.train()    # 训练代码...

总结

什么时候用哪种方法?

  • 从零训练:当你有大量数据,或者任务很特殊(预训练模型不适合)
  • 微调:当你数据有限,或者任务与预训练任务相似

目前打算做一个简单的诈骗短信分类的任务,最简单方法则感觉是微调一个中文的NLP模型来完成,因此本次先简单记录一下差异,便于后续任务探究~

方面 直接训练 微调
模型初始化 class CustomModel(nn.Module):models.Sequential([...]) models.resnet18(pretrained=True)applications.MobileNetV2(weights='imagenet')
参数冻结 所有参数默认参与训练 param.requires_grad = Falsebase_model.trainable = False
优化器设置 optimizer = optim.Adam(model.parameters(), lr=0.001) optimizer = optim.Adam([{'params': layer1, 'lr': 0.001}, {'params': layer2, 'lr': 0.01}])
训练轮次 通常 30-100 轮 通常 5-20 轮
学习率 较大 (0.001) 较小 (0.0001 或更小)
数据增强 较强的增强策略 相对温和的增强策略
训练策略 单一阶段训练 常采用分阶段训练策略

如何学习AI大模型?

如果你对AI大模型入门感兴趣,那么你需要的话可以点击这里大模型重磅福利:入门进阶全套104G学习资源包免费分享!

这份完整版的大模型 AI 学习和面试资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

在这里插入图片描述

这是一份大模型从零基础到进阶的学习路线大纲全览,小伙伴们记得点个收藏!

请添加图片描述
第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

100套AI大模型商业化落地方案

请添加图片描述

大模型全套视频教程

请添加图片描述

200本大模型PDF书籍

请添加图片描述

👉学会后的收获:👈

• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

LLM面试题合集

请添加图片描述

大模型产品经理资源合集

请添加图片描述

大模型项目实战合集

请添加图片描述

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐