首页 > 其他分享 >机器学习:pytorch框架(2)--核心概念理解

机器学习:pytorch框架(2)--核心概念理解

时间:2024-11-22 15:18:01浏览次数:3  
标签:None Tensor 框架 -- requires torch 张量 pytorch grad

学习记录总结目录:

  1. 机器学习:pytorch框架(1)环境安装

1 前言

在安装基本的环境之后,下面就直接进入正式的pytorch学习中了:

首先需要了解的是:PyTorch的基本概念(如Tensor和Variable)​、自动微分等PyTorch的核心模块。

2 pytorch的基本概念

同样的,pytorch框架在开发过程中也构建了相应的一些基本概念,包括张量(pytorch中用Tensor表示)。而张量就是多维数组,并且提供了CPU设备和GPU设备的支持。如果机器上有GPU设备,就可以在Tensor上调用cuda方法,将Tensor数据加载到GPU设备中运行,提升运行速度。

  • Tensor可以和NumPy进行无缝转换,在Tensor上可以使用numpy方法将Tensor转换为NumPy中的ndarray对象;ndarray对象也可以通过Torch提供的form_numpy方法转换成Tensor对象。
  • 创建张量需要借助Torch提供的Tensor方法或from_numpy方法,理论上可以创建任意维度的多维数组,但最常用的Tensor不超过五维。

2.1 深入理解什么是张量?

张量是一个多维数据,是标量、向量、矩阵的高维拓展,类似于numpy中的ndarray对象,如下图所示:

  1. 【零维标量】PyTorch中将只包含一个元素的变量称为标量,只有大小没有方向,如温度、质量、湿度等;
  2. 【一维向量】PyTorch中用Array数组表示向量,既有大小又有方向的量为一维向量;
  3. 【二维矩阵】它的特点是多行、多列。矩阵是科学计算中最常见的数据结构。
  4. 【三维立方体】将多个二维矩阵叠加在一起就可以形成三维立方体。三维Tensor常用于表示一张图片数据[width,height,channel]​
  5. 【四维多立方体】四维Tensor常见于批量的图片数据,如下图所示:相册就是多张图片的叠加,最常见的形式为[batch,width,height,channel]​。
  6. 【五维表示多个四维Tensor的叠加】五维Tensor常见于视频数据,视频按帧数划分,如50fps(帧/秒)​,如果一个视频的时长为1 min,每个单位时间有50张图片,共有60个这样的单位时间,frames=60,那么其表现形式为[frames,batch,width,height,channel]​。

如何更加直观的理解相应的概念呢?这里引入一个生活中的例子——相册

这种多维数据表示的好处是非常适合矩阵的并行计算的,并且现在的计算机都是多核多处理器的,计算一批数据和计算一个数据的调度时间是差不多的,因此通常会指定一个适合的Batch。

2.2 Tensor与Variable

(1)Variable(了解)

其是torch.autograd中的数据类型(在0.4.0版本之后,已经并入Tensor)。主要用于封装Tensor,并进行自动求导。

data:被包装的Tensor
grad:data的梯度
grad_fn:创建Tensor的Function,是自动求导的关键
requires_grad:指示是否需要梯度
id_leaf:指示是否是叶子结点(张量)

(2)Tensor(torch.Tensor)

dtype:张量的数据类型,如torch.FloatTensor,torch.cuda.FloatTensor,主要分了9种数据类型,共3大三类(浮点型--float16/32/64,整型--uint8,int8/16/32/64,,布尔型--bool),其中float32(例如在卷积层的权值,或图像预处理后默认),long(int64,例如图像标签用长整型表示--计算交叉熵损失函数)用的最多。
shape:张量的形状,如(3,4,5,3)
device:张量所在设备:CPU/GPU,是加速的关键,只有张量在GPU上,才可以采用GPU加速运算。

在一个Tensor上可以使用shape方法获取该张量的维度及每个维度的Size。

3 张量的创建

3.1 直接创建(torch.tensor/torch.Tensor/torch.from_numpy)

(1)torch.tensor/torch.Tensor

# 定义创建
torch.tensor(
    data, # 数据,可以是list,numpy
    dtype=None, # 数据类型,默认与data一致
    device=None, # 所在设备,cuda/CPU
    requies_grad=False, # 是否需要梯度
    pin_memory=False # 是否存于锁页内存,与转化效率有关,通常设置为False
)

# 示例
import numpy as np
import torch
arr = np.ones((3,3))
# 当使用 torch.Tensor 创建张量时,默认的数据类型是 torch.get_default_dtype(),通常为 torch.float32。这意味着即使你的NumPy数组是整数类型,使用 torch.Tensor 创建的张量也会被转换成浮点类型。
t = torch.Tensor(arr)
# 会尝试保持原数据的类型。如果你的NumPy数组是整数类型,那么使用 torch.tensor 创建的张量也将是整数类型的。
t = torch.tensor(arr)

