Pytorch 函数 – tensor()、fill_diagnol()、append()、index_copy()
本文旨在分享一些 PyTorch 函数,这些函数将对您的深度学习和数据科学之旅有很大帮助。将使用两个编写示例和一个无法使用这些功能的示例来解释每个函数。所以让我们开始吧。
PyTorch 是一个开源机器学习库,它包含一个张量库,可以创建一个标量、一个向量、一个矩阵,或者简而言之,我们可以创建一个 n 维矩阵。它用于计算机视觉和自然语言处理,主要由 Facebook 的研究实验室开发。它是开源软件,在修改后的 BSD(Barkley 软件分发)许可下发布。
我们的四大功能:
- 火炬.张量()
- 填充对角线_()
- 追加(*大小)
- index_copy()
函数1——torch.tensor()
这个函数使我们能够创建 PyTorch 张量。张量可以是任何东西,即它可以是一个标量,它可以是一个一维矩阵,它可以是一个 n 维矩阵。
为什么我们需要张量?
每当我们想在深度学习模型中计算任何矩阵计算时,第一个也是最重要的任务是将我们的数据帧转换为 numpy 数组,然后转换为张量,或者如果我们正在处理一些图像分类问题,我们必须将这些图像转换为 PyTorch 张量.
语法和参数:
data: data that we want to convert into tensor.
dtype: data type of that data whether it is torch32, torch64 etc.
device: type of your device whether it is cpu or gpu(cuda).
requires_grad: if it is True, then gradients of that tensor will be saved in
torch.grad property.
代码:使用此函数创建向量。
Python
# vector of int datatype
t1 = torch.tensor([1, 2, 3, 7, 1])
# if one float can convert the whole tensor into flat
t2 = torch.tensor([4, 2, 5, .9])
# we can convert the tensor data type
t3 = torch.tensor([2, 6, 1, 6, 8.], dtype = torch.int32
Python3
t4 = torch.tensor([[3, 6, 8], [2, 6, 8], [0, 7, 4]])
Python3
t4 = torch.tensor([[3, 6, 8], [2, 6, 8], [0, 7, 4]])
Python3
a = torch.zeros(3, 3)
Python3
a.fill_diagonal_(fill_value = 4, wrap = False)
print(a)
Python3
b = torch.zeros([9, 4])
# without putting wrap = True
A = b.fill_diagonal_(5, wrap = False)
Python3
B = b.fill_diagonal_(6, True)
print(B)
Python3
B = b.fill_diagonal_(6, True)
print(B)
Python3
a = torch.tensor([[5], [3], [8], [4]])
a.size()
a.expand(4, 8)
Python3
b = torch.tensor([[7], [3], [4]])
b.size()
b.expand(3, -1)
Python3
c = torch.tensor([[4, 6], [9, 6]])
c.size() # this matrix didn't any singleton dimension
c.expand(2, 6)
Python3
self_tensor = torch.zeros(6, 3)
a
t = torch.tensor([[7, 6, 9], [3, 9, 1], [0, 1, 9]], dtype = torch.float)
i = torch.tensor([3, 1, 0])
self_tensor.index_copy_(0, i, t)
Python3
a = torch.tensor([[1, 8], [9, 5], [1, 5]])
b = torch.tensor([[3, 5], [9, 0], [2, 2]])
i = torch.tensor([2, 1, 0])
a.index_copy_(0, i, b)
Python3
a = torch.tensor([[8, 3], [1, 0]])
b = torch.tensor([[3, 9]])
i = torch.tensor([1])
a.index_copy(1, i, b)
在上面的示例中, t1是包含简单一维数组的张量。在, t2我们里面的火炬。张量我们使用了单个浮点元素,但由于那个单一的,我们的整个t2张量已转换为浮点类型。在t3中,我们强制设置 dtype = torch.int32 来更改张量的数据类型。
代码:使用矩阵创建张量。
Python3
t4 = torch.tensor([[3, 6, 8], [2, 6, 8], [0, 7, 4]])
在上面的例子中,我们创建了一个3*3张量的 t4 张量。类似地,如果我们想创建一个 n 维张量,我们可以创建它,例如具有 4 维或更多维的张量。
示例 3(最常见的错误):
在这个例子中,我们将讨论在创建张量期间经常尝试的错误。在示例 2 中,我们了解到可以创建 n 维数组。
代码:
Python3
t4 = torch.tensor([[3, 6, 8], [2, 6, 8], [0, 7, 4]])
在这里,我们创建了一个具有两个维度的张量,但每个维度不包含相等的 no。元素的数量,即每个维度的长度不同。因为这。编译器会抛出一个错误,说...
ValueError Traceback (most recent call last)
# Example 3?-?breaking (to illustrate when it breaks)?-?? 2 torch.tensor([[1, 2], [3, 4, 5]])
ValueError: expected sequence of length 2 at dim 1 (got 3)
所以我们学到的是,我们可以创建一个 n 维数组,但所有维度应该具有相同的长度,否则我们会得到一个错误。
函数2 – fill_diagonal_()
Fill_diagonal() 用 fill_value 填充主对角线,但该矩阵应该是 2D 矩阵,对于 ndim > 2 矩阵,行数应该等于列数,如果不是,那么我们必须设置 wrap = True 以便对角线价值可以重复。
语法和参数:
fill_diagonal_(fill_value, wrap=False) -> 张量
fill_value: tensor matrix whose diagonals we want to fill.
wrap: it takes boolean, it enables us to work with a non-square matrix.
示例 1:
在这个例子中,首先我们将使用 torch.zeros(3, 3) 创建一个大小为 (3, 3) 的张量。
Python3
a = torch.zeros(3, 3)
a 是一个大小为 (3, 3) 的张量,它的所有元素都为零,即 a 是一个零矩阵
现在我们想要的是用 .4 替换它的所有对角线值,所以我们可以在 fill_diagonal_() 的帮助下做到这一点。
Python3
a.fill_diagonal_(fill_value = 4, wrap = False)
print(a)
如果,我们看张量 a 它看起来像
tensor([[4., 0., 0.], [0., 4., 0.], [0., 0., 4.]])
示例 2:
正如我们从示例 1 中了解到的,我们可以使用此函数替换对角线元素,但是如果我们有一个张量,其中没有。行数不等于否。列,那么在这种情况下,我们必须设置 fill_diagonal_() 的“wrap”参数。
你可以看看这段代码,
Python3
b = torch.zeros([9, 4])
# without putting wrap = True
A = b.fill_diagonal_(5, wrap = False)
在上面的代码中,首先我们创建了一个大小为 (9, 4) 的零张量,然后我们用 5 填充它的对角线,但我们没有设置 wrap = True。现在让我们看看张量 A,
tensor([[5., 0., 0., 0.], [0., 5., 0., 0.], [0., 0., 5., 0.], [0., 0., 0., 5.], [0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]])
在这里您可以看到,一旦对角线到达特定尺寸长度的末端,那么对角线的其余部分就不会改变
所以要解决这个问题,我们必须将 wrap 设置为 True。看看这段代码,
Python3
B = b.fill_diagonal_(6, True)
print(B)
现在看看张量 B
tensor([[6., 0., 0., 0.], [0., 6., 0., 0.], [0., 0., 6., 0.], [0., 0., 0., 6.], [0., 0., 0., 0.], [6., 0., 0., 0.], [0., 6., 0., 0.], [0., 0., 6., 0.], [0., 0., 0., 6.]])
您会观察到,即使对角线到达特定维度的末端,它也会再次开始从下一个维度更改对角线。
示例 3(常见错误):
假设您有一个大小为零的张量(4, 5),并且您想用 .3 更改它的对角线,但是如果您想将该张量的数据类型更改为 int32,那么您可能会考虑设置一个 dype = fill_diagonal_() 中的 torch.int32 为,
B = b.fill_diagonal_(6, True)
打印(B)
Python3
B = b.fill_diagonal_(6, True)
print(B)
但是,在这里你必须记住一点,fill_diagonal_() 只接受两个参数作为参数,一个是你想要放入对角线的数据,另一个是用于处理非方形张量的包装,
所以,上面的代码会抛出一个错误,
TypeError
Traceback (most recent call last)
1 # Example 3?-?breaking (but if try to set it’s data type it throws an error)
2 a = torch.zeros(4, 5)
– ? 3 a.fill_diagonal_(.3, dtype = torch.float32) TypeError: fill_diagonal_() got an unexpected keyword argument ‘dtype’
函数3 – 展开(*size)
- 返回一个新的 self 张量视图,其中单例维度扩展为更大的尺寸。
- 传递 -1 作为维度的大小意味着不更改该维度的大小。
- Tensor 也可以扩展到更大的维度,新的维度会附加在前面。对于新维度,大小不能设置为 -1。
- 扩展张量不会分配新内存,而只会在现有张量上创建一个新视图,其中通过将步幅设置为 0,将尺寸为 1 的维度扩展为更大的尺寸。任何尺寸为 1 的尺寸都可以扩展为任意值无需分配新内存。
语法和参数:
expand(*size)
示例 1:
如果我们有一个单维矩阵,那么我们可以使用 expand() 扩展它的单维矩阵
Python3
a = torch.tensor([[5], [3], [8], [4]])
a.size()
a.expand(4, 8)
在张量 a 处寻找,
tensor([[5, 5, 5, 5, 5, 5, 5, 5],
[3, 3, 3, 3, 3, 3, 3, 3],
[8, 8, 8, 8, 8, 8, 8, 8],
[4, 4, 4, 4, 4, 4, 4, 4]])
最初,a 是一个包含单维的矩阵,现在使用 expand() 我们将它的单维扩展为 8
示例 2:
Python3
b = torch.tensor([[7], [3], [4]])
b.size()
b.expand(3, -1)
在上面的例子中,我们将第二个尺寸设置为 -1,这意味着我们不想扩大它的尺寸。
示例 3(常见错误):
Python3
c = torch.tensor([[4, 6], [9, 6]])
c.size() # this matrix didn't any singleton dimension
c.expand(2, 6)
这会引发错误,因为根据 expand() 的定义,我们必须将一个尺寸与非单件维度匹配,但由于我们有两个单件维度,因此我们无法满足条件。错误…。
RuntimeError: The expanded size of the tensor (6) must match the existing size (2) at non-singleton dimension 1. Target sizes: [2, 6]. Tensor sizes: [2, 2]
函数4 – index_copy_(dim, index, tensor) ?张量
它使我们能够将张量复制到给定索引中的自张量中,该索引在索引张量中定义它包含三个参数
- 暗淡
- 保持索引顺序的索引张量
- 我们想要在我们的自张量中复制的张量
示例 1:
Python3
self_tensor = torch.zeros(6, 3)
a
t = torch.tensor([[7, 6, 9], [3, 9, 1], [0, 1, 9]], dtype = torch.float)
i = torch.tensor([3, 1, 0])
self_tensor.index_copy_(0, i, t)
现在,如果您查看输出张量...
tensor([[0., 1., 9.],
[3., 9., 1.],
[0., 0., 0.],
[7., 6., 9.],
[0., 0., 0.],
[0., 0., 0.]])
在上面的例子中
我们将 t 张量复制到 self_tensor 中,其顺序在 i 张量中定义
示例 2:
Python3
a = torch.tensor([[1, 8], [9, 5], [1, 5]])
b = torch.tensor([[3, 5], [9, 0], [2, 2]])
i = torch.tensor([2, 1, 0])
a.index_copy_(0, i, b)
输出张量:
tensor([[2, 2],
[9, 0],
[3, 5]])
我们可以使用两个非零张量执行示例 1 的相同操作
示例 3(常见错误)
Python3
a = torch.tensor([[8, 3], [1, 0]])
b = torch.tensor([[3, 9]])
i = torch.tensor([1])
a.index_copy(1, i, b)
————————————————————————— RuntimeError
Traceback (most recent call last)
3 b = torch.tensor([[3, 9]]) 4 i = torch.tensor([1]) —-> 5 a.index_copy(1, i, b) RuntimeError: index_copy_(): Source/destination tensor must have same slice shapes. Destination slice shape: 2 at dimension 1 and source slice shape: 1 at dimension 0.
上面的例子抛出了一个错误,因为我们试图给 dim = 1
但是,索引的暗淡元素应该包含与我们的 b 张量所拥有的元素数量相同的元素。
结论:所以每当我们需要将张量复制到具有指定顺序的自张量时,我们都可以使用这个函数
参考链接 –
- PyTorch 官方文档链接
- 整个代码的笔记本