PyTorch深度学习实践学习笔记

 传送门:B站 刘二大人1. Overview_哔哩哔哩_bilibili

 第一节 Overview

表示学习presentation learning(高维空间需要的数据量成倍增长,费钱,所以可以把高维变成低维,但是要保证数据的特征基本不变)

Manifold 流形

深度学习,端到端的学习方法

SVM的局限性

神经网络

感知机

反向传播(Back Propagation):核心是计算图(求偏导、前馈、链式法则)

第二节 线性模型

步骤:1.准备数据集 2.模型的设计 3.训练 4.推理

监督学习

过拟合、泛化,把训练集用作训练和开发(提前测试一下)

权重,先随机取一个权重,结果与真实值比较,需要一个数值来评估误差(loss损失函数)

每一个权重对应一个数值,可以用穷举法求出loss最小的权重值(视频中有代码)

MSZ(平均平方误差)

深度学习重视可视化(Visdom),比如可以看见过拟合过程。

作业是穷举法画出y=ax+b(a,b为权重)的损失图(平面上的图)

第三节 梯度下降算法

分治法也可以求出使loss最小的权重值,寻找目标函数最小值即为优化问题(损失函数就是有画面目标)

学习率,贪心算法(可以得到局部最优解,不一定全局最优),非凸函数存在局部最优点。好在深度学习网络没有太多的局部最优点,但是有鞍点(平了)没法继续迭代了。

梯度下降,因为可以继承前一次的计算结果,因此时间复杂度底,但性能底。(视频中有代码)

随机梯度下降,时间复杂度高,性能高。取一个样本,有可能由于噪声跨过鞍点。(视频中有代码)

综合用Batch:取小批量样本做一次梯度下降。

第四章 反向传播

两层的神经网络,会合并,所以加入偏置

前馈求出loss,反馈算出梯度

pytorch中如何进行反向传播

各种维度的数值保存在Tensor中,Tensor中的Data保存权重值,Grad保存loss对于权重w的导数值。

import torch
 
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
 
w = torch.Tensor([1.0])  # 相当于npl.arry 选择一个权重,创建一个Tensor变量,值为1.0
w.requires_grad = True   # 需要计算梯度 (默认不计算梯度)
 
def forward(x):
    return x*w    # w是tensor类型的,x会自动类型转换为tensor
 
def loss(x,y):     # 每调用一次loss,就是在动态构建一次计算图
    y_pred = forward(x)
    return (y_pred-y)**2
 
print('predict before training',4,forward(4).item())    # predict before training 4 4.0
 
# 训练过程(随机梯度下降)
for epoch in range(100):
    for x,y in zip(x_data,y_data):
        l=loss(x,y)   # 前馈只需计算loss
        l.backward()  # 每进行一次反向传播,梯度存到w里,计算图即被释放
        print('\tgrad:',x,y,w.grad.item())
        w.data -= 0.01*w.grad.data#只做纯数值的修改,不用求梯度,所以用data取数值,不建立计算图,建图直接用张量
        w.grad.data.zero_()  # 把权重里的梯度数据清零
    print("progress:",epoch,l.item()) #会得到每次循环的损失值
 
print('predict after training',4,forward(4).item())   # predict after training 4 7.999998569488525

第五章 用PyTorch实现线性回归

基本步骤包括:数据集准备、模型定义并实例化、损失函数和优化器、模型训练测试(前馈反馈更新)

损失要变成标量才能反向传播,

import torch
 
# step1 准备数据集
x_data = torch.Tensor([[1.0],[2.0],[3.0]]) #x,y必须为矩阵
y_data = torch.Tensor([[2.0],[4.0],[6.0]])
 
# step2 设计模型
class LinearModel(torch.nn.Module):   # LinearModel继承nn.Module这个父类,自动实现反向传播,所以无需定义。若无法自动计算反向传播,可从forward继承,则需要定义反向传播。
    def __init__(self):   # 构造函数(初始化对象时默认调用)
        super(LinearModel,self).__init__()  # super调用父类的构造,这步一定要有
        self.linear = torch.nn.Linear(1,1)  # nn.Linear类,也继承在Module父类,构造对象,包含权重w和偏置b两个tensor,自动计算y=  wx+b
    def forward(self,x):   # 前馈时要执行的计算
        y_pred = self.linear(x)    #计算y=  wx+b
        return y_pred
 
model = LinearModel()  # 实例化
 
# step3  损失函数和优化器
criterion = torch.nn.MSELoss(size_average=False)  # nn.MSELoss继承自nn.Module
optimizer = torch.optim.SGD(model.parameters(),lr=0.01)   #第一个部分。提取权重;第二个部分,学习率
 