# *使用 torch.Tensor 创建的张量不会与原始的NumPy数组共享内存。对NumPy数组的修改不会反映到张量上,反之亦然。


# 创建时放到GPU上
t = torch.tensor(arr)
print(t) # 打印结果上会显示:device='cuda:0',其中0表示GPU编号

(2)torch.from_numpy

** 从torch.from_numpy创建的tensor与原ndarray是共享内存的,当修改其中一个数据,另外一个也会被改动。

arr = np.array([[1,2,3],[4,5,6]])
t.torch.from_numpy(arr)

# 修改某一个值,则同时会被修改
arr[0,0] = 6
t[0,0] = -1

3.2 依据数值创建(torch.zeros/torch.zeros_like/torch.ones/torch.ones_like/torch.full/torch.full_like/torch.arange/torch.linspace/torch.logspace/torch.eye)

创建全0/1/自定义数值的张量,或者等差数列,均分数列,对数均分数列等等

(1)torch.zeros/torch.zeros_like

# 定义依据size创建全0张量
torch.zeros(
    *size, # 张量的形状,如(3,3),(3,4,5,6)
    out=None, # 输出的张量
    dtype=None, 
    layout=torch.strided, # 内存中布局形式,有strided(默认),sparse_coo(稀疏,提高读取效率)等
    device=None,
    requires_grad=False
)


# 示例
out_t = torch.tensor([1])
t = torch.zeros((3,3),out=out_t)
print(t,out_t,id(t),id(out_t)) # 输出的两个张量都是3×3的全0张量,且内存地址是一样的。

# 定义
torch.zeros_like(
    input, # 创建与input同形状的全0张量
    dtype=None,
    layout=None,
    device=None,
    requires_grad=False
)

(2)torch.ones/torch.ones_like

# 定义创建全1张量
torch.ones(
    *size, # 张量的形状,如(3,3),(3,4,5,6)
    out=None, # 输出的张量
    dtype=None, 
    layout=torch.strided, # 内存中布局形式,有strided(默认),sparse_coo(稀疏,提高读取效率)等
    device=None,
    requires_grad=False
)

# 定义创建全1张量
torch.ones_like(
    input, # 创建与input同形状的全1张量
    dtype=None,
    layout=None,
    device=None,
    requires_grad=False
)

(3)torch.full/torch.full_like

# 自定义数值
torch.full(
    size, # 张量的形状,如(3,3),(3,4,5,6)
    fill_value, # 填充的张量的值
    out=None, # 输出的张量
    dtype=None, 
    layout=torch.strided, # 内存中布局形式,有strided(默认),sparse_coo(稀疏,提高读取效率)等
    device=None,
    requires_grad=False
)

# 示例--创建全为10的张量
t = torch.full((3,3),10)
print(t)

(4)torch.arange

# 定义创建等差的1维张量,数值区间为[start,end)--左闭右开
torch.arange(
    start, # 数列起始值
    end, # 数列“结束值”
    step=1, # 数列公差,默认为1
    out=None,
    dtype=None, 
    layout=torch.strided,
    device=None,
    requires_grad=False
)

# 示例--创建公差为2的1维张量
t = torch.arange(2,10,2)
print(t)
# 输出结果:tensor([2,4,6,8])

(5)torch.linspace

# 定义创建均分的1维张量,数值区间为[start,end]--闭区间
torch.linspace(
    start, # 数列起始值
    end, # 数列结束值
    steps=100, # 数列长度
    out=None,
    dtype=None, 
    layout=torch.strided,
    device=None,
    requires_grad=False
)

# 示例
t = torch.linspace(2,10,5)
print(t)
# 输出结果:tensor([ 2.,  4.,  6.,  8., 10.])
t = torch.linspace(2,10,6)
print(t)
# 输出结果:tensor([ 2.0000,  3.6000,  5.2000,  6.8000,  8.4000, 10.0000]),步长是(10-2)/(6-1)=1.6。

(6)torch.logspace

# 定义创建对数均分的1维张量,数值区间为[start,end]--闭区间
torch.linspace(
    start, # 数列起始值
    end, # 数列结束值
    steps=100, # 数列长度
    base=10.0 # 对数函数的底,默认为10
    out=None,
    dtype=None, 
    layout=torch.strided,
    device=None,
    requires_grad=False
)

(7)torch.eye

# 定义创建单位对角矩阵的2维张量,默认为方阵
torch.eye(
    n, # 矩阵行数,通常只用设置行数
    m=None, # 矩阵列数,默认
    out=None,
    dtype=None, 
    layout=torch.strided,
    device=None,
    requires_grad=False
)

3.3 依据概率创建(torch.normal/torch.randn/torch.randn_like/torch.randint/torch.randint_like/torch.randperm/torch.bernoulli)

