Pytorch笔记

1.构建tensor类型的矩阵

#1 创建一个空的矩阵
x = torch.empty(5,3)
#2 创建一个全零的矩阵
x = torch.zeros(5,3.dtype =torch.long)
#3 创建一个随机值矩阵
x = torch.rand(5,3)
#4 显示tensor矩阵的大小
x.size()

2.基本计算方法

#1 矩阵加法(类型一)
y = torch.rand(5,3)
x + y   
#2 矩阵加法(类型二)
torch.add(x,y)

3.view函数

view函数可以改变矩阵的维度
x = torch.rand(4,4) #创建4行4列的矩阵
y = x.view(16) #将x矩阵改变为1行16列的矩阵
z = x.view(-1,8) #将x矩阵改变为2行8列的矩阵(在这种情况下,你可以严格限制矩阵的列数,而行数等于-1,则是根据矩阵的大小,自己去改变。)

4.Tensor与Numpy相互转化

#1 tensor格式转化成numpy格式
a = torch.ones(5)
b = a.numpy() #将tensor类型的a转换成numpy类型的b
#2 numpy格式转化成tensor格式
a = np.ones(5)
b = torch.from_numpy(a) #将numpy类型的a转化成tensor类型的b

5.反向传播—自动求导

#1 自动求导方法一
x = torch.randn(3,4,requires_grad = True)
#2 自动求导方法二
x = torch.randn(3,4)
x.requires_grad = True
#3 反向传播---自动求导实例
import torch
b = torch.randn(3,4,requires_grad = True)
t = x + b
y = t.sum()
y.backkward()
print(b.grad)
#输出:tensor([1.,1.,1.,1.],
              [1.,1.,1.,1.],
              [1.,1.,1.,1.])

注:pytorch求梯度,反向传播过程中,如果计算一次梯度不清零,下次求梯度则会累加之前的梯度,所以在做反向传播过程中,求完梯度,要清零,反向更新,在进行下一次反向传播。
6.线性回归实例—反向求梯度

  • 首先要构造一组输入数据x和其对应的标签值y
#准备数据
import torch
import torch.nn as nn
x_values = [ i for i in range(11)]
x_train = np.array(x_values,dtype = np.float32)
x_train = x_train.reshap(-1,1) #x_train是np.array数据类型,所以改变数组的维度直接使用reshape就可以

y_values = [2*i + 1 for i in x_values]
y_train = np.array(y_values,dtype = np.float32)
y_train = y_train.reshape(-1,1)

class LinearRegressionModel(nn.Module):
	def __init__(self,input_dim,output_dim):
		super(LinearRegressionModel,self).__init__()
		self.linear = nn.Linear(input_dim,output_dim)
	def forward(self,x):
		out = self.linear(x)
		return out
input_dim = 1
output_dim = 1
model = LinearRegressionModel(input_dim,output_dim)
#指定好参数和损失函数
epochs = 100
learning_rate = 0.01
optimizer = torch.optim.SGD(model.paramaters().lr=learning_rate)
criterion = nn.MSELoss()
#训练模型
for epoch in range(epochs):
	#准备数据
	inputs = torch.from_numpy(x_train)
	labels = torch.from_numpy(y_train)
	#梯度清零
	optimizer.zero_grad()
	#前向传播
	outputs = model(inputs)
	#计算损失
	loss = criterion(outputs,labels)
	#反向传播
	loss.backward()
	#更新权重参数
	optimizer.step()
	#输出损失值
	if epoch % 20 == 0:
		print('epoch{},loss{}'.format(epoch,loss.item())
#测试模型结果
predicted = model(torch.from_numpy(x_train),requires_grad_()).data.numpy()
#模型的保存与读取
torch.save(model.state_dict(),'model.pkl')  #保存模型参数
model.load_state_dict(torch.load('model.pkl'))  #读取模型参数
#使用GPU训练模型
#-------------------------------------
#只需要把数据和模型传入到cuda里面就可以了
#-------------------------------------
import torch
import torch.nn as nn
import numpy as np 
class LinearRegressionModel(nn.Model):
	def __init__(self,input_dim,output_dim):
		super(LinearRegressionModel,self).__init__()
		self.linear = nn.Linear(input_dim,output_dim)
	def forward(self,x):
		out = self.linear(x)
		return out
input_dim = 1
output_dim = 1
model = LinearRegressionModel(input_dim,output_dim)
#把模型加载进入GPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
criterion = nn.MSELoss()
learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(),lr = learning_rate)
epochs = 100
for epoch in range(epochs):
#将数据加载进入GPU
	inputs = torch.from_numpy(x_train).to(device)
	labels = torch.from_numpy(y_train).to(device)
	optimizer.zero_grad()
	outputs = model(inputs)
	loss = criterion(outputs,labels)
	loss.backward()
	optimizer.step()
	if epoch % 20 == 0:
		print('epoch{},loss{}'.format(epoch,loss.item()))

7.Tensor常见的形式有哪些

  • 0: scalar
  • 1: vector
  • 2: matrix
  • 3: n-dimensional tensor
    Scalar 通常是一个数值
x = tensor(42.)
#输出为:tensor(42.)
x.dim()
#输出为:0
x.item()
#输出为:42.0

Vector在深度学习中通常指特征,例如向量

v = tensor([1.5,-0.5,3.0])
#输出为:tensor([1.5000,-0.5000,3.000])
v.dim()
#输出为:1
v.size()
#输出为:torch.Size([3])

