张量的创建
文章目录
直接创建
torch.tensor
torch.tensor(data,dtype=None,device=None,requires_grad=False,pin_memory=False)
data(array_like) - tensor的初始数据,可以是list, tuple, numpy array, scalar或其他类型。
dtype(torch.dtype, optional) - tensor的数据类型,如torch.uint8, torch.float, torch.long等
device (torch.device, optional) – 决定tensor位于cpu还是gpu。如果为None,将会采用默认值,默认值在torch.set_default_tensor_type()中设置,默认为 cpu。
requires_grad (bool, optional) – 决定是否需要计算梯度。
pin_memory (bool, optional) – 是否将tensor存于锁页内存。这与内存的存储方式有关,通常为False。
l = [[1,2,3],[4,5,6],[7,8,9]]
t = torch.tensor(l)
print(t)
print(t.dtype)
ll = [[1.,-1.],[1.,-1.]]
t2 = torch.tensor(ll,dtype=torch.float64)
print(t2)
print(t2.dtype)
t3 = torch.tensor(ll)
print(t3)
print(t3.dtype)
![[Pasted image 20240809213925.png]]
浮点数默认是torch.float32类型,可以指定参数dtype进行指定数据类型
arr = np.array([[1,2,3],[4,5,6]])
t_from_arr = torch.tensor(arr,dtype=torch.uint8)
print(t_from_arr)
torch.from_numpy
还有一种常用的通过numpy创建tensor方法是torch.from_numpy()。这里需要特别注意的是,创建的**tensor和原array共享同一块内存(**The returned tensor and ndarray
share the same memory. ),即当改变array里的数值,tensor中的数值也会被改变。
arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
t_from_numpy = torch.from_numpy(arr)
print("numpy array:",arr)
print("torch tensor:",t_from_numpy)
print("\n修改arr")
arr[0,0]=0
print("numpy array:",arr)
print("torch tensor:",t_from_numpy)
print("\n修改tensor")
t_from_numpy[0,1]=1
print("numpy array:",arr)
print("torch tensor:",t_from_numpy)
![[Pasted image 20240809215934.png]]
依数值创建
torch.zeros
*torch.zeros(size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
功能:依给定的size创建一个全0的tensor,默认数据类型为torch.float32(也称为torch.float)。
*size
是 Python 中的一种特殊语法,表示“可变长度参数”。
具体来说,*size
的作用是允许函数接收任意数量的参数,并将这些参数作为一个元组传递给函数。在 torch.zeros
中,size
表示张量的形状(即它的维度)。通过使用 *size
,你可以传递一个或多个整数来指定张量的每一维的大小。
单个参数:
torch.zeros(3)
这会创建一个一维的张量,其大小为3。
多个参数:
torch.zeros(3, 4)
这会创建一个二维的张量,其形状为3x4。
使用元组解包:
你也可以通过传递一个元组并使用
*
操作符解包参数:size = (3, 4, 5) torch.zeros(*size)
这会创建一个三维的张量,其形状为3x4x5。
主要参数:
out (tensor, optional)
作用:
out
参数允许你指定一个已有的张量,用于接收torch.zeros
创建的张量结果。这意味着函数的输出不会生成一个新的张量,而是将结果直接存储到out
参数指定的张量中。使用场景:
- 内存优化: 在高效计算和节省内存分配方面非常有用。如果你已经有一个张量,并且希望在相同的内存位置存储新的数据(例如,全零的张量),可以使用
out
参数。 - 避免不必要的内存分配: 对于大型张量,避免了重复分配内存的开销。
- 内存优化: 在高效计算和节省内存分配方面非常有用。如果你已经有一个张量,并且希望在相同的内存位置存储新的数据(例如,全零的张量),可以使用
使用示例:
existing_tensor = torch.empty(2, 3) # 创建一个未初始化的张量
torch.zeros(2, 3, out=existing_tensor) # 使用 out 参数将全零的张量结果存储在 existing_tensor 中
print(existing_tensor)
n = np.random.randint(0, 10, size=(3, 3)) #生成一个 3x3 的矩阵,每个元素是 [0, 10) 之间的随机整数
print(n)
#转为张量
nn = torch.from_numpy(n)
#使用 torch.zeros 并将结果存储在 nn 中
torch.zeros(3,3,out=nn)
print(nn)
![[Pasted image 20240809221307.png]]
2. `layout (torch.layout, optional)`
- **作用**: `layout` 参数决定张量在内存中的存储布局方式。PyTorch 支持不同的内存布局,适用于不同的计算需求。
- **常见布局**:
- **`torch.strided`**: 默认的内存布局。数据以密集格式存储,张量元素按照一定的步长(stride)在内存中排列。
- **`torch.sparse_coo`**: 稀疏张量的布局方式,适用于大部分元素为零的稀疏矩阵。这种布局只存储非零元素及其索引,节省内存。
- **使用场景**:
- **默认密集存储**: 如果你的数据是密集的(大多数元素非零),使用默认的 `torch.strided` 布局。
- **稀疏数据**: 如果你的数据是稀疏的(大多数元素为零),使用 `torch.sparse_coo` 布局更为高效。
- **使用示例**:
(1) 默认布局(连续存储):
```python
import torch
# 创建一个形状为 (2, 3) 的默认连续布局零张量
default_tensor = torch.zeros(2, 3)
print(default_tensor)
print(default_tensor.is_contiguous()) # 输出: True
![[Pasted image 20240809222238.png]]
(2) 指定 strided 布局:
# 创建一个形状为 (2, 3) 的 strided 布局零张量
strided_tensor = torch.zeros(2, 3, layout=torch.strided)
print(strided_tensor)
print(strided_tensor.is_contiguous()) # 输出: True
![[Pasted image 20240809222245.png]]
(3) 稀疏布局:
# 创建一个稀疏布局的零张量
sparse_tensor = torch.zeros(2, 3, layout=torch.sparse_coo)
print(sparse_tensor)
print(sparse_tensor.is_sparse) # 输出: True
![[Pasted image 20240809222349.png]]
解释:
1. indices=tensor([], size=(2, 0))
:
- 这表示稀疏张量中非零元素的索引。
- size=(2, 0)
表示这是一个2D张量,但目前没有任何索引(因为张量是空的)。
- 第一个维度 (2) 对应于张量的维数(在这里是2D)。
- 第二个维度 (0) 表示没有非零元素。
2. `values=tensor([], size=(0,))`:
- 这表示非零元素的值。
- 当前为空,因为没有非零元素。
3. `size=(2, 3)`:
- 这是整个稀疏张量的形状。
- 它表示这个稀疏张量在稠密形式下会是一个 2x3 的矩阵。
4. `nnz=0`:
- "nnz" 代表 "number of non-zero elements"(非零元素的数量)。
- 这里为0,表示没有非零元素。
5. `layout=torch.sparse_coo`:
- 这指定了张量的布局。
- `sparse_coo` 表示这是一个 COO(Coordinate)格式的稀疏张量。
(4) 使用 as_strided 创建非连续布局:
# 创建一个非连续布局的零张量
non_contiguous_tensor = torch.zeros(4, 4).as_strided((2, 2), (2, 1))
print(non_contiguous_tensor)
print(non_contiguous_tensor.is_contiguous()) # 输出: False
![[Pasted image 20240809222532.png]]
解释:
torch.zeros(4, 4)
:- 首先,创建一个 4x4 的全零张量。
- 这个张量在内存中是连续存储的。
.as_strided((2, 2), (2, 1))
:然后,使用
as_strided
方法重新解释这个张量的存储。as_strided
接受两个主要参数:新的形状和新的步长(stride)。新的形状
(2, 2)
:
这表示我们要将原来的 4x4 张量重新解释为一个 2x2 的张量。新的步长
(2, 1)
:- 步长定义了在内存中如何"跳跃"以获取下一个元素。
2
表示在第一个维度上,每次需要跳过2个元素。1
表示在第二个维度上,每次只需要移动到下一个相邻元素。
结果是什么样的?
原始的 4x4 张量(用索引表示):
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
应用 as_strided((2, 2), (2, 1))
后,我们得到:
0 1
4 5
这个新的 2x2 张量是通过以下方式从原始张量中"提取"的:
- 第一行:取原始张量的 (0,0) 和 (0,1) 元素
- 第二行:取原始张量的 (1,0) 和 (1,1) 元素
这个新张量是非连续的,因为它在内存中不是连续存储的。它跳过了原始张量中的一些元素。
使用 as_strided
可以创建对原始数据的新视图,而不需要复制数据。这在某些情况下可以提高效率,但也需要小心使用,因为不正确的使用可能导致意外的结果。
(5) 指定设备和数据类型:
# 在 CUDA 设备上创建一个 float16 类型的零张量
if torch.cuda.is_available():
cuda_tensor = torch.zeros(2, 3, dtype=torch.float16, device='cuda', layout=torch.strided)
print(cuda_tensor)
print(cuda_tensor.device) # 输出: cuda:0
![[Pasted image 20240809222710.png]]
torch.zeros_like
torch.zeros_like(input, dtype=None, layout=None, device=None, requires_grad=False)
功能:依input的size创建全0的tensor。
主要参数:
input(Tensor) - 创建的tensor与intput具有相同的形状。
除了创建全0还有创建全1的tensor,使用方法是一样的,这里就不赘述。
*torch.ones(size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
功能:依给定的size创建一个全1的tensor。
torch.ones_like(input, dtype=None, layout=None, device=None, requires_grad=False)
功能:依input的size创建全1的tensor。
torch.full(size, fill_value, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
功能:依给定的size创建一个值全为fill_value的tensor。
主要参数:
siz (int…) - tensor的形状。
fill_value - 所创建tensor的值
out(tensor, optional) - 输出的tensor,即该函数返回的tensor可以通过out进行赋值。
example:
import torch
print(torch.full((2, 3), 3.141592))
torch.full_like(input, fill_value, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
torch.full_like之于torch.full等同于torch.zeros_like之于torch.zeros,因此不再赘述。
torch.arange(start=0, end, step=1, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
功能:创建等差的1维张量,长度为 (end-start)/step,需要注意数值区间为[start, end)。
主要参数:
start (Number) – 数列起始值,默认值为0。the starting value for the set of points. Default: 0.
end (Number) – 数列的结束值。
step (Number) – 数列的等差值,默认值为1。
out (Tensor, optional) – 输出的tensor,即该函数返回的tensor可以通过out进行赋值。
example:
import torch
print(torch.arange(1, 2.51, 0.5))
torch.range()函数就不推荐了,因为官网说了“This function is deprecated in favor of torch.arange().”
torch.linspace(start, end, steps=100, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
功能:创建均分的1维张量,长度为steps,区间为[start, end]。
主要参数:
start (float) – 数列起始值。
end (float) – 数列结束值。
steps (int) – 数列长度。
example:
print(torch.linspace(3, 10, steps=5))
print(torch.linspace(1, 5, steps=3))
torch.logspace(start, end, steps=100, base=10.0, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
功能:创建对数均分的1维张量,长度为steps, 底为base。
主要参数:
start (float) – 确定数列起始值为base^start
end (float) – 确定数列结束值为base^end
steps (int) – 数列长度。
base (float) - 对数函数的底,默认值为10,此参数是在pytorch 1.0.1版本之后加入的。
example:
torch.logspace(start=0.1, end=1.0, steps=5)
torch.logspace(start=2, end=2, steps=1, base=2)
torch.eye(n, m=None, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)**
功能:创建单位对角矩阵。
主要参数:
n (int) - 矩阵的行数
m (int, optional) - 矩阵的列数,默认值为n,即默认创建一个方阵
example:
import torch
print(torch.eye(3))
print(torch.eye(3, 4))
*torch.empty(size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)
功能:依size创建“空”张量,这里的“空”指的是不会进行初始化赋值操作。
主要参数:
size (int…) - 张量维度
pin_memory (bool, optional) - pinned memory 又称page locked memory,即锁页内存,该参数用来指示是否将tensor存于锁页内存,通常为False,若内存足够大,建议设置为True,这样在转到GPU时会快一些。
torch.empty_like(input, dtype=None, layout=None, device=None, requires_grad=False)
功能:torch.empty_like之于torch.empty等同于torch.zeros_like之于torch.zeros,因此不再赘述。
torch.empty_strided(size, stride, dtype=None, layout=None, device=None, requires_grad=False, pin_memory=False)
功能:依size创建“空”张量,这里的“空”指的是不会进行初始化赋值操作。
主要参数:
stride (tuple of python:ints) - 张量存储在内存中的步长,是设置在内存中的存储方式。
size (int…) - 张量维度
pin_memory (bool, optional) - 是否存于锁页内存。
依概率分布创建
总结
关于张量的创建方式以及是否会自动计算梯度的表格如下:
创建方式 | 描述 | 是否自动计算梯度 |
---|---|---|
torch.tensor(data) |
创建一个包含数据的张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.zeros(size) |
创建一个全0的张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.ones(size) |
创建一个全1的张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.full(size, value) |
创建一个张量,并用指定值填充,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.arange(start, end) |
创建一个包含从start到end的序列的张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.linspace(start, end) |
创建一个包含线性间隔的序列的张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.rand(size) |
创建一个包含均匀分布随机数的张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.randn(size) |
创建一个包含正态分布随机数的张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.empty(size) |
创建一个未初始化的张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.eye(size) |
创建一个单位矩阵张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.autograd.Variable() |
创建一个变量(旧版本),可以设置是否启用梯度计算(通过requires_grad=True )。 |
是(如果设置requires_grad=True ) |
torch.from_numpy(ndarray) |
将一个NumPy数组转换为张量,默认不启用梯度计算。 | 否(除非设置requires_grad=True ) |
torch.tensor(data, requires_grad=True) |
创建一个启用梯度计算的张量。 | 是 |
张量的操作
scater_
张量的随机种子
张量的数学操作
总结
参考
- https://tingsongyu.github.io/PyTorch-Tutorial-2nd/chapter-2/2.4-method-tensor.html#%E4%BE%9D%E6%95%B0%E5%80%BC%E5%88%9B%E5%BB%BA