Pytorch学习笔记(四)

(8)迁移学习(Transfer Learning)
接下来将会使用ResNet进行迁移学习,完成图片分类。目前迁移学习的方式主要有两种,一种是fineturning,就是只改变pretrain网络最后一层或者几层的网络结构,对于pretrain网络的全局参数在原来的基础上进行微调;另外一种是将ConvNet当做一个特征提取器(Feature Extractor),结构方面只改变pretrain网络最后一层或者几层的网络结构,对于参数的话固定住前面没有改变部分的参数,只对后面修改过的层进行更新。
两种方式的代码如下:

# -*- coding:utf-8 -*-
# Transfer Learning tutorial
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.optim as optim
import numpy as np
import torchvision
from torchvision import datasets, models, transforms
import matplotlib.pyplot as plt
import time
import copy
import os


data_transforms = {
    'train': transforms.Compose([
        transforms.RandomSizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'val': transforms.Compose([
        transforms.Scale(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])
}

data_dir = './data/hymenoptera_data'
dsets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x])
         for x in ['train', 'val']}
dset_loaders = {x: torch.utils.data.DataLoader(dsets[x], batch_size=4,
                                               shuffle=True, num_workers=4)
                for x in ['train', 'val']}
dset_sizes = {x: len(dsets[x]) for x in ['train', 'val']}
dset_classes = dsets['train'].classes
print(dset_classes)


use_gpu = torch.cuda.is_available()
print(use_gpu)

def imshow(inp, title=None):
    inp = inp.numpy().transpose(1, 2, 0)
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    inp = std * inp + mean
    plt.imshow(inp)
    if title is not None:
        plt.title(title)

inputs, classes = next(iter(dset_loaders['train']))
out = torchvision.utils.make_grid(inputs)
imshow(out, title=[dset_classes[x] for x in classes])
# plt.show()


def train_model(model, criterion, optimizer, lr_scheduler, num_epoch=25):
    since = time.time()

    best_model = model
    best_acc = 0.0

    for epoch in range(num_epoch):
        print('Epoch {}/{}'.format(epoch, num_epoch - 1))
        print('-' * 10)

        for phase in ['train', 'val']:
            if phase == 'train':
                optimizer = lr_scheduler(optimizer, epoch)
                model.train(True)
            else:
                model.train(False)

            running_loss = 0.0
            running_corrects = 0

            for data in dset_loaders[phase]:
                inputs, labels = data
                if use_gpu:
                    inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda())
                else:
                    inputs, labels = Variable(inputs), Variable(labels)
                optimizer.zero_grad()
                outputs = model(inputs)
                _, preds = torch.max(outputs.data, 1)
                loss = criterion(outputs, labels)

                if phase == 'train':
                    loss.backward()
                    optimizer.step()

                running_loss += loss.data[0]
                running_corrects += torch.sum(preds == labels.data)

            epoch_loss = running_loss / dset_sizes[phase]
            epoch_acc = running_corrects / dset_sizes[phase]

            print('{} Loss: {:.4f} Acc: {:.4f}'.format(
                phase, epoch_loss, epoch_acc))

            if phase == 'val' and epoch_acc > best_acc:
                best_acc = epoch_acc
                best_model = copy.deepcopy(model)


        print()

    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(
        time_elapsed // 60, time_elapsed % 60))
    print("Best val Acc: {:4f}".format(best_acc))
    return best_model



def exp_lr_scheduler(optimizer, epoch, init_lr=0.001, lr_decay_epoch=7):
    lr = init_lr * (0.1 ** (epoch // lr_decay_epoch))
    if epoch % lr_decay_epoch == 0:
        print("LR is set to {}".format(lr))
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr
    return optimizer


def visualize_model(model, num_images=6):
    images_so_far = 0
    fig = plt.figure()
    for i, data in enumerate(dset_loaders['val']):
        inputs, labels = data
        if use_gpu:
            inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda())
        else:
            inputs, labels = Variable(inputs), Variable(labels)

        outputs = model(inputs)
        _, preds = torch.max(outputs.data, 1)

        for j in range(inputs.size()[0]):
            images_so_far += 1
            ax = plt.subplot(num_images // 2, 2, images_so_far)
            ax.axis('off')
            ax.set_title('predicted: {}'.format(dset_classes[labels.data[j]]))
            imshow(inputs.cpu().data[j])
            if images_so_far == num_images:
                return


# Finetuning the convnet
model_ft = models.resnet18(pretrained=True)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, 2)

if use_gpu:
    model_ft = model_ft.cuda()

criterion = nn.CrossEntropyLoss()
optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)

model_ft = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler, num_epoch=25)

