【深度学习|学习笔记】预训练(Pretraining)的作用有哪些?
欢迎宝子们点赞、关注、收藏!欢迎宝子们批评指正!
祝所有的硕博生都能遇到好的导师!好的审稿人!好的同门!顺利毕业!
大多数高校硕博生毕业要求需要参加学术会议,发表EI或者SCI检索的学术论文会议论文。详细信息可关注VX “
学术会议小灵通
”或参考学术信息专栏:https://fighting.blog.csdn.net/article/details/146986229
以下是预训练模型的主要好处:
预训练模型不仅限于单一任务,如今还广泛应用于:
优点 | 说明 |
---|---|
性能提升 | 提高准确率,提升模型表达能力 |
收敛更快 | 初始化更优,训练更稳定 |
降低成本 | 节省时间与算力 |
泛化更强 | 数据少时表现依然优秀 |
易于迁移 | 可快速应用于多种任务 |
可复现性强 | 使用社区公认结构与权重 |
为了将你自己的遥感数据(输入波段为 17)用作 DenseNet121 的预训练基础,并替代默认的 ImageNet 预训练权重,你需要完成以下三步:
in_channels=3
,你需要改为 17:self.densenet = models.densenet121(pretrained=False) # 不加载ImageNet预训练权重
self.densenet.features.conv0 = nn.Conv2d(17, 64, kernel_size=7, stride=2, padding=3, bias=False)
# 自定义预训练
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import models
from torch.utils.data import DataLoader, Subset
from your_dataset import YourDataset # 替换为你的数据集类
# 1. 加载模型(通道17)
model = models.densenet121(pretrained=False)
model.features.conv0 = nn.Conv2d(17, 64, kernel_size=7, stride=2, padding=3, bias=False)
model.classifier = nn.Linear(1024, num_classes) # 你设置的分类数
# 2. 提取10%数据作为预训练集
full_dataset = YourDataset()
pretrain_size = int(0.1 * len(full_dataset))
pretrain_indices = torch.randperm(len(full_dataset))[:pretrain_size]
pretrain_subset = Subset(full_dataset, pretrain_indices)
pretrain_loader = DataLoader(pretrain_subset, batch_size=16, shuffle=True)
# 3. 设置优化器和损失函数
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
optimizer = optim.Adam(model.parameters(), lr=1e-4)
criterion = nn.CrossEntropyLoss()
# 4. 执行预训练
for epoch in range(10): # 可调整
model.train()
total_loss = 0
for inputs, labels in pretrain_loader:
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {total_loss:.4f}")
# 5. 保存你自训练的模型参数
torch.save(model.state_dict(), "densenet121_17bands_pretrained.pth")
class DenseNet(nn.Module):
def __init__(self, num_classes=6):
super(DenseNet, self).__init__()
self.densenet = models.densenet121(pretrained=False)
self.densenet.features.conv0 = nn.Conv2d(17, 64, kernel_size=7, stride=2, padding=3, bias=False)
self.densenet.classifier = nn.Linear(1024, num_classes)
# 加载自定义预训练参数
self.densenet.load_state_dict(torch.load("densenet121_17bands_pretrained.pth"))
self.features = self.densenet.features
self.classifier = self.densenet.classifier
def forward(self, x):
des1 = self.features.conv0(x)
des1 = self.features.norm0(des1)
des1 = self.features.relu0(des1)
des1 = self.features.pool0(des1)
des2 = self.features.denseblock1(des1)
des2 = self.features.transition1(des2)
des3 = self.features.denseblock2(des2)
des3 = self.features.transition2(des3)
des4 = self.features.denseblock3(des3)
des4 = self.features.transition3(des4)
return des1, des2, des3, des4
步骤 | 说明 |
---|---|
修改通道 | 将 conv0 改为接受 17 通道输入 |
自定义预训练 | 使用 10% 数据对 DenseNet 进行初步训练 |
模型初始化 | 使用你训练得到的参数作为后续模型的初始化 |