pytorch的API
1. torch包
初始化Tensor,Tensor的变换,随机初始化一个Tensor, 上下文管理器torch.no_grad(),不进行梯度传播。
torch.randn(2,3)
随机一个两行三列的tensortorch.zeros(3)
随机一个一维的0向量torch.argmax()
获取最大位置torch.matmul()
两个矩阵相乘,支持numpy的broadcast机制
满足broadcast的两个条件:要么两个矩阵的shape是完全相同的,这没得说,另一个条件是从后往前,对应位置的维度相同,或者是有其中一个是1。
广播机制:https://blog.csdn.net/luo3300612/article/details/100100291
乘法中的广播机制:对于两个tensor,肯定是维度少的那个是broadcast矩阵。比如最后一个,比如常见,一个维度是[10, 3, 4] 的矩阵,乘以一个[4, 5]的矩阵,其实是后者进行了广播,[1, 4, 5],对前者,相当于是有10个3x4的矩阵,每个矩阵乘了一个[4, 5]的矩阵,得到[3,5]的矩阵。
回想tensorflow中的tf.matmul()
函数也是广播的。
>>> # vector x vector 一维乘以一维的向量:对应元素相乘再相加,得到标量
>>> tensor1 = torch.randn(3)
>>> tensor2 = torch.randn(3)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([])
>>> # matrix x vector
>>> tensor1 = torch.randn(3, 4)
>>> tensor2 = torch.randn(4)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([3])
>>> # batched matrix x broadcasted vector
>>> tensor1 = torch.randn(10, 3, 4)
>>> tensor2 = torch.randn(4)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([10, 3])
>>> # batched matrix x batched matrix
>>> tensor1 = torch.randn(10, 3, 4)
>>> tensor2 = torch.randn(10, 4, 5)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([10, 3, 5])
>>> # batched matrix x broadcasted matrix
>>> tensor1 = torch.randn(10, 3, 4)
>>> tensor2 = torch.randn(4, 5)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([10, 3, 5])
torch.squeeze()
与torch.unsqueenze()
的用法:
squeeze的用法主要就是对数据的维度进行压缩或者解压。
先看torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的数去掉第一个维数为一的维度之后就变成(3)行。squeeze(a)就是将a中所有为1的维度删掉。不为1的维度没有影响。a.squeeze(N) 就是去掉a中指定的维数为一的维度。还有一种形式就是b=torch.squeeze(a,N) a中去掉指定的定的维数为一的维度。
再看torch.unsqueeze()这个函数主要是对数据维度进行扩充。给指定位置加上维数为一的维度,比如原本有个三行的数据(3),在0的位置加了一维就变成一行三列(1,3)。a.squeeze(N) 就是在a中指定位置N加上一个维数为1的维度。还有一种形式就是b=torch.squeeze(a,N) a就是在a中指定位置N加上一个维数为1的维度
torch.nn
这个包主要包括了神经网络的各个层的实现
- nn.Module,算法基类
- 卷积层
- 池化层
- 各种激活函数
- 各种损失函数
- 循环神经网络:RNN,LSTM,GRU
- Embedding层
- transform层
- Linearn层
torch.nn.Functional
把torch.nn包转化为函数
torch.optim
优化器,都在这个包里。在初始化一个优化器的时候需要传入需要训练的参数。并且所有的optimizer都实现了一个step()
方法来更新参数。
optimizer还有一个参数是clousure,用来重新计算梯度。
一个官方的例子:
# -*- coding: utf-8 -*-
import torch
import random
class DynamicNet(torch.nn.Module):
def __init__(self, D_in, H, D_out):
super(DynamicNet, self).__init__()
self.input_linear = torch.nn.Linear(D_in, H)
self.middle_linear = torch.nn.Linear(H, H)
self.out_linear = torch.nn.Linear(H, D_out)
def forward(self, x) -> torch.Tensor:
h_relu = self.input_linear(x).clamp(min=0)
# 每次迭代时加入的不定层数的relu后,学习速率变慢了
for _ in range(random.randint(0, 3)):
h_relu = self.middle_linear(h_relu)
y_pred = self.out_linear(h_relu)
return y_pred
N, D_in, H, D_out = 64, 1000, 100, 10
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
learning_rate = 1e-4
model = DynamicNet(D_in, H, D_out)
criterion = torch.nn.MSELoss(reduction='sum')
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
for t in range(500):
# forward pass
y_pred = model(x)
loss = criterion(y_pred, y)
if t % 100 == 0:
print(t, loss.item())
# zero gradient, backward, update weights
optimizer.zero_grad()
# backward是为了计算梯度,在计算梯度之前清空optimizer存放的上一步的梯度
loss.backward()
optimizer.step()