visualize_model(model_ft)
plt.ioff()
plt.show()




# ConvNet as feature extractor
model_conv = models.resnet18(pretrained=True)
for param in model_conv.parameters():
    param.requires_grad = False

num_ftrs = model_conv.fc.in_features
model_conv.fc = nn.Linear(num_ftrs, 2)

if use_gpu:
    model_conv = model_conv.cuda()

criterion = nn.CrossEntropyLoss()

optimizer_conv = optim.SGD(model_conv.fc.parameters(), lr=0.001, momentum=0.9)

model_conv = train_model(model_conv, criterion, optimizer_conv,
                         exp_lr_scheduler, num_epochs=25)

visualize_model(model_conv)
plt.ioff()
plt.show()

运行结果如下:

['ants', 'bees']
True
Epoch 0/24
----------
LR is set to 0.001
train Loss: 0.1694 Acc: 0.6311
val Loss: 0.1212 Acc: 0.7974

Epoch 1/24
----------
train Loss: 0.1318 Acc: 0.7623
val Loss: 0.0505 Acc: 0.9216

Epoch 2/24
----------
train Loss: 0.1236 Acc: 0.7992
val Loss: 0.0510 Acc: 0.9085

Epoch 3/24
----------
train Loss: 0.1451 Acc: 0.7705
val Loss: 0.0487 Acc: 0.9412

Epoch 4/24
----------
train Loss: 0.1047 Acc: 0.8525
val Loss: 0.0753 Acc: 0.9020

Epoch 5/24
----------
train Loss: 0.1324 Acc: 0.8115
val Loss: 0.0756 Acc: 0.8889

这里写图片描述

### PyTorch 学习笔记概述 李毅编写的《PyTorch学习笔记》是一份详尽的学习指南,旨在帮助读者掌握深度学习框架PyTorch的核心概念和技术。这份笔记不仅涵盖了基础理论知识,还提供了大量实践案例和代码实现。 #### 主要内容结构 1. **环境搭建** 安装配置PyTorch运行所需的软件环境,包括Python版本的选择、CUDA支持以及Anaconda的使用方法[^2]。 2. **张量操作** 解释了如何创建、转换和处理多维数组(即张量),这是构建神经网络模型的基础构件之一[^3]. 3. **自动求导机制** 描述了Autograd模块的工作原理及其在反向传播算法中的应用,使用户能够轻松定义复杂的计算图并高效训练模型[^4]. 4. **优化器与损失函数** 探讨了几种常用的梯度下降变体(SGD, Adam等)及相应的损失衡量标准(MSE Loss, CrossEntropyLoss等),这些组件对于调整权重参数至关重要[^5]. 5. **数据加载与预处理** 展示了Dataset类和DataLoader类的功能特性,它们可以简化大规模图像分类任务的数据读取流程;同时也介绍了常见的图片增强技术来扩充样本集规模[^6]. 6. **卷积神经网络(CNN)** 结合具体实例深入剖析CNN架构设计思路,如LeNet,VGG,resnet系列,并给出完整的项目源码供参考学习[^7]. 7. **循环神经网络(RNN/LSTM/GRU)** 阐述时间序列预测场景下RNN家族成员的特点优势,通过手写字符识别实验验证其有效性[^8]. 8. **迁移学习实战演练** 利用预训练好的大型模型作为特征提取器,在新领域内快速建立高性能的应用程序,减少重复劳动成本的同时提高了泛化能力[^9]. 9. **分布式训练入门指导** 当面对超大数据集时,单机难以满足需求,此时可借助于torch.distributed包来进行集群式的协同工作模式探索[^10]. ```python import torch from torchvision import datasets, transforms transform = transforms.Compose([transforms.ToTensor()]) train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform) train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True) for images, labels in train_loader: print(images.shape) break ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值