# step4 训练循环
for epoch in range(1000):
    y_pred = model(x_data)   # 前馈:预测,算y_pred
    loss = criterion(y_pred,y_data)   # 前馈:损失,算loss
    print(epoch,loss)   # loss自动调用__str__(),不会产生计算图
    
    optimizer.zero_grad()   # 梯度归零
    loss.backward()   # 反向传播
    optimizer.step()  # 更新
 
# 输出权重和偏置
print('w=',model.linear.weight.item()) #.item不打印矩阵,只打印数值
print('b=',model.linear.bias.item())
 
# 测试模型
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred=',y_test.data)

不同的优化器 

 第六章 逻辑斯蒂回归

对于回归问题,输出值连续,对于分类问题,输出值分散。

解决分类问题:分类问题中输出的是属于每一个分类的概率。

分类任务常用数据集,可用torchvision下载训练集。

import torchvision
train_set = torchvision.datasets.MNIST(root='../dataset/mnist',train=True,download=True)
test_set = torchvision.datasets.MNIST(root='../dataset/mnist',train=False,download=True)

Sigmoid函数 满足3个条件:(1)函数值有极限(2)单调增(3)饱合函数

其中最出名的是 logistic 函数

import torch
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt
 
# 准备数据集
x_data = torch.Tensor([[1.0],[2.0],[3.0]])
y_data = torch.Tensor([[0],[0],[1]])
 
# 设计模型(从nn.Module继承)
class LogisticRegressionModel(torch.nn.Module):
    def __init__(self):
        super(LogisticRegressionModel,self).__init__()
        self.linear=torch.nn.Linear(1,1)
    def forward(self,x):
        y_pred=F.sigmoid(self.linear(x))
        return y_pred
model = LogisticRegressionModel()
 
# 构造损失函数BCE(二分类交叉熵)用于二分类问题和优化器(使用Pytorch API)
criterion = torch.nn.BCELoss(size_average=False)
optimizer = torch.optim.SGD(model.parameters(),lr=0.01)
 
# 训练周期:前馈、反馈、更新
for epoch in range(1000):
    y_pred = model(x_data)
    loss = criterion(y_pred,y_data)
    print(epoch,loss.item())
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
 
# 测试
x = np.linspace(0,10,200)  # 0-10h采样200个点
x_t = torch.Tensor(x).view((200,1))  # 变为200行1列的矩阵,类似于numpy里的reshape
y_t = model(x_t)
y = y_t.data.numpy()  # 拿到数组
plt.plot(x,y)
plt.plot([0,10],[0.5,0.5],c='r')
plt.xlabel('Hours')
plt.ylabel('Probability of Pass')
plt.grid()  # 网格
plt.show()

 第七章 处理多维特征的输入

 映射不一定是线性的,用多个线性变换层,通过找到最优的权重,把它们组合起来,模拟非线性变换。神经网络的本质是寻找非线性空间的变换函数 。

 激活函数:给线性变换增加非线性因子,从而拟合非线性变换。

人工神经网络
# 准备数据集
import torch
import numpy as np
xy = np.loadtxt('diabetes.csv.gz',delimiter=',',dtype=np.float32)  # 用numpy的函数loadtxt读取数据集内容,delimiter为分隔符,神经网络计算用32位浮点数
# torch.from_numpy()创建Tensor
x_data = torch.from_numpy(xy[:,:-1])  # 所有行,第1列开始,最后1列不要
y_data = torch.from_numpy(xy[:,[-1]])  # -1外面加[]是为了保证拿出来是一个矩阵,不加的话拿出来是一个向量
 
