PyTorch入门与实战必备基础知识(上)01
前言
在PyTorch快速入门中我们大概知道了一个神经网络模型的构成模块以及如何从数据处理到模型训练。但是没有具体去了解每部分的细节,本章节我们来学习一些PyTorch必备的知识,为后续学习奠定基础。
深度学习能够超过传统的机器学习算法离不开神经网络,然而神经网络最基本的数据结构就是张量,神经网络的输入是张量,然后通过每个张量进行线性变换,再经过激活函数的非线性变换,通过层层计算最终使得损失函数的最小化,完成模型的训练。所以要想学好深度学习,对基础的数据结构还是要非常了解。目录:回顾一下相关的线性代数的基础知识向量、矩阵和张量Pytorch如何表示向量、矩阵和张量的计算Pytorch中张量的一些基本操作向量、矩阵和张量及其运算
1、向量
向量 (1维数组)定义为一行 或者一列数 ,分别称之为行向量 和列向量 ,如图1和图2所示(这里用T代表转置,意思是行列互换)。向量是最基本的一种数据排列方式,组成向量的每个数称为向量的分量,这里用 来表示,其中的n代表向量分量的数目 ,即向量的大小。
图1 行向量
图2 列向量
向量与向量之间一个重要的运算是点积(Dot Product),或者称之为内积(Inner Product),表现为两个相同大小的向量 按分量相乘并且求和.。如图3所示
图3 两个向量的内积
内积的几何解释 :两个向量的内积等于向量的模长乘以向量之间夹角的余弦,如图4所示。
图4
我们把向量与自身内积的平方根称之为向量的长度(或模,即L2-norm)。
在神经网络中 ,向量往往不是某事物的特征。例如,房子的价格是受多种因素(是否为学区房、附近有无地铁、房子面积、房间数量、楼层等)来影响,那么我们将这多种因素来表示为房子的特征,这一组特征值就可以用向量表示。
2、矩阵
矩阵由一组向量组成的集合。矩阵也称为2维数组。
图 矩阵的定义和矩阵运算的例子
在神经网络中, 在刚才的例子中,一套房子的特征可以用一个向量来表示。那么我们要建m套房子的数据集,那么就是m个向量的组合,也即是得到一个m行n列的矩阵。(n为一套房子的向量的长度)。
3、张量
张量是矩阵的推广,可以用来描述N维数据。其实在计算机领域内,大家叫法都不那么严格,一个矩阵,你可以叫它矩阵,也可以叫它二阶张量,也可以叫它二维数组。
向量、矩阵和三维向量示意图
在神经网络中 ,张量在图像领域用的是很普遍的。如一张彩色图像,有宽度和高度,同时又有R,G,B三个通道。所以一张彩色图像就是三阶张量(通道 * 宽度 *高度)。
再比如高一阶的四阶张量,可以理解为一个批次(批次简单理解为多张图片)的彩色图像。因为在做图像识别过程中,我们训练和推理过程中可以一次推理N张图像,这个N称为批次。即是 批次 * 通道 * 宽度 *高度 的四阶张量。在深度学习中,我们要处理不止一张图片或一篇文档——我们要处理一个集合。我们可能有10,000张郁金香的图片,这意味着,我们将用到4 阶张量
4、向量、矩阵和张量比较
几何代数中定义的张量是基于向量和矩阵的推广,比如我们可以将标量视为零阶张量,矢量可以视为一阶张量,矩阵就是二阶张量。
张量维度
代表含义
0维张量
代表的是标量(数字)
1维张量
代表的是向量
2维张量
代表的是矩阵
3维张量
时间序列数据 股价 文本数据 单张彩色图片( RGB )
1. 标量,也称 Scalar,是一个只有大小,没有方向的量,比如 1.8、e、10 等。
2. 向量,也称 Vector,是一个有大小也有方向的量,比如 (1,2,3,4) 等。
3. 矩阵,也称 Matrix,是多个向量合并在一起得到的量,比如[(1,2,3),(4,5,6)]等。
不难发现,几种数据表示其实都是有着联系的,标量可以组合成向量,向量可以组合成矩 阵。那么,我们可否将它们看作是一种数据形式呢?
答案是可以的,这种统一的数据形式,在 PyTorch 中我们称之为张量 (Tensor)。从标 量、向量和矩阵的关系来看,大致可以认为它们就是不同"维度"的 Tensor。
张量是深度学习的基础。它的核心是一个数据容器,多数情况下,它包含数字,有时候它也包含字符串,但这种情况比较少。 Pytorch如何表示向量、矩阵和张量的计算
1、向量: 一个向量表示一组有序排列的数,通过次序中的索引我们能够找到每个单独的数,向量 通常用粗体的小写字母表示 ,如x。 import numpy as np #行向量 a = np.array([1,2,3,4])
2、矩阵: 是一个二维数组,其中的每一个元素由两个索引来决定( ),矩阵通常用加粗斜体的大写字母表示,如X。 import numpy as np #矩阵 a = np.array([[1,2,3],[4,5,6],[7,8,9]])
3、张量:
张量是一种特殊的数据结构,与数组和矩阵非常相似。在 PyTorch 中,我们使用张量对模型的输入和输出以及模型的参数进行编码。
张量类似于NumPy 的ndarray,除了张量可以在 GPU 或其他硬件加速器上运行。事实上,张量和 NumPy 数组通常可以共享相同的底层内存,从而无需复制数据(请参阅Bridge with NumPy)。张量也针对自动微分进行了优化(我们将在稍后的Autograd 部分中看到更多相关内容)。如果您熟悉 ndarrays,那么您对 Tensor API 会很熟悉。如果没有,请跟随!import·torch import·numpy·as·np
3.1 初始化张量
张量可以以各种方式初始化。请看以下示例:
直接创建张量
首先来看直接创建的方法,这也是最简单创建的方法。我们可以通过torch.tensor()直接使用数据,构造一个张量。数据类型是自动推断的。data = [[1, 2],[3, 4]] x_data = torch.tensor(data) x_datatensor([[1, 2], [3, 4]])
NumPy 数组创建张量
在实际应用中,我们在处理数据 的阶段多使用的是 NumPy,而数据处理好之后想要传入 PyTorch 的深度学习模型中,则 需要借助 Tensor,所以 PyTorch 提供了一个从 NumPy 转到 Tensor 的语句。并且可以从 NumPy 数组创建,反之亦然 。np_array = np.array(data) x_np = torch.from_numpy(np_array) x_nptensor([[1, 2], [3, 4]])
随机初始化张量
我们可以通过 torch.rand()的方法,构造一个随机初始化的矩阵(2阶张量): import torch x = torch.rand(6, 4) print(x)
注意: torch.rand 用于生成数据类型为浮点型且维度指定的随机 Tensor,随机生成的浮点数据在 0~1 区间均匀分布。 torch.randn 用于生成数据类型为浮点型且维度指定的随机 Tensor,随机生成的浮点数的取值满足均值为 0、方差为 1 的标准正态分布。 torch.normal 用于生成数据类型为浮点型且维度指定的随机 Tensor,可以指定均值和标准差。 torch.randint 用于生成随机整数的 Tensor,其内部填充的是在[low,high) 均匀生成的随机整数。
全0矩阵的构建
我们可以通过 torch.zeros()构造一个矩阵全为 0,并且通过 dtype设置数据类型为 long。 import torch x = torch.zeros(5 3, dtype=torch.long) print(x)
根据一个张量构建形状相同的张量:
新张量保留参数张量的属性(形状、数据类型),除非显式覆盖。x = torch.ones(2, 2, dtype=torch.double) print(x) x1 = torch.randn_like(x, dtype=torch.float) print(x1) # 结果会有一样的size # 获取它的维度信息 print(x.size()) print(x1.shape)tensor([[1, 1], [1, 1]]) tensor([[0.0809, 0.7885], [0.0739, 0.3876]])
使用随机值和定值:
shape是张量维度的元组。在下面的函数中,它决定了输出张量的维度。shape = (2,3,) rand_tensor = torch.rand(shape) ones_tensor = torch.ones(shape) zeros_tensor = torch.zeros(shape) print(f"Random Tensor: {rand_tensor} ") print(f"Ones Tensor: {ones_tensor} ") print(f"Zeros Tensor: {zeros_tensor}") Random Tensor: tensor([[0.0312, 0.8956, 0.5396], [0.0653, 0.3294, 0.7575]]) Ones Tensor: tensor([[1., 1., 1.], [1., 1., 1.]]) Zeros Tensor: tensor([[0., 0., 0.], [0., 0., 0.]])
Tensor 的转换
在实际项目中,我们接触到的数据类型有很多,比如 Int、list、NumPy 等。为了让数据在 各个阶段畅通无阻,不同数据类型与 Tensor 之间的转换就非常重要了。接下来我们一起来看看 int、list、NumPy 是如何与 Tensor 互相转换的。
Int 与 Tensor 的转换:a = torch.Tensor(1) b = a.item()
我们通过 torch.Tensor 将一个数字(或者标量)转换为 Tensor,又通过 item() 函数,将 Tensor 转换为数字(标量),item() 函数的作用就是将 Tensor 转换为一个 python number。
list 与 tensor 的转换:a = [1, 2, 3] b = torch.Tensor(a) c = b.numpy().tolist()
在这里对于一个 list a,我们仍旧直接使用 torch.Tensor,就可以将其转换为 Tensor 了。 而还原回来的过程要多一步,需要我们先将 Tensor 转为 NumPy 结构,之后再使用 tolist() 函数得到 list。
张量到 NumPy 数组
背后原理:CPU 中张量和 NumPy 数组上的张量可以共享它们的底层内存位置,改变一个会改变另一个。t = torch.ones(5) print(f"t: {t}") n = t.numpy() print(f"n: {n}")t: tensor([1., 1., 1., 1., 1.]) n: [1. 1. 1. 1. 1.]
张量的变化反映在 NumPy 数组中。t.add_(1) print(f"t: {t}") print(f"n: {n}") t: tensor([2., 2., 2., 2., 2.]) n: [2. 2. 2. 2. 2.]
NumPy 数组到张量n = np.ones(5) t = torch.from_numpy(n) print(n) print(t)[1. 1. 1. 1. 1.] tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
NumPy 数组的变化反映在张量中。np.add(n, 1, out=n) print(f"t: {t}") print(f"n: {n}") t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64) n: [2. 2. 2. 2. 2.]
常见的构造张量(Tensor)的方法总结
函数
功能
Tensor(sizes)
基础构造函数
tensor(data)
类似于np.array
ones(sizes)
全1
zeros(sizes)
全0
eye(sizes)
对角为1,其余为0
arange(s,e,step)
从s到e,步长为step
linspace(s,e,steps)
从s到e,均匀分成step份
rand/randn(sizes)
rand是[0,1)均匀分布;randn是服从N(0,1)的正态分布
normal(mean,std)
正态分布(均值为mean,标准差是std)
randperm(m)
随机排列
3.2 张量的属性
张量属性描述了它们的形状、数据类型和存储它们的设备tensor = torch.rand(3,4) # Get cpu or gpu device for training. device = "cuda" if torch.cuda.is_available() else "cpu" print(f"Using {device} device") print(f"Shape of tensor: {tensor.shape}") print(f"Datatype of tensor: {tensor.dtype}") print(f"Device tensor is stored on: {tensor.device}") Using cuda device Shape of tensor: torch.Size([3, 4]) Datatype of tensor: torch.float32 Device tensor is stored on: cpu
3.3 张量运算
在PyTorch中有超过 100 种张量运算,包括算术、线性代数、矩阵操作(转置、索引、切片)、采样等。
这些操作中的每一个都可以在 GPU 上运行(通常以比 CPU 更高的速度)。如果您使用的是 Colab,请转到运行时 > 更改运行时类型 > GPU 来分配 GPU。
默认情况下,张量是在 CPU 上创建的。我们需要使用 .to方法明确地将张量移动到 GPU(在检查 GPU 可用性之后)。请记住,跨设备复制大张量在时间和内存方面可能会很昂贵!
标准的类似 numpy 的索引和切片:tensor = torch.ones(4, 4) print(f"First row: {tensor[0]}") print(f"First column: {tensor[:, 0]}") print(f"Last column: {tensor[..., -1]}") tensor[:,1] = 0 print(tensor) First row: tensor([1., 1., 1., 1.]) First column: tensor([1., 1., 1., 1.]) Last column: tensor([1., 1., 1., 1.]) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]])
拼接张量
您可以用来torch.cat沿给定维度连接一系列张量t1 = torch.cat([tensor, tensor, tensor], dim=1) print(t1) tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]]) t2 = torch.cat([tensor, tensor, tensor], dim=0) print(t2) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) t2 = torch.stack([tensor, tensor, tensor], dim=2) print(t2.shape)torch.Size([4, 4, 3])
算术运算:加法、减法、乘法加法操作: import torch # 方式1 x = torch.rand(4, 3) y = torch.rand(4, 3) print(x + y) # 方式2 print(torch.add(x, y)) # 方式3 in-place,原值修改 y.add_(x) print(y)
2.减法操作import torch x = torch.rand(4, 3) y = torch.rand(4, 3) print(x - y)
3.乘法操作# 相同位置的元素之间相乘.,计算出来的张量形状不变。如z1, z2, z3 将是相同值。 tensor = torch.ones(4, 4) z1 = tensor * tensor print(z1) z2 = tensor.mul(tensor) print(z2) z3 = torch.rand_like(tensor) print(z2) torch.mul(tensor, tensor, out=z3) print(z3)tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) 小结
1、认识了向量、矩阵和张量之间的区别和联系
2、向量、矩阵和张量在PyTorch如何实现
3、张量的基本操作,如算术运行、Numpy转Tensor等
思考题
谈谈 torch.Tensor() 和 torch.tensor() 两种函数区别??
女儿说以后不结婚,不生孩子,如果是你能接受吗?当年不肯嫁春风,无端却被秋风误。如花美眷是男人的梦想,似水流年是女人的劫遇。每个女孩子心里都藏着一个梦。有一天,她的样子带着水晶鞋,骑着白马来娶她。到那时,三生石上注良缘,恩爱夫妻
恒大爆雷,还有多少房地产企业面临困境?恒大爆出的一系列问题,真实反映了了中国房地产企业目前的处境。现在的房地产企业普遍都在爆雷,作为房地产企业的员工,我来分享一下我们公司目前面临的困境。我从事房地产十多年,先后在大房企
为什么现在教师退休金比较高,企业职工就比较低呢?教师退休金比企业职工退休金适当高一点,这是对教育者地位的认可,但是高的离谱就失去了公平。退休金高也没所谓,关键的是现在的教育还真没有八十年代我们读高中时期老师们尽心尽责!当年考大学
单位规定,休病假必须先休年假,有没有违背劳动法?正常情况下,职工的年休假和病假是两条线,互不干扰。休了年休假,并不影响请病假,请病假也不影响正常休年休假。只不过,职工带薪年休假条例中,明确规定,请病假超过一定时间,是不能再享受带
把文字转语音,哪个软件好用?感谢邀请回答,其实软件还是比较多的。第一款讯飞科技第二款配音阁第三款百度的文字转语音工具第四款一些自动的小工具。以上就是我的个人经验。希望我的回答可以帮助到你。个人推荐文字转语音工
退休中人有企业经历和没有企业经历的人员中人补发养老金差距大吗?过去的时候机关事业单位,退休人员是按照工龄计算退休费的。退休费计算主要按照连续工龄确定本人退休费的计发比例,再加上退休当地本人的退休生活补贴数额。过去的时候,连续工龄指的是职工最后
东莞确诊夫妻是因为到西安考驾照,东莞的驾照那么难考吗?我和你说个真事儿啊!我家大姨子嫁到南边了,广东省考驾照是不是最难的我不知道,反正比我们河北省难吧!其实说难可能也不太准确,一个地方一个规则,最起码河北有夜考但是没有高速考试,我听我
在辽阳月薪四千够用吗?在我们辽阳市月薪4000元左右的话,如果不背负分期买房子的房贷的压力话,可以生活的应该还是可以凑合的。辽阳的物价还是很便宜的,不像沈阳那般昂贵。如果是一个土生土长的辽阳人,那就免去
n95口罩多久换一次,一天一个成本好高,怎么换比较合适?我以下所说的都是基于目前口罩属于战备紧缺物资,第一是贵第二是少的前提下,只能节衣缩食出此下策,也算是非常时期非常办法。什么是N95口罩?简单来说,N95有两层意思,N是不耐油(no
具备什么条件你才会考虑生二胎或三胎?没什么条件,只要你不懒,勤劳,和四五六十年代一样,生十个,八个都没问题。至少经济上不会太紧张吧,另外得有人帮忙带孩子,比如父母或者有条件请到称心的保姆家庭居住条件和经济条件允许就可
你吃过哪些不经常吃的水果?谢谢!由于南北方气温相差较大,种出的水果等就有所不同,南方长出的荔枝龙眼等在北方就很少而北方长出的苹果梨等在南方也就很少。现在虽然交通方便,但靠运输的都比较昂贵,这些东西只有在本地