transfer dense121迁移学习模型模板参数不变只训练classifier这一层的参数

本文介绍了一个使用预训练DenseNet121模型进行猫狗图像分类的深度学习项目。通过定义图像转换、加载数据集、冻结参数、构建分类器并训练模型,展示了如何在PyTorch框架下实现图像分类任务。同时,监测训练和验证损失,以评估模型性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# Freeze parameters so we don't backprop through them
#print("model.parameters()=",type(model.parameters()))

import torch
from torch import nn
from torch import optim
import torch.nn.functional as F
from torchvision import datasets, transforms, models
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as plt
import helper
from collections import OrderedDict


data_dir = 'Cat_Dog_data'

# TODO: Define transforms for the training data and testing data
train_transforms = transforms.Compose([transforms.RandomRotation(30),
                                       transforms.RandomResizedCrop(224),                                     
                                       transforms.RandomHorizontalFlip(),
                                       transforms.ToTensor(),
                                       transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))                                      
                                      ])

test_transforms = transforms.Compose([transforms.RandomRotation(30),
                                       transforms.RandomResizedCrop(224),                                       
                                       transforms.RandomHorizontalFlip(),
                                       transforms.ToTensor(),
                                       transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))                                      
                                      ])

# Pass transforms in here, then run the next cell to see how the transforms look
train_data = datasets.ImageFolder(data_dir + '/train', transform=train_transforms)
test_data = datasets.ImageFolder(data_dir + '/test', transform=test_transforms)

trainloader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)
testloader = torch.utils.data.DataLoader(test_data, batch_size=64)

epoches =1
every=70
steps=0

tr_losses = []
te_losses = []
test_accu=0
train_loss=0
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") #选什么设备
model = models.densenet121(pretrained=True)
for param in model.parameters():
    param.requires_grad = False

from collections import OrderedDict
classifier = nn.Sequential(OrderedDict([
                          ('fc1', nn.Linear(1024, 500)),
                          ('relu', nn.ReLU()),
                          ('fc2', nn.Linear(500, 2)),
                          ('output', nn.LogSoftmax(dim=1))
                          ]))
    
model.classifier = classifier
criterion = nn.NLLLoss()
opti = optim.Adam(model.classifier.parameters(),lr=0.001)
model.to(device)

for e in range(epoches):

    print("trainloader.len=",len(trainloader))
    for inputs,labels in trainloader:

        opti.zero_grad()
        inputs,labels = inputs.to(device),labels.to(device)
        steps+=1
        #print("inputs.shape=",inputs.shape)
        #imgs = imgs.view(inputs.shape[0],-1)
        ps = model.forward(inputs)

       
        loss = criterion(ps,labels)
        train_loss+=loss
        tr_losses.append(loss)
        loss.backward()
        opti.step()
        
        if steps%every==0:
            test_loss=0
            test_accu=0
            model.eval()
            with torch.no_grad():
                for imgs2 ,lb2 in testloader:
                    imgs2,lb2=imgs2.to(device),lb2.to(device)
                    #imgs2 = imgs2.view(imgs2.shape[0],-1)
                    ps2=model.forward(imgs2)

                   
                    loss2 = criterion(ps2,lb2)
                    te_losses.append(loss2)
                    test_loss+=loss2

                    ps2 = torch.exp(ps2)#为了计算准确率
                    t_p,t_c = ps2.topk(1,dim=1)
                    equals = t_c==lb2.view(t_c.shape)
                    test_accu = torch.mean(equals.type(torch.FloatTensor))
            model.train()
            print("accur={}".format(test_accu),"train_loss={}".format(train_loss/every),"test_loss={}".format(test_loss/len(testloader)))               
            train_loss=0
print("######################################观察训练与校验损失函数走向便于确定过拟合位置")
plt.plot(tr_losses, label='Training loss')
plt.plot(te_losses, label='Validation loss')
plt.legend(frameon=False)     

https://classroom.udacity.com/nanodegrees/nd009-cn-advanced/parts/5f4d630c-d15a-412c-aaeb-b57ad61cd03c/modules/3aa9e812-62cd-4ae3-8fc4-593538f08455/lessons/9b014a97-2267-4f1b-af97-284b7dac2a58/concepts/572cd59e-540f-43d9-906f-33d22a4452a6

### 添加 Dropout 层的作用与实现 #### Dropout 的作用 Dropout 是一种正则化技术,用于减少神经网络中的过拟合现象。通过在训练过程中随机丢弃一部分神经元,使得模型无法完全依赖某些特定的特征组合来完成预测任务,从而提高模型的泛化能力[^1]。 #### 在 ResNet 中添加 Dropout 层的效果 在 ResNet 模型中引入 Dropout 层可以帮助缓解因复杂结构带来的过拟合风险。尤其当数据集较小或者模型较深时,这种效果更为显著。然而需要注意的是,在已经具有残差连接机制的情况下,ResNet 对抗梯度消失的能力较强,因此 Dropout 并不是必需品。但在实际应用中,适当增加 Dropout 可进一步提升性能稳定性[^3]。 #### 使用 PyTorch 实现 Dropout 方法 以下是利用 PyTorch 将 Dropout 集成至 ResNet 模型的具体代码示例: ```python import torch.nn as nn from torchvision import models class CustomResNet(nn.Module): def __init__(self, num_classes=2, dropout_rate=0.5): super(CustomResNet, self).__init__() # 加载预训练的 ResNet 模型 resnet = models.resnet18(pretrained=True) # 替换最后一层全连接层,并加入 Dropout layers = list(resnet.children())[:-1] # 移除原 FC 层 self.feature_extractor = nn.Sequential(*layers) # 定义新的分类头,包含 Dropout 和 FC 层 self.classifier = nn.Sequential( nn.Dropout(p=dropout_rate), nn.Linear(512, num_classes) # 修改为对应类别数 ) def forward(self, x): features = self.feature_extractor(x) features = features.view(features.size(0), -1) # 扁平化处理 output = self.classifier(features) return output ``` 上述代码展示了如何修改标准 ResNet 结构以支持自定义分类器部分的同时集成 Dropout 功能[^2]。 #### TensorFlow/Keras 下的应用实例 同样也可以采用 Keras API 来构建带 Dropout 的 ResNet 模型如下所示: ```python from tensorflow.keras.applications import ResNet50 from tensorflow.keras.models import Model from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout base_model = ResNet50(weights='imagenet', include_top=False) x = base_model.output x = GlobalAveragePooling2D()(x) x = Dropout(rate=0.5)(x) # 插入 Dropout 层 predictions = Dense(units=2, activation='softmax')(x) model = Model(inputs=base_model.input, outputs=predictions) for layer in base_model.layers: layer.trainable = False # 冻结基础模型参数 ``` 此段脚本说明了怎样借助 Transfer Learning 技巧快速搭建适合迁移学习场景下的改进版本 ResNet 架构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值