文章目录

  • 数据加载
  • 1、为何在模型中使用数据加载器
  • 2、数据集类
  • 2.1 Dataset基类介绍
  • 2.2 案例
  • 2.3 迭代数据集
  • 3、自带数据集
  • 3.1 torchversion.datasets
  • 4、实现手写数字识别
  • 4.1 思路和流程分析
  • 4.2 准备训练集和测试集
  • 4.3 构建模型
  • 4.4 损失函数
  • 4.5 训练模型
  • 4.6 模型保存和加载
  • 4.7 模型评估


数据加载

1、为何在模型中使用数据加载器
  • 在前面的线性回归模型中,我们使用的数据很少,所以直接把全部数据放到模型中去使用。
  • 但是在深度学习中,数据量通常是都非常多,非常大的,如此大量的数据,不可能一次性的在模型中进行向前的计算和反向传播,经常我们会对整个数据进行随机的打乱顺序,把数据处理成一个个的batch,同时还会对数据进行预处理。
2、数据集类
2.1 Dataset基类介绍

通常继承torch.until.data.Dataset实现对数据集的加载。

class Dataset(object):
    r"""An abstract class representing a :class:`Dataset`.

    All datasets that represent a map from keys to data samples should subclass
    it. All subclasses should overwrite :meth:`__getitem__`, supporting fetching a
    data sample for a given key. Subclasses could also optionally overwrite
    :meth:`__len__`, which is expected to return the size of the dataset by many
    :class:`~torch.utils.data.Sampler` implementations and the default options
    of :class:`~torch.utils.data.DataLoader`.

    .. note::
      :class:`~torch.utils.data.DataLoader` by default constructs a index
      sampler that yields integral indices.  To make it work with a map-style
      dataset with non-integral indices/keys, a custom sampler must be provided.
    """

    def __getitem__(self, index):
        raise NotImplementedError

    def __add__(self, other):
        return ConcatDataset([self, other])

    # No `def __len__(self)` default?
    # See NOTE [ Lack of Default `__len__` in Python Abstract Base Classes ]
    # in pytorch/torch/utils/data/sampler.py
2.2 案例
# -*- coding: utf-8 -*-
""" @Time : 2021/5/17 9:28
 @Author : XXX
 @Site : 
 @File : DemoGetData.py
 @Software: PyCharm 
"""
from torch.utils.data import Dataset

class MyDLoadData(Dataset):

    def __init__(self):
        self.file = open('../databases/test.txt').readlines()

    def __getitem__(self, item):

        return self.file[item]

    def __len__(self):

        return len(self.file)


if __name__ == '__main__':
    data =MyDLoadData()
    print("第一行的数据为:",data[1])
    print("该数据集的长度为:",len(data))

运行结果

pytorch加载的pth文件 pytorch 数据加载_深度学习

2.3 迭代数据集
  • 批处理数据(Batching the data)
  • 打乱数据(Shuffling the data)
  • 使用多线程mu1tiprocessing 并行加载数据。
    在pytorch中torch.until. data.DataLpader提供了上述的所用方法
# -*- coding: utf-8 -*-
""" @Time : 2021/5/17 9:28
 @Author : XXX
 @Site : 
 @File : DemoGetData.py
 @Software: PyCharm 
"""
from torch.utils.data import DataLoader, Dataset


class MyDLoadData(Dataset):

    def __init__(self):
        self.file = open('../databases/test.txt').readlines()

    # 对数据进行处理返回
    def __getitem__(self, item):

        return self.file[item]

    # 返回数据的长度
    def __len__(self):

        return len(self.file)



if __name__ == '__main__':

    my_data = MyDLoadData()
    data_load = DataLoader(dataset=my_data, batch_size=2, shuffle=True, num_workers=2)
    """
    参数:
        · dataset:提前定义的dataset的实例;
        · batch_size:传入数据的batch的大小,常用128/256;
        · shuffle:【bool】获取数据的时候是否打乱;
        · num_workers:加载数据的线程数。 
    *** 注意:数据总长度的:batch_size*len(data_load)
    """
    for i in data_load:
        print(i)
        break

pytorch加载的pth文件 pytorch 数据加载_pytorch_02

3、自带数据集
  • torchvision:提供对图片数据处理相关的API和数据。
  • 数据位置:torchvision.datasets
  • torchtext:提供了对文本数据处理相关的API和数据。
  • 数据位置:torchtext.datasets
3.1 torchversion.datasets
torchvision.datasets.MNIST(root='files', train, download, transform)
"""
参数:
	· root:参数表示数据存放的位置;
	· train:【bool】使用训练集的数据还是测试集的数据;
	· download:【bool】是否需要下载数据到root目录;
	· transform:实现的对图片的处理函数。
"""