# 定义模型(输入8维—>线性层1—>6维—>线性层2—>4维—>线性层3—>输出1维)
class Model(torch.nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        self.linear1 = torch.nn.Linear(8,6)
        self.linear2 = torch.nn.Linear(6,4)
        self.linear3 = torch.nn.Linear(4,1)
        self.sigmoid = torch.nn.Sigmoid()  # 给模型添加一个非线性变换,继承自Module;另一种写法:torch.nn.Functional.Sigmoid()
    def forward(self,x):
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        x = self.sigmoid(self.linear3(x))
        return x
model = Model()
 
# 构建损失和优化器
criterion = torch.nn.BCELoss(size_average=True)  # loss取平均值变小了,学习率最好调大一点
optimizer = torch.optim.SGD(model.parameters(),lr=0.1)
 
# 训练周期(训练时尚未使用Mini-Batch)
for epoch in range(100):
    # 前馈
    y_pred = model(x_data)
    loss = criterion(y_pred,y_data)
    print(epoch,loss.item())
    
    # 反馈
    optimizer.zero_grad()
    loss.backward()
    
    # 更新
    optimizer.step()

 可以变换激活函数,

如将激活函数换成 ReLU 时的代码:

import torch
class Model(torch.nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        self.linear = torch.nn.Linear(8,6)  
        self.linear = torch.nn.Linear(6,4)
        self.linear = torch.nn.Linear(4,1)
        self.activate = torch.nn.ReLU()
    def forward(self,x):
        x = self.activate(self.linear1(x))
        x = self.activate(self.linear2(x))
        x = self.activate(self.linear3(x))
        return x
model = Model()

第八章 加载数据集

Epoch:所有训练样本经历了一次前向传播和反向传播的过程(嵌套循环)

Batch-Size:每次训练时用的样本数量

Iteration:Batch分了多少个迭代次数

import torch
from torch.utils.data import Dataset  # Dataset是一个抽象类,不能实例化,只能被其他子类继承
from torch.utils.data import DataLoader  # DataLoader类(加载器)可以实例,加载数据(shuffle和batch_size自动完成)
 
class DiabetesDataset(Dataset):   # DiabetesDataset是自己定义的类,继承自Dataset类
    def __init__(self):
        pass
    def __getitem__(self,index):   # 实例化对象后支持下标操作,通过索引拿出数据
        pass
    def __len__(self):   # 返回数据集里的数据条数,即整个数据的数量
        pass
 
dataset = DiabetesDataset()  # 实例化为数据对象

train_loader = DataLoader(dataset=dataset,batch_size=32,shuffle=True,num_workers=2)
# DataLoader加载器初始化时至少传4个量,num_workers:读数据、构成Mini-Batch时是否多线程(并行化),并行化可提高读取的效率
import numpy as np
import torch
from torch.utils.data import Dataset,DataLoader
 
# 1、准备数据(不再是加载全部数据)
class DiabetesDataset(Dataset):
    def __init__(self,filepath):
        xy = np.loadtxt(filepath,delimiter=',',dtype=np.float32)
        self.len = xy.shape[0]   # xy为N行9列(N行:数据样本个数;9列:8个特征列,1个目标列)
        self.x_data = torch.from_numpy(xy[:,:-1])   # 前8列
        self.y_data = torch.from_numpy(xy[:,[-1]])  # 最后1列
    def __getitem__(self,index):
        return self.x_data[index],self.y_data[index]   # 返回的是一个元组
    def __len__(self):
        return self.len
 
dataset = DiabetesDataset('diabetes.csv.gz')#路径
train_loader = DataLoader(dataset=dataset,batch_size=32,shuffle=True,num_workers=0)#加载器
 
# 2、设计模型
class Model(torch.nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        self.linear1 = torch.nn.Linear(8,6)
        self.linear2 = torch.nn.Linear(6,4)
        self.linear3 = torch.nn.Linear(4,1)
        self.sigmoid = torch.nn.Sigmoid()
    def forward(self,x):
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        x = self.sigmoid(self.linear3(x))
        return x
model = Model()
 
# 3、构建损失和优化器
criterion = torch.nn.BCELoss(size_average=True)
optimizer = torch.optim.SGD(model.parameters(),lr=0.01)
 
# 4、训练周期(变为了嵌套循环,以便使用Mini-Batch)
# 嵌套循环
for epoch in range(100):
    # enumerate()获得当前是第几次迭代
    for i,data in enumerate(train_loader,0):   # data为元组(x,y)
        # 1. 准备数据
        inputs,labels = data #也可以把上一行写成for i(inputs,labels) in enumerate(train_loader,0),主要目的是把x,y解构出来
        # 2. 前馈
        y_pred = model(inputs)
        loss = criterion(y_pred,labels)
        print(epoch,i,loss.item())
        # 3. 反馈
        optimizer.zero_grad()
        loss.backward()
        # 4. 更新
        optimizer.step()
import torch
from torch.utils.data import DataLoader
from torchvision import transforms   # PIL Image —> Tensor
from torchvision import datasets
 
train_dataset = datasets.MNIST(root='../dataset/mnist',train=True,transform=transform.ToTensor(),download=True)
test_dataset = datasets.MNIST(root='../dataset/mnist',train=False,transform=transform.ToTensor(),download=True)
 
train_loader = DataLoader(dataset=train_dataset,batch_size=32,shuffle=True)
test_loader = DataLoader(dataset=test_dataset,batch_size=32,shuffle=False)   # 测试数据一般不需要shuffle
 
for epoch in range(100):
    for batch_idx,(inputs,target) in enumerate(train_loader):
        ...

第九章 多分类问题

 十分类问题有几种解决思路。

以下代码中模型设计、训练、测试有具体思路和语法解释。

# 0.导包
import torch
from torchvision import transforms   # 对图像进行原始处理的工具
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F   # 为了使用函数 relu()
import torch.optim as optim   # 为了构建优化器
 
# 1.准备数据
batch_size = 64
transform = transforms.Compose([transforms.ToTensor(),   # PIL Image 转换为 Pytorch里的张量(图像有通道,把0~225变成0~1)Tensor
                                transforms.Normalize((0.1307, ),(0.3081, ))])  # 归一化到0-1分布,其中mean均值=0.1307,std标准差=0.3081
  
train_dataset = datasets.MNIST(root='../dataset/mnist',train=True,download=True,transform=transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)
 
test_dataset = datasets.MNIST(root='../dataset/mnist',train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)
 
# 2.设计模型
class Net(torch.nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        # 线性层
        self.l1 = torch.nn.Linear(784,512)
        self.l2 = torch.nn.Linear(512,256)
        self.l3 = torch.nn.Linear(256,128)
        self.l4 = torch.nn.Linear(128,64)
        self.l5 = torch.nn.Linear(64,10)
 
    def forward(self,x):
        x = x.view(-1,784)
        x = F.relu(self.l1(x))
        x = F.relu(self.l2(x))
        x = F.relu(self.l3(x))
        x = F.relu(self.l4(x))
        return self.l5(x)  # 最后一层不做激活,直接接到softmax
        
model = Net()
 
# 3.构建损失和优化器
criterion = torch.nn.CrossEntropyLoss() #交叉熵损失
optimizer = optim.SGD(model.parameters(),lr=0.01,momentum=0.5) #带冲量的
 
# 4.训练
def train(epoch):   # 把一轮循环封装到函数里
    running_loss = 0
    for batch_idx, data in enumerate(train_loader,0):
        inputs,target=data
        optimizer.zero_grad() #优化器在优化前要清零
        
        # 前馈 反馈 更新
        outputs = model(inputs)
        loss = criterion(outputs,target)
        loss.backward()
        optimizer.step()
        
        running_loss += loss.item()
        if batch_idx % 300 == 299:  # 每300批量输出一次
            print('[%d,%5d]loss: %.3f' % (epoch+1,batch_idx+1,running_loss/300))
            running_loss = 0
 
# 5.测试
def test():
    correct = 0
    total = 0
    with torch.no_grad(): #下面一段代码不再计算梯度
        for data in test_loader:
            images,labels = data
            outputs = model(images)
            _,predicted = torch.max(outputs.data,dim=1)  # 求每一行里max的下标,对应着分类,其中dim=1为行,dim=0为列
            total += labels.size(0)  # (N,1),取N
            correct += (predicted==labels).sum().item()
    print('Accuracy on test set: %d %%' %(100*correct/total))
 
if __name__ == '__main__':
    for epoch in range(10):
        train(epoch) 
        test()   # 训练一轮,测试一轮
        # 若想每训练10轮测试1次,可在test()前面加一行 if epoch % 10 == 9: 

  • 28
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 《PyTorch深度学习实践》是由牟大恩编写的一本介绍PyTorch深度学习实践指南。这本书主要分为两部分,第一部分介绍了PyTorch的基本概念和使用方法,包括PyTorch的基本原理、张量运算、自动求导、数据集、数据加载等;第二部分涵盖了构建深度学习网络的高级主题,包括卷积神经网络、循环神经网络、生成对抗网络、迁移学习等。 《PyTorch深度学习实践》的优点在于其内容深入浅出,对于初学者也很友好。书中提供了很多实例和代码,可以帮助读者更好地理解和掌握PyTorch的使用。此外,这本书还介绍了一些实际应用案例,可以让读者了解深度学习在不同领域的应用。 如果您正在学习PyTorch深度学习,或者正在进行深度学习相关研究,那么《PyTorch深度学习实践》是一本很有价值的参考书籍。无论您是初学者还是有经验的研究人员,都可以从这本书中获得一些实用的知识和灵感。如果您对这本书感兴趣,可以在各大图书网站上下载或购买。 ### 回答2: PyTorch是近年来非常受欢迎的深度学习框架之一。而《PyTorch深度学习实践》这本书则是由牟大恩所写,是一本介绍PyTorch框架及其应用的指南。 本书主要分为三个部分:第一部分介绍了Python基础、NumPy、Tensor和PyTorch基础,这对于初学者非常重要;第二部分是深度学习PyTorch的应用,包括图像分类、预训练模型、目标检测和分割等内容;第三部分则涉及更高级的深度学习技术,如生成对抗网络、自然语言处理和强化学习。 此外,本书还提供了大量的实例代码和Jupyter笔记本,供读者练习和实践。这些案例覆盖了诸如文本分类、时间序列分析、语音识别等不同领域。 总之,如果你想学习深度学习PyTorch框架,特别是如果你已经具有Python编程经验,那《PyTorch深度学习实践》是一本非常实用的图书。它可以帮助你深入了解该框架,学习如何构建和训练深度神经网络,并通过实践掌握更高级的深度学习技巧。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值