pytorch 入门笔记

1.数据加载

自定义dataset

import os
import os.path as osp

from torch.utils.data import Dataset


class DogCatDataset(Dataset):

    def __init__(self, root_path, is_train):
        self.is_train = is_train
        self.train_set_path = osp.join(root_path, 'train_set')
        self.test_set_path = osp.join(root_path, 'test_set')
        self.train_data = os.listdir(self.train_set_path)
        self.test_data = os.listdir(self.test_set_path)

    def __len__(self):
        return len(self.train_data) if self.is_train else len(self.test_data)

    def __getitem__(self, idx):
        if self.is_train:
            return osp.join(self.train_set_path, self.train_data[idx])
        else:
            return osp.join(self.test_set_path, self.test_data[idx])

这种方式无法实现batch、shuffle数据或通过多线程读取,所以还可以通过DataLoader定义迭代器

from torch.utils.data import DataLoader

dataset = DogCatDataset('../data', is_train=True)
dataiter = DataLoader(dataset, batch_size=32, shuffle=True)

对于图片数据可以使用torchversion.dataset下的ImageFolder

from torchvision.datasets import ImageFolder
# transform 和 target_transform 用于数据增强
ImageFolder(root='../data/train_set',transform=None, target_transform=None)

2. nn 模组  Module(网络)

pytorch中定义计算图,层结构和损失函数均来着torch.nn模组

from abc import ABC

from torch.nn import Module
from torch.nn import Conv2d
from torch.nn import CrossEntropyLoss


class TestNet(Module, ABC):
    def __init__(self):
        super(TestNet, self).__init__()
        self.conv1 = Conv2d(in_channels=3, out_channels=8, kernel_size=3)
        self.criterion = CrossEntropyLoss()

    def forward(self, x):
        x = self.conv1(x)
        return x

    def build_loss(self, output, target):
        loss = self.criterion(output, target)
        return loss

3. 一个完整的LinearRegression示例

from abc import ABC

import numpy as np
from torch.autograd import Variable
from torch.nn import Module
from torch.nn import Linear
import torch
from torch.nn import MSELoss
import torch.optim as optim
import matplotlib.pyplot as plt


class LinearRegression(Module, ABC):
    def __init__(self):
        super(LinearRegression, self).__init__()
        self.linear = Linear(1, 1)  # input output is 1 dim

    def forward(self, x):
        out = self.linear(x)
        return out


x_train = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168],
                    [9.779], [6.182], [7.59], [2.167], [7.042],
                    [10.791], [5.313], [7.997], [3.1]], dtype=np.float32)

y_train = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573],
                    [3.366], [2.596], [2.53], [1.221], [2.827],
                    [3.465], [1.65], [2.904], [1.3]], dtype=np.float32)

x_train = torch.Tensor(x_train)
y_train = torch.Tensor(y_train)

if torch.cuda.is_available():
    model = LinearRegression().cuda()
else:
    model = LinearRegression()

criterion = MSELoss()
optimizer = optim.SGD(model.parameters(), lr=1e-3)

num_epochs = 1000

for epoch in range(num_epochs):
    if torch.cuda.is_available():
        inputs = Variable(x_train).cuda()
        targets = Variable(y_train).cuda()
    else:
        inputs = Variable(x_train)
        targets = Variable(y_train)

    # forward
    out = model(inputs)
    loss = criterion(out, targets)

    # backward
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if (epoch + 1) % 20 == 0:
        print('Epoch[{}/{}], loss:{:6f}'.format(epoch + 1, num_epochs, loss.data.item()))

# evaluation
# 将模型转变为测试模式 因为有些层 Dropout BN 等 训练和预测时的操作不同
model.eval()
predict = model(Variable(x_train))
predict = predict.data.numpy()
plt.plot(x_train.numpy(), y_train.numpy(), 'ro', label='original data')
plt.plot(x_train.numpy(), predict, label='fitting line')
plt.show()

注意:在模型预测前,需要将模型转换为eval模型

4. 一个简化的 VGG 示例

import sys
from abc import ABC

from torch.utils.data import DataLoader

sys.path.append('..')

import numpy as np
import torch
from torch import nn
from torchvision.datasets import CIFAR10
from torch.nn import Module
from torch.nn import Sequential, Conv2d, MaxPool2d, ReLU, Linear
from d_cnn.utils import train