下载

MNIST是由Yann Lecun等人提供的免费的图像识别的数据集,其中包括60000个训练样本和10000个测试样本,其中图拍了的尺寸已经进行的标准化的处理,都是黑白的图像,大小为28×28

import torchvision

dataset = torchvision.datasets.MNIST(root='../databases', download=True)

pytorch加载的pth文件 pytorch 数据加载_数据_03

4、实现手写数字识别
4.1 思路和流程分析
  • 准备数据
  • 构建模型
  • 模型训练
  • 模型评估
  • 保存模型
4.2 准备训练集和测试集

下载数据:

torchvision.datasets.MNIST(root='files', train, download, transform) 使用这个下载即可

数据处理:

ToTensor:

  • torchvision.transforms.ToTensor:把一个取值范围是[0, 255]的PIL.Image或者shape为(H,W,C)的numpy.ndarray,转换形状为[C,H,W],取值范围是[0,1,0]的torch.FloatTensor
  • 其中(H,W,C)为(高,宽,通道数),黑白图片的通道数只有1,其中每个像素点的取值为[0,255],彩色图片的通道数为(R,G,B)每个通道的每个像素点的取值为[0,255],三个通道的颜色相互叠加,形成了各种颜色。
result = transform.ToTensor()(dataset[0][0])

Normalize:

  • torchvision.transforms.Normalize(mean, std)
  • 给定均值:mean,shape和图片的通道数相同(指的是每个通道的均值),方差:std,和图片的通道数(指的是每个通道的方差),将会把Tensor规范化处理。=>Normalized_image = (image-mean)/std

Compose(transforms)

  • 使用列表的存储方式,将多个transform组合起来。
4.3 构建模型
  • 激活函数:torch.nn.functional
  • 原始输入数据的形状:[batch_size, 1,28, 28]
  • 进行形状的修改:[batch_size, 28*28](全连接层是在进行矩阵的乘法操作);
  • 第一个全连接层的输出形状:[batch_size, 28]
  • 激活函数不会修改数据的形状;
  • 第二个全连接层的输出形状:[batch_size, 10] 10个类别。
4.4 损失函数

对于二分类,我们使用sigmoid计算对数似然损失,来定义二分类的损失。

  • 在二分类中我们有正类和负类,正类的概率为:,而父类的概率:1-P(x);
  • 将这个结果进行计算对数似然损失就可以到的最终的损失。
而对于多分类,我们使用softmax函数,与sigmoid的区别在于我们需要去计算样本属于每个类别的概率,需要计算多次,而sigmoid只需计算一次。

pytorch加载的pth文件 pytorch 数据加载_深度学习_04

pytorch加载的pth文件 pytorch 数据加载_神经网络_05

例如:输入2.3,2.4,5.6后的结果为:

pytorch加载的pth文件 pytorch 数据加载_pytorch_06

在经过前面的计算后,还需要进行对数似然损失的计算得到交叉熵损失。

pytorch加载的pth文件 pytorch 数据加载_pytorch_07

实现损失的俩种方法

# 第一种
criterion = nn.CrossEntropyLoss()
loss = criterion(input, targtet)

# 第二种
# 对输出值计算softmax和取对数
output = F.log_softmax(x, dim=-1)
# 使用带权损失
loss = F.nll_loss(output, target)

带权损失定义:ln = -Σwi*xi,log§作为xi,真实值Y作为权重。

4.5 训练模型
  • 实例化模型
  • 实例化优化器,实例化损失函数
  • 获取,遍历dataloder
  • 梯度置为0
  • 进行向前计算
  • 计算损失
  • 反向传播
  • 更新参数
4.6 模型保存和加载

模型保存

torch.save(mnist_net.state_dict(), 保存路径)torch.save(optimizer.state_dict(),保存路径)

模型加载

mnist_net.load_state_dict(torch.load(保存路径))optimizer.load_state_dict(torch.load(保存路径))

4.7 模型评估
  • 不需要计算梯度
  • 需要收集损失准确率,用来计算平均损失平均准确率
  • 损失的计算和训练时候损失的计算方法相同;
  • 准确率的计算:
  • 模型的输出为[batch_size,10]的形状;
  • 其中最大值的位置就是其预测的目标值(预测值进行过sotfmax后为概率,sotfmax中分母都是相同的,分子越大,概率越大);
  • 最大值的位置获取的方法可以使用torch.max ,返回最大值和最大值的位置;
  • 返回最大值的位置后,和真实值( [batch_size])进行对比,相同表示预测成功。