编程小菜学习之李沐老师动手学深度学习笔记-37微调


# 37 微调
# 源数据集通常远复杂目标数据,效果更好
import matplotlib.pyplot as plt
import os
import torch
import torchvision
from torch import nn
from d2l import torch as d2l


# resnet18模型下载路径
os.environ['TORCH_HOME']=r'D:\worksoftware\PycharmProjects\pythonProject\torch_model'


# 下载,会主动在data文件夹下,下载名为hotdog.zip数据集
d2l.DATA_HUB['hotdog'] = (d2l.DATA_URL + 'hotdog.zip', 'fba480ffa8aa7e0febbb511d181409f899b9baa5')
data_dir = d2l.download_extract('hotdog')
# 读取
train_imgs = torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train'))
test_imgs = torchvision.datasets.ImageFolder(os.path.join(data_dir, 'test'))

# for x, y in train_imgs:
    #print(x.size) # 图片杂大小杂乱无章
    #print(y) 标号1代表热狗,0代表其他类型,是个二分类数据集

#显示前8个正类样本图⽚和最后8张负类样本图⽚。
hotdogs = [train_imgs[i][0] for i in range(8)]
not_hotdogs = [train_imgs[-i - 1][0] for i in range(8)]
d2l.show_images(hotdogs + not_hotdogs, 2, 8, scale=1.4)
plt.show() # 这一行,不加不显示图片

# 数据增广
#Normalize() 函数的作用是将数据转换为标准正太分布,使模型更容易收敛
# 对每一个channel,([mean], [std])    (x-mean)/std
normalize = torchvision.transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])

#增广,也就是对图片剪切,调整大小,色彩,对比度等
# 224x224与imagnet一致,随机水平旋转,转换成张量,正则化
train_augs = torchvision.transforms.Compose([
    torchvision.transforms.RandomResizedCrop(224),
    torchvision.transforms.RandomHorizontalFlip(),
    torchvision.transforms.ToTensor(),
    normalize]
)
#CenterCrop:在图片的中间区域进行裁剪
test_augs = torchvision.transforms.Compose([
    torchvision.transforms.Resize(256),
    torchvision.transforms.CenterCrop(224),
    torchvision.transforms.ToTensor(),
    normalize]
)

# 定义和初始化模型
pretrained_net = torchvision.models.resnet18(pretrained=True)
#下载模型,pretrained=True:把训练好的参数也拿下来

print(pretrained_net.fc) # 最后的一层全连接层
# Linear(in_features=512, out_features=1000, bais=Ture)

finetune_net = torchvision.models.resnet18(pretrained=True)
finetune_net.fc = nn.Linear(finetune_net.fc.in_features, 2) # 替换最后一层,改为二分类(512, 2)
# 仅初始化最后一层权重,其他层不变
nn.init.xavier_uniform_(finetune_net.fc.weight)

# 微调模型
def train_fine_tuning(net, learning_rate, batch_size=128, num_epochs=5, param_group=True):
    # 数据迭代处理
    train_iter = torch.utils.data.DataLoader(
        train_imgs = torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train'),
        transform=train_augs), batch_size=batch_size, shuffle=True)
    test_iter = torch.utils.data.DataLoader(
        test_imgs=torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train'),
        transform=train_augs), batch_size=batch_size, shuffle=True)
    # 采用cpu/gpu运算,前面章节有介绍
    devices = d2l.try_all_gpus()
    #定义损失 reduction='none':输出损失就是一个和样本数相等的向量
    loss = nn.CrossEntropyLoss(reduction='none')
    # 非最后一层学习率为lr,最后一层学习率lr*10
    # 这里还对权重w进行惩罚 lambd=0.0001
    if param_group:
        params_1x = [param for name, param in net.named_parameters()
                     if name not in ['fc.weight', 'fc.bias']]
        trainer = torch.optim.SGD([{'params':params_1x},
                                   {'params':net.fc.parameters(),  'lr':learning_rate*10}],
                                  lr = learning_rate, weight_decay=0.001 )
    else:
        trainer = torch.optim.SGD(net.parameters(), lr = learning_rate, weight_decay=0.001)

    d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, devices)


train_fine_tuning(finetune_net, 5e-5)


# 比较更新全部参数
scratch_net = torchvision.models.resnet18()
scratch_net.fc = nn.Linear(scratch_net.fc.in_features, 2)
train_fine_tuning(scratch_net,5e-4, param_group=False)

备注:仅学习使用无需任何打赏

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值