目录
前言:
这里以一个手写数字识别的例子,简单了解一下pytorch 实现神经网络的过程.
本章重点讲一下加载数据过程
参考:
一 概述
整体流程如下,分为四步

二 加载图片
如下为加载minist 数据集过程
- # -*- coding: utf-8 -*-
- """
- Created on Thu Nov 24 17:17:19 2022
- @author: chengxf2
- """
- import torchvision
-
- from matplotlib import pyplot as plt
- import torch
- import torchvision.transforms as transforms
- import torchvision.datasets
- from util import plot_curve,plot_image
-
-
-
-
-
-
- '''
- root : 需要下载地址的根目录位置
- train: True 下载训练集trainin.pt False 下载test.pt
- transform: 一系列作用在PIL 图片上的转换操作,返回一个转换版本
- dowenload: 是否下载到root 指定的位置
- transforms.Compose():
- 将多个预处理依次累加在一起, 每次执行transform都会依次执行其中包含的多个预处理程序
- transforms.ToTensor():
- 在做数据归一化之前必须要把PIL Image转成Tensor
- transforms.Normalize([0.5], [0.5]):
- 归一化,这里的两个0.5分别表示对张量进行归一化的 全局平均值和方差,
- 因为图像是灰色的只有一个通道,所以分别指定一了一个值,如果有多个通道,
- 需要有多个数字,如3个通道,就应该是Normalize([m1, m2, m3], [n1, n2, n3])
- '''
- def load_data(batch =512):
- transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize([0.1307], [0.3018])])
- train_dataset = torchvision.datasets.MNIST('mnist_data', train=True, transform=transform, download=True)
- test_dataset = torchvision.datasets.MNIST('mnist_data/', train=False, transform=transform, download=False)
-
- train_loader = torch.utils.data.DataLoader(train_dataset, batch_size = batch, shuffle=True)
- test_loader = torch.utils.data.DataLoader(test_dataset)
- print("\n --end--",type(train_loader))
- return train_loader, test_loader
-
- def show(data):
-
- #递归所有的元素
- for step, (x,y) in enumerate(data):
- print("\n step ",step,y.shape) #512
-
- ###单独取一个###
- x,y = next(iter(train_loader))
- print(x.shape, y.shape)
- print(x.min(), x.max(),type(x)) #Tensor
- plot_image(x,y,'image sample')
- if __name__ =="__main__":
- train_loader , test_loader = load_data()
- show(train_loader)
三 绘图部分
-
- # -*- coding: utf-8 -*-
- """
- Created on Mon Nov 21 17:16:16 2022
- @author: chengxf2
- """
- import torch
-
- from matplotlib import pyplot as plt
-
- def plot_curve(data):
-
- #画训练过程的loss
- fig = plt.figure()
- N= len(data)
-
- plt.plot(range(N),data, color='green')
- plt.legend(['value'], loc='up right')
- plt.xlabel('step')
- plt.ylabel('value')
-
- plt.show()
-
-
- def plot_image(img, label, name):
- #画图片
- fig = plt.figure()
-
- for i in range(6):
-
- plt.subplot(2,3,i+1) #t(nrows ncols plot_number)
- plt.tight_layout() #会自动调整子图参数,使之填充整个图像区域
- plt.imshow(img[i][0]*0.3081+0.1307,interpolation ='none')
- plt.title("{}:{}".format(name, label[i].item()))
- plt.xticks([])
- plt.yticks([])
- plt.show()
-
-
- '''
- 生成one-hot
- Tensor.scatter_(dim, index, src, reduce=None) → Tensor
- Parameters
- scatter_(dim, index, src): 将src中所有的值分散到self 中,填法是按照index中所指示的索引来填入。
- dim (int) – the axis along which to index
- dim=0,按照index行索引的指示来进行散射
- dim=1 ,按照index列索引的指示来进行散射
- index (LongTensor) – the indices of elements to scatter, can be either empty or of the same dimensionality as src. When empty, the operation returns self unchanged.
- src (Tensor or float) – the source element(s) to scatter. 要填进去的元素
- reduce (str, optional) – reduction operation to apply, can be either 'add' or 'multiply'. 用的相对较少。
- '''
- def one_hot(label, depth=10):
-
- N = label.size(0)
-
- print("\n n:",N)
-
- out = torch.zeros(N, depth)
- idx = torch.LongTensor(label).view(-1,1)
- out.scatter_(dim=1, index=idx, value=1)
- print("\n out ",out)
- return out
-
- #label =[1,2,5]
- #label = torch.LongTensor(label)
- #one_hot(label)
-
-
四 Pytorch 中的backward
Numpy ,pytorch 可以自己实现反向传播算法,也可以使用pytorch给的API,通过动态图自动
求导
这里面给出3个例子3.1
3.1 简单的LR 模型



梯度:

- Created on Tue Nov 22 14:58:50 2022
-
- @author: chengxf2
- """
- import torch
- from torch.autograd import Variable
- '''
- 自动求梯度例子1
- '''
- def grad():
-
- x = torch.tensor([2.0,1.0],requires_grad=True)
- w = torch.tensor([1.0,2.0],requires_grad=True)
-
- y = torch.matmul(w, x.T)
- L = (y-1.0)**2/2.0
-
- print("\n L ",L)
- L.backward()
- print(w.grad)
-
- grad()
bias tensor(3., grad_fn=
tensor([6., 3.])