pytorch 是一个基于python的科学计算包,
用于代替numpy,可以利用gpu的性能进行计算;
作为一个深度学习平台。
入门
创建张量
张量(tensor)类似于NumPy中的ndarray,但还可以在GPU上使用,实现加速计算的效果。
创建张量的几种方式:
-
创建一个没有初始化的矩阵张量
x=torch.empty(5,3) -
创建一个随机初始化矩阵
x = torch.rand(5,3) -
创建一个填满零,且数据类型为long的矩阵
x = torch.zeros(5, 3, dtype=torch.long)
print(x) -
直接从数据构造张量
x = torch.tensor([5.5, 3]) -
根据已有的张量构造新的张量
x = x.new_ones(5, 3, dtype=torch.double)
x = torch.randn_like(x, dtype=torch.float)
获取张量的形状
print(x.size())
注意,x.size的类型是元组
张量的运算
加法:
- 加法形式一
y = torch.rand(5, 3)
print(x + y) - 加法形式二
print(torch.add(x, y)) - 加法:给定一个输出张量作为参数
result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result) - 加法:原位/原地操作(in-place)
y.add_(x)
print(y)
乘法:
a*b: 对应元素相乘
>>> a = torch.tensor([2, 3, 5])
>>> b = torch.tensor([1, 4, 2])
>>> a*b
tensor([ 2, 12, 10])
eg2
>>> a = torch.rand(3,2,4)
>>> print(a)
tensor([[[0.7227, 0.4787, 0.9396, 0.6984],
[0.1252, 0.2006, 0.2366, 0.9549]],
[[0.4684, 0.3253, 0.7873, 0.1744],
[0.2180, 0.4210, 0.0993, 0.2495]],
[[0.0966, 0.7351, 0.1396, 0.2278],
[0.9622, 0.9284, 0.3647, 0.4792]]])
>>> b = torch.rand(3,2,4)
>>> print(b)
tensor([[[0.9952, 0.0990, 0.1335, 0.7350],
[0.6576, 0.5238, 0.2977, 0.6391]],
[[0.5607, 0.5219, 0.0735, 0.8392],
[0.3514, 0.5577, 0.7860, 0.4641]],
[[0.0231, 0.1542, 0.1217, 0.3119],
[0.8564, 0.1494, 0.3588, 0.8848]]])
>>> print(a*b)
tensor([[[0.7193, 0.0474, 0.1254, 0.5133],
[0.0824, 0.1051, 0.0704, 0.6103]],
[[0.2626, 0.1698, 0.0579, 0.1463],
[0.0766, 0.2348, 0.0780, 0.1158]],
[[0.0022, 0.1134, 0.0170, 0.0710],
[0.8241, 0.1387, 0.1309, 0.4240]]])
索引操作:
print(x[:, 1])
输出x的第二列数据
改变tensor形状:使用torch.view
x = torch.rand (5,3)
y= x.torch.view(15)
z = x.torch.view(-1, 5)
转置、索引、切片等等其他运算,参考链接: link.
桥接NumPy
torch张量和numpy数组之间可以互相转化,
他们共享底层内存,一个改变,另一个也会改变
-
torch张量转换为numpy数组
a = torch.ones(5) #创建了值全为1的一维张量
b = a. numpy() #把张量a转换为数组b随a的变化而变化,对a实施加一的操作,那么b的值也会相应的加一。
-
numpy数组转换为torch张量
a = np.ones(5)
b = torch.from_numpy(a)
cuda上的张量
张量可以使用.to移动到任何设备(device)s上
device = torch.device(“cuda”)
x = x.to(device)
或者直接在Gpu上创建tensor
y = torch.ones_like(x, device =device)
autograd自动求导
为张量上的所有操作提供了自动求导操作。
张量的属性
.requires_grad属性:当该属性设置为true的话,会追踪该张量的所有操作
.grad属性: 这个张量的所有梯度会自动累加到.grad属性。
.grad_fn属性:每个张量都有一个.grad_fn属性,该属性引用了创建tensor的function
完成计算后,通过调用.backward(),来自动计算所有梯度。
求梯度
如果需要计算导数,可以在 Tensor 上调用 .backward()。
如果 Tensor 是一个标量(即它包含一个元素的数据),则不需要为 backward() 指定任何参数,
但是如果它有更多的元素,则需要指定一个 gradient 参数,该参数是形状匹配的张量。
x = torch.ones(2, 2, requires_grad=True)
y = x + 2
z = y * y * 3
out = z.mean()
print(z, out)
现在求out对x的梯度,
因为out是个标量,所以out.backward()等价于out.backward(torch.tensor(1.))
out.backward() #开始反向传播
print(x.grad) #输出导数 d(out)/dx
得到的梯度是个4*4的矩阵
可以通过给backward指定参数v,求雅可比向量积
神经网络
使用torch.nn包来构建神经网络。
nn包依赖于autograd包来定义模型并对他们求导。
一个神经网络的典型训练过程:
- 定义网络
- 在数据集上迭代,经过网络计算得到输出
- 计算损失loss
- 将梯度反向传播给网络的参数
- 更新网络的权重参数,weight = weight -learning_rate * gradient