001.Tensor
2024.3.18(人生第一次用Markdown写语法)
1.创建Tensor
对应tensor_create类,创建Tensor有三种方法
1.直接加载其它数据类型
这种数据类型一般是python的六大基本类型
data = [[1, 2], [3, 4]] # python list
x_data = torch.tensor(data) #
x_data2 = torch.tensor((1, 2, 3))
# x_data3 = torch.tensor({"a": 5}) # fail
print("x_data2: ", x_data2)
PS:一些常用Tensor属性:
#x_data.dtype 查看tensor内的数据类型
#x_data.device 查看tensor存储在cpu或gpu
#x_data.stride 查看步长(数据沿着一个轴在内存上的间距)
#x_data.real 查看实部
#x_data.imag 查看虚部
#x_data.T 转置
#x_data.grad_fn 查看计算反向梯度的函数(pytorch是自动计算梯度的)
#x_data.grad 返回梯度存的对象
2.利用内置函数初始化tensor
初始化全1矩阵或者对角矩阵(如在auto_guard中初始传入就必须是全矩阵)
data = torch.ones(1, 2, 3)
data1 = torch.zeros(1, 3, 4)
data2 = torch.randn(3, 4, 5)
data3 = torch.eye(4, 5)
data4 = torch.randint(5, (2, 10))
print("data type: ", type(data4))
print("data2: ", data4)
3.运用numpy来初始化
PS:计算机中存储矩阵的方法
#data=meta_data+raw_data
#meta_data=shape/dtype/stride/dim/device
#raw_data=data_ptr
#meta存储的矩阵的属性(如元素类型,维度,步长等)
#raw即存储的指针
#由于numpy和tensor都需要对矩阵进行高效连续的运算,但
传统的python中的list在内存中存储数据是离散的,不便于进行数学上的矩阵运算
#所以tensor底层还是运用的numpy中的数据存储方式进行运算
numpy和tensor互相转化
import torch
import numpy as np
np_array = np.array([1, 2, 3])
#运用.from_numpy()来将numpy转化为tensor
tensor_numpy = torch.from_numpy(np_array)
#运用.numpy来将tensor转化为numpy
data_numpy = tensor_numpy.numpy()
print("numpy tensor: ", tensor_numpy)
2.tensor.to用法
1.转化数据类型
import torch
import numpy as np
tensor = torch.ones(4, 5)
tensor = tensor.to(torch.float32)
2.转化计算平台
第一种写法,直接转换
import torch
import numpy as np
tensor = torch.ones(4, 5)
tensor_0 = tensor.to(torch.int32).to("cuda:0") # 数据的搬迁 h2d: h: host d:device(gpu)
print("tensor device: ", tensor_0.device)
第二种写法,比较全面的写法
import torch
import numpy as np
tensor = torch.ones(4, 5)
if torch.cuda.is_available():
device = torch.device("cuda:0")
else:
device = torch.device("cpu")
tensor_2 = tensor.to(device)
print(tensor_2.device)
3.tensor.transpose()
PS:关于存储数据在空间上的连续
import torch
import numpy as np
data0 = torch.randn(4, 6) # 24
data1 = data0.reshape(6, 4)
data2 = data0.view(6, 4) # reshape 和 view 相同
data3 = data0.transpose(0, 1) # data uncontiguous
print(data0)
print(data2)
print(data3)
运行结果如下图所示
import torch
import numpy as np
data0 = torch.randn(4, 6) # 24
data1 = data0.reshape(6, 4)
data2 = data0.view(6, 4) # reshape 和 view 相同
data3 = data0.transpose(0, 1) # data uncontiguous
print(data0.storage())
print(data3.storage())
可见,当运用reshape或者storge后原来数据的存储地址并没有发生变化,但显示print的结果却发生了变化,说明在读取内存上的数据的时候它们并不是连续的,(不是按顺序来访问的),
我们称这种情况为 uncontiguous(不连续),即访问顺序在内存上并不是连续的.
这时候我们再使用.view()方法则会报错
import torch
import numpy as np
data0 = torch.randn(4, 6) # 24
data1 = data0.reshape(6, 4)
data2 = data0.transpose(0, 1) # data uncontiguous
data3 = data2.view(4,6)
因为不连续!
这时候我们可以用.contiguous()将其变成连续的,但这时候相当于重新复制了一份数据
import torch
import numpy as np
data0 = torch.randn(4, 6) # 24
data1 = data0.transpose(0, 1) # data uncontiguous
data2 = data1.contiguous()
print(data1.data_ptr())
print(data2.data_ptr())