class VggLite(Module, ABC):

    def __init__(self):
        super(VggLite, self).__init__()
        self.feature = Sequential(
            Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            ReLU(True),
            MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1)),

            Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            ReLU(True),
            MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1)),

            Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            ReLU(True),
            Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            ReLU(True),
            MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1)),

            Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            ReLU(True),
            Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            ReLU(True),
            MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1)),

            Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            ReLU(True),
            Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            ReLU(True),
            MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1))
        )

        self.classifier = Sequential(
            Linear(512, 100),
            ReLU(True),
            Linear(100, 10)
        )

    def forward(self, x):
        x = self.feature(x)
        x = x.view(x.shape[0], -1)
        x = self.classifier(x)
        return x


def data_tf(x):
    x = np.array(x, dtype='float32') / 255
    x = (x - 0.5) / 0.5  # 标准化,这个技巧之后会讲到
    x = x.transpose((2, 0, 1))  # 将 channel 放到第一维,只是 pytorch 要求的输入方式
    x = torch.from_numpy(x)
    return x


train_set = CIFAR10('../data', train=True, transform=data_tf, download=True)
train_data = DataLoader(train_set, batch_size=64, shuffle=True)
test_set = CIFAR10('../data', train=False, transform=data_tf, download=True)
test_data = DataLoader(test_set, batch_size=128, shuffle=False)

net = VggLite()
optimizer = torch.optim.SGD(net.parameters(), lr=1e-1)
criterion = nn.CrossEntropyLoss()

train(net, train_data, test_data, 20, optimizer, criterion)

5. 学习率衰减

# 定义一个优化器 单组参数
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, weight_decay=1e-4)
# 多组参数
optim.SGD([{'params': model.base.parameters()},
           {'params': model.classifier.parameters(), 'lr': 1e-3}], 
            lr=1e-2, momentum=0.9)
# 打印优化器的参数
print('learning rate: {}'.format(optimizer.param_groups[0]['lr']))
print('weight decay: {}'.format(optimizer.param_groups[0]['weight_decay']))
learning rate: 0.01
weight decay: 0.0001

所以可以在循环过程中指定优化器的 lr 值来衰减学习率

# 单组参数时 直接更改
optimizer.param_groups[0]['lr'] = 1e-5
# 多组参数时 使用循环更改
for param_group in optimizer.param_groups:
    param_group['lr'] = 1e-5

6. 正则化

L2正则化

# 通过添加 weight_decay 设置L2正则
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, weight_decay=1e-4) 

7.数据增强

from PIL import Image
from torchvision import transforms as tfs

’‘’
常用的数据增强方法如下:
1.对图片进行一定比例缩放
2.对图片进行随机位置的截取
3.对图片进行随机的水平和竖直翻转
4.对图片进行随机角度的旋转
5.对图片进行亮度、对比度和颜色的随机变化
‘’‘
im = Image.open('./cat.png')

# 随机比例缩放
new_im = tfs.Resize((100, 200))(im)

# 随机裁剪
random_im1 = tfs.RandomCrop(100)(im) # 100 x 100
random_im2 = tfs.RandomCrop((150, 100))(im) # 100 x 100
center_im = tfs.CenterCrop(100)(im) # 中心 100 x 100
# 随机尺寸裁剪后 ,缩放到定义大小 150 x 150
random_im3 = tfs.RandomSizedCrop(150)(im)

# 随机翻转
h_filp = tfs.RandomHorizontalFlip()(im) # 随机水平翻转
v_flip = tfs.RandomVerticalFlip()(im)   # 随机竖直翻转

# 随机角度旋转
rot_im = tfs.RandomRotation(45)(im)

# 亮度、对比度和颜色的变化
# 亮度
bright_im = tfs.ColorJitter(brightness=1)(im) # 随机从 0 ~ 2 之间亮度变化,1 表示原图
# 对比度
contrast_im = tfs.ColorJitter(contrast=1)(im) # 随机从 0 ~ 2 之间对比度变化,1 表示原图
# 颜色
color_im = tfs.ColorJitter(hue=0.5)(im) # 随机从 -0.5 ~ 0.5 之间对颜色变化

# 使用 torchvision.transforms.Compose() 组合变换
im_aug = tfs.Compose([
    tfs.Resize(120),
    tfs.RandomHorizontalFlip(),
    tfs.RandomCrop(96),
    tfs.ColorJitter(brightness=0.5, contrast=0.5, hue=0.5)
])

im_aug(im)

8.数据标准化

 

### 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 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值