Matrix一般计算的都是矩阵,通常都是多维度

m = tensor([[1.,2.],[3.,4.]])
#输出为:tensor([[1.,2.],
               [3.,4.]])

8.构建卷积神经网络

#1 导包
#————————————————————————————————————————————————————
#1 导包
#————————————————————————————————————————————————————
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import matplotlib.pyplot as plt
import numpy as np
from torchvision import datasets,transforms
#—————————————————————————————————————————————————————
#2 读取数据
#-----分别构建训练集和测试机
#-----DataLoader来迭代取数据
#—————————————————————————————————————————————————————
#定义需要用到的超参数
input_size = 28  #图像的尺寸为28*28
num_class = 10   #标签的种类数
num_epochs = 3   #训练的总循环周期
batch_size = 64  #批处理图片的数量
#构建训练集
train_dataset = datasets.MNIST(root='./data',
                               train=True,
                               transform=transforms.ToTensor(),
                               download=True)
#构建测试集
test_dataset = datasets.MNIST(root='./data',
                              train=False,
                              transform=transforms.ToTensor())
#构建batch数据
train_loader = torch.utils.data.DataLoader(dataset = train_dataset,
                                           batch_size = batch_size,
                                           shuffle = True)
test_loader = torch.utils.data.DataLoader(dataset = test_dataset,
                                          batch_size = batch_size,
                                          shuffle = True)
#————————————————————————————————————————————————————————————————————————
#3 卷积网络模块构建
#————————————————————————————————————————————————————————————————————————
class CNN(nn.Module):
    def __init__(self):
        super(CNN,self).__init__()
        self.conv1 = nn.Sequential(          #第一个卷积:输入大小(1,28,28)
            nn.Conv2d(
                in_channels=1,               #输入的通道数(1为灰度图)
                out_channels=16,             #输出的通道数
                kernel_size=5,               #卷积核大小
                stride=1,                    #步长
                padding=2,                   #填充
                                             #输出的特张图大小为(16*28*28)
            ),
            nn.ReLU(),                       #激活函数
            nn.MaxPool2d(kernel_size=2),     #最大池化,输出结果为(16*14*14)
        )
        self.conv2 = nn.Sequential(          #第二个卷积:输入为(16*14*14)
            nn.Conv2d(16,32,5,1,2),          #输出为(32*14*14)
            nn.ReLU(),                       #激活函数
            nn.MaxPool2d(2),                 #池化层,输出结果为(32*7*7)
        )
        self.out = nn.Linear(32*7*7,10)      #全连接层得到结果
    def forward(self,x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0),-1)
        output = self.out(x)
        return output
#——————————————————————————————————————————————————————————————————————————————————————
#4  准确率作为评估标准
#——————————————————————————————————————————————————————————————————————————————————————
def accuracy(predictions,labels):
    pred = torch.max(predictions.data,1)[1]
    rights = pred.eq(labels.data.view_as(pred)).sum()
    return rights,len(labels)
#——————————————————————————————————————————————————————————————————————————————————————
#5 训练网络模型
#——————————————————————————————————————————————————————————————————————————————————————
#实例化3步骤的网络模型
net = CNN()
#损失函数
criterion = nn.CrossEntropyLoss()
#优化器
optimizer = optim.Adam(net.parameters(),lr=0.001)
#训练模型
for epoch in range(num_epochs):
    #当前epoch的结果保存下来
    train_rights = []
    for batch_idx,(data,target) in enumerate(train_loader):
        net.train()
        output = net(data)
        loss = criterion(output,target)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        right = accuracy(output,target)
        train_rights.append(right)
        if batch_idx % 20 == 0:
            net.eval()
            val_rights = []
            for (data,target) in test_loader:
                output = net(data)
                right = accuracy(output,target)
                val_rights.append(right)
            #计算准确率
            train_r = (sum([tup[0] for tup in train_rights]),sum([tup[1] for tup in train_rights]))
            val_r = (sum([tup[0] for tup in val_rights]),sum([tup[1] for tup in val_rights]))
            print('当前epoch:{} [{}/{}({:.0f}%)]\t损失:{:.6f}\t训练集准确率:{:.2f}%\t测试集准确率:{:.2f}%'.format(
                epoch,batch_idx*batch_size,len(train_loader.dataset),
                100. * batch_idx / len(train_loader),
                loss.data,
                100. * train_r[0].numpy() / train_r[1],
                100. * val_r[0].numpy() / val_r[1]))

9.基于经典网络架构训练图像分类模型

数据预处理部分
  • 数据增强:torchvision中transforms模块自带功能,比较实用
  • 数据预处理:torchvision中transforms直接调用即可
  • DataLoader模块直接读取batch数据
网络模块设置
  • 加载预训练模型,torchvision中有很多经典网络架构,调用起来十分方便,并且可以用比尔训练好的模型在此基础上训练,也就是所谓的迁移学习
  • 需要注意的是,根据自己的任务,修改模型的参数,比如:类别数,所用到的模块选择等等
  • 可以选择从零开始训练,可以设置模型的断点续训,在中断训练时,在下一次训练的时候,可以重新接着上一次训练的数据训练模型
网络模型保存与测试
  • 模型保存的时候可以设置保存最佳精度的模型,具有选择性
  • 读取保存的模型参数进行测试

你可能感兴趣的:(笔记,pytorch,python,深度学习)