(1)torch.normal(使用最多)

# 定义创建正态分布(高斯分布)的张量,一共有4种情况
torch.normal(
    mean, # 均值(标量/张量)
    std, # 标准差(标量/张量)
    out=None,
    size, # 设定维度的大小
    dtype=None, 
    layout=torch.strided,
    device=None,
    requires_grad=False
)

# 示例一:mean--张量;std--张量
mean = torch.arange(1,5,dtype=torch.float)
std = torch.arange(1,5,dtype=torch.float)
t_normal = torch.normal(mean,std)
print(mean,std,t_normal)
# 输出结果:tensor([1., 2., 3., 4.]) tensor([1., 2., 3., 4.]) tensor([1.0233, 1.8873, 2.3852, 7.0919])
# 其中:1.0233是根据均值为1,标准差为1的正态分布采样得来,其他同理

# 示例二:mean--标量;std--标量,需要设置维度的大小
mean = 0
std = 1
t_normal = torch.normal(mean,std,size=(4,))
print(mean,std,t_normal)
# 输出结果:0 1 tensor([0.5512, 0.0760, 0.4638, 0.3257])

# 示例三:mean--张量;std--标量
mean = torch.arange(1,5,dtype=torch.float)
std = 1
t_normal = torch.normal(mean,std)
print(mean,std,t_normal)
# 输出结果:tensor([1., 2., 3., 4.]) 1 tensor([1.2008, 0.7497, 3.6345, 4.1258])

(2)torch.randn/torch.randn_like

# 定义创建标准正态分布张量,因为是标准正态分布,所以只用设置size
torch.randn(
    *size, # 张量的形状,如(3,3),(3,4,5,6)
    out=None,
    dtype=None, 
    layout=torch.strided,
    device=None,
    requires_grad=False
)

(3)torch.rand/torch.rand_like和torch.randint/torch.randint_like

# 定义创建均匀分布张量,实现在区间[0,1)上,生成均匀分布
torch.rand(
    *size, # 张量的形状,如(3,3),(3,4,5,6)
    out=None,
    dtype=None, 
    layout=torch.strided,
    device=None,
    requires_grad=False
)

# 定义创建均匀分布张量,实现在区间[low,high)上,生成整数均匀分布
torch.randint(
    low=0,
    high,
    size, # 张量的形状,如(3,3),(3,4,5,6)
    out=None,
    dtype=None, 
    layout=torch.strided,
    device=None,
    requires_grad=False
)

(4)torch.randperm和torch.bernoulli

# 定义创建从0到n-1的随机排列张量
torch.randperm(
    n, # 张量的长度,(乱序索引)
    out=None,
    dtype=torch.int64, 
    layout=torch.strided,
    device=None,
    requires_grad=False
)

# 定义创建以input为概率,生成伯努利分布(0-1分布,两点分布)
torch.bernoulli(
    input, # 概率值
    *,
    generator=None,
    out=None
)

4 自动微分

神经网络计算优化的过程大体上可以分为前向传播计算损失和反向传播更新梯度。如果没有自动微分的支持,就需要手动计算偏导数,然后更新权重参数。而PyTorch基于Aten构建的自动微分系统能为我们完成这一切,因为梯度的计算对于调用者来说是透明的,这大大降低了手写梯度函数带来的高门槛。

Tensor中有requires_grad属性,代表是否需要计算梯度,这个属性的默认值为False。可以通过requires_grad参数显式地指定Tensor需要计算梯度。

如果计算拓扑中的输入有一个Tensor是需要计算梯度的,则依赖该Tensor所计算出来的Tensor也是需要计算梯度的。如果所有的输入都不需要计算梯度,则使用输入计算出的Tensor也不需要计算梯度。

requires_grad属性在迁移学习中进行模型微调的时候特别有用,因为在迁移学习中我们需要冻结学习好的参数,而对于需要微调的参数则指定requires_grad为True,使其在迭代过程中更新和学习。
例如,使用ResNet18预训练模型进行迁移学习,通过模型上的parameters方法获取所有计算拓扑中的Parameter对象,设置requires_grad属性为False,这样在训练时这些参数就会被冻结,不会在反向传播过程中更新。我们只需要修改最后的FC(Full Connection)​,使其适合自己的业务需求。

5 核心模块简介

PyTorch将系统的实现抽象为不同的模块,最核心的模块是Tensor,它是整个动态图的基础,自动微分及反向传播都需要借助该模块。

Torch为创建Tensor提供了多种方法,如torch.randn、torch.randint等。Tensor上实现了大量的方法,如sum、argmin、argmax等。Tensor也是torch.nn模块构建网络的核心,网络构建好之后通过网络的parameters方法可以获取网络的所有参数,并且可以通过遍历这些参数对象改变requires_grad属性来达到冻结参数的目的,这在迁移学习中特别有用。

