Pytorch 基本元素的操作
创建一个矩阵的操作
import torch
x = torch.empty(5,3)
if __name__ == '__main__':
print(x)
创建一个有初始化的矩阵:
y = torch.rand(2,4)
y_1 = torch.randn(2,4)
if __name__ == '__main__':
print(y)
print(y_1)
对比有初始化和无初始化的矩阵时,当声明一个未初始化的矩阵的时候,它本身不包活任何确切的值。
创建一个全0的矩阵,指定数据的类型为long
x: Tensor = torch.zeros(5,7,dtype =torch.long )
if __name__ == '__main__':
print(x)
通过数据来创建张量
y: Tensor = torch.tensor([2.5,3.5])
通过已有的一个张量来创建一个相同尺寸的新张量,创建一个与已有张量尺寸相同的张量但是其中的值不同的张量
x: Tensor = torch.zeros(5, 7, dtype=torch.long)
'''use new_methods to construct a new tensor which own the same size of the
ole ones '''
x = x.new_ones(5, 7, dtype=torch.double)
'''use rand_like method to construct a new tensor which own the same size of
the old one but the values of the new tensor are random also the type of the
values are redefine'''
y: Tensor = torch.rand_like(x, dtype=torch.double)
double类型显示的所有张量都带有.
得出张量的尺寸
print(x.size())
注意:x.size()函数本质返回的是一个tuple,因此它支持元组的所有操作。
基本运算操作
加法操作
第一种
print(x+y)
第二种
z = torch.add(x,y)
第三种
'''define a new empty tensor, use the parameter of the add method to give the
value of the method's result through " out " '''
result = torch.empty(5,7)
torch.add(x,y,out=result)
第四种(原地置换)
y.add_(x)
注意:所有的原地置换(in-place)都是存在小下划线的_,并且会改变原来的对象
利用Numpy切片的方式访问张量
print(x[:,0]) # 访问张量x的第0列
print(x[:,: 3]) # 访问张量x从第0,1,2列
改变张量的形状 torch.view() view使用的前提是保证元素的个数相同
x = torch.randn(4,4)
y = x.view(16) # 表示1行16列的张量
z = x.view(-1,8) # -1表示自动适配后边列的个数
如果张量中只有唯一的元素的话,可以用.item()将值取出,作为一个python number
x = torch.randn(1)
print(x)
print(x.item())
关于Torch Tensor 和Numpy array 之间的相互转换
torch tensor和numpy array是共享底层内存空间的,改变一个值,另一个也会改变
a = torch.ones(5)
b = a.numpy()
a.add_(1)
if __name__ == '__main__':
print(a)
print(b)
共享内存:对一个实现加法,另一个也会改变。
反过来numpy array 转换为torch tensor 也是一样的
c = np.ones(6)
d = torch.from_numpy(c)
np.add(c,1,out = c)
if __name__ == '__main__':
print(c)
print(d)
注意:所有在cpu上的tensors,除了chartensor,剩下的都可以转换为numpy array并且可以实现互相转换
pytorch 中的autograd
在整个pytorch框架中,所有的神经网络本质上都是一个autograd package(用来自动求导的包)
autograd提供了一个对tensors上所有的操作进行自动微分的功能
关于 torch.tensor
torch.tensor是整个package中的核心类,如果将属性requires_grad设置为true,它将自动追踪在这个类定义上的所有操作,当代码要反向传播的时候,直接调用.backward()就可以自动计算所有的梯度,在这个tensor上的所有梯度将被累加进属性.grad中。
如果想要中止一个tensor在计算图中的追踪回溯,只需要执行.detach()就可以从该tensor从计算图中撤下,在未来的回溯计算中也不会再计算该tensor。
除了.detach(),如果想要中止计算图的回溯,也就是不在进行方向传播求导数的过程,也可以采用代码块的方式 with torch.no_grad():这种方式非常适用于对模型进行预测的时候,因为预测阶段不再需要对梯度进行计算。
关于torch.function
Function 类是和tensor 类同等重要的一个核心类,它和tensor共同构建一个完整的类,每一个tensor拥有一个.grad_fn属性,代表引用了哪个具体的function创建了该tensor
如果某个张量tensor是用户自定义的,则其对应的grad_fu is None
x1 = torch.ones(3,3)
x = torch.ones(2,2,requires_grad=True)
y = x + 2
if __name__ == '__main__':
print(x)
print(x1)
print(y)
print(x.grad_fn)
print(y.grad_fn)
因为x是自定义的张量,而y是靠着x衍生出来的张量,所以y的grad_fn会是一个类的对象x则是none。
关于方法requires_grad_(),该方法可以原地改变tensor的属性 .requires_grad的值,如果没有主动设定,默认为false
关于梯度Gradient
在pytorch之中,反向传播是依靠.backward()实现的
关于自动求导的属性设置,可以通过设置.requires_grad = True 来执行自动求导,也可以通过代码块的方式来中止自动求导
print(x.requires_grad)
print((x**2).requires_grad)
//代码块来中止求导
with torch.no_grad():
print((x**2).requires_grad)
可以通过.detach()来获得一个新的tensor,拥有相同的内容但是不需要自动求导