torch.nn模块通过functional子模块提供了大量方法,如conv、ReLU、pooling、softmax等。这些方法在网络的forward中调用,结果输出值由torch.nn.xxxLoss损失函数计算损失。torch.nn模块中提供了很多可选的损失函数,如MSELoss、CrossEntropyLoss等,将损失传递给优化模块,优化模块提供了大量的优化器,常见的有SGD、Adam等。优化器会根据损失计算并更新梯度,达到优化的目的,最终将更新parameters。

除了这些核心模块,PyTorch还提供了JIT模块,在运行时动态编译代码;multiprocessing并行处理模块实现数据的并行处理;torch.utils.data模块提供数据的加载接口等。


***个人学习过程总结,持续记录ing

标签:None,Tensor,框架,--,requires,torch,张量,pytorch,grad
From: https://blog.csdn.net/SpiderB/article/details/143974710

相关文章

  • 最后提醒一下大模型面试肚子里没墨水的人
    浅浅罗列了些最近秋招被问到的好问题(个人感觉),受限于知识面浅薄,有些问题当时直接干晕了(红温了属于是),但问题是不错的,所以抛砖引玉,看看有没有大佬给出更好的回答呢,如果能帮上大家就更好啦。Triton(openai版)今年确实挺火的,肉眼可见zhihu上多了很多相关的优秀博客,互联网大......
  • Python 初学者的学习指南:从入门到实践 ---亲身经历版本!!!
    前言Python因其简单易学、功能强大而成为初学者编程的首选语言。无论你是零基础的小白,还是想拓展技能的开发者,Python都能为你提供无限可能。本篇博客将为Python初学者提供一套学习方法和学习路线,帮助你在短时间内掌握Python编程的核心知识,并学以致用。学习方法明......
  • 基于java和微信小程序实现投票评选系统项目【项目源码+论文说明】计算机毕业设计
    基于java和微信小程序实现投票评选系统演示【内附项目源码+LW说明】摘要越来越多信息化融入到我们生活当中的同时,也在改变着我们的生活和学习方式,当然,变化最明显的除了我们普通民众之外,要数高校学生的生活方式以及校园信息化的变革。智慧是改变生活和生产的一种来源,那么智......
  • 【C++】深入理解 C++ 中的继承进阶:多继承、菱形继承及其解决方案
    个人主页:起名字真南的CSDN博客个人专栏:【数据结构初阶】......
  • Java基础知识(八)
    文章目录异常Exception和Error有什么区别?CheckedException和UncheckedException有什么区别?Throwable类常用方法有哪些?try-catch-finally如何使用?finally中的代码一定会执行吗?如何使用`try-with-resources`代替`try-catch-finally`?异常使用有哪些需要注意的......
  • Java基础知识(七)
    文章目录泛型什么是泛型?有什么作用?泛型的使用方式有哪几种?项目中哪里用到了泛型?反射何谓反射?反射的优缺点?反射的应用场景?注解何谓注解?注解的解析方法有哪几种?SPI何谓SPI?SPI和API有什么区别?SPI的优缺点?序列化和反序列化什么是序列化?什么是反序列化?如果有些字......
  • 硬件防火墙和软件防火墙的区别有哪些?
    在网络安全领域当中,防火墙是保护网络不会受到潜在威胁的第一道防线,其中最为常见的就是硬件防火墙和软件防火墙两种类型,主要的功能就是为了保护网络安全,但两者在部署和管理多种方面上还是有着显著的区别。软件防火墙就是指装在服务器平台上的软件产品,主要是通过在操作系统底层......
  • 【sql-labs]第九关,时间盲注
    我们注入参数?id=1我们再随便注入其他不存在的参数页面还是显示正常,说明我们用不到报错注入和布尔盲注,因为他根本没有返回值。我们就要用到时间注入了sleep()函数MySql的sleep()函数能够起到休眠的作用,如注入sleep(1)它的延迟高达1006m,所以我们可以通过响应差来代替......
  • 机器学习:pytorch框架(1)安装
    在整个框架的学习过程中,需要注重三个方面:①勤动手:深刻体会相应的知识;②成体系(构建相应的知识树);③多总结(理解吸收)1基本背景pyTorch是一个经过市场上无数从业者筛选的深度学习框架,提供了健全的神经网络接口,其动态网络结构及Python友好性,获得了大量深度学习从业人员的......
  • 国内外优秀的视频提取音频在线工具分享
    在数字时代,音频和视频的处理变得越来越频繁和重要。有时,我们可能只需要视频中的音频部分,而不需要视频内容。为了满足这一需求,各种视频提取音频的工具应运而生。本文将介绍一些国内外优秀的视频提取音频在线工具。国内在线工具推荐:易我人声分离易我人声分离是一款功能强大的......