PyTorch 提供两种类型的数据抽象,称为张量和变量。张量类似于Numpy中的数组,它们也可以在GPU上使用,并能够改善性能。
常见张量如下:
- 标量(0维张量)
- 向量(1维张量)
- 矩阵(2维张量)
- 3维张量
- 切片张量
- 4维张量
- 5维张量
- GPU张量
标量(0维张量)
x = torch.rand(10)
x.size()
注:标量的类型通常是FloatTensor或LongTensor
向量(1维向量)
temp = torch.FloatT
矩阵(2维向量)
boston_tensor = torch.from_numpy(boston.data)
boston_tensor.size()
boston_tensor[:2]
注:torch.from_numpy
将Numpy数组转换成torch张量
3维张量
from PIL import Image
# 使用PIL包从磁盘读入熊猫图像并转成numpy数组
panda = np.array(Image.open('image.jpg').resize((224,224)))
panda_tensor = torch.from_numpy(panda)
panda_tensor.size()
切片张量
sales = torch.FloatTensor([1000, 23, 213, 42, 12, 25, 231, 53])
sales[:5]
4维张量
# 从磁盘中读取图片文件
cats = glob(data_path + '*.jpg')
#将图片转换为numpy数组
cat_images = np.array([np.array(Image.open(cat).resize((224,224))) for cat in cats[:64]])
cat_imgs = cat_imgs.reshape(-1, 224, 224, 3)
cat_tensors = torch.from_numpy(cat_imgs)
5维张量
# 视频数据,帧数
1×30×224×224×3 一个视频30帧,每帧图片224×224×3
GPU上的张量
a = torch.rand(2, 2)
b = torch.rand(2, 2)
c = a + b
d = torch.add(a, b)
#CPU
a.matmul(b)
#GPU
a = a.cuda()
b = b.cuda()
a.matmul(b)
注:PyTorch提供了一个名为cuda()
的简单函数,将张量从CPU赋值到GPU。
变量
# class中定义Variable: data, grad和creator
x = Variable(torch.ones(2, 2), requires_grad=True)
y = x.mean()
y.backward() # 反向传播
x.grad # 梯度
x.grad_fn # 指向梯度函数
注:深度学习算法经常表示计算图。
训练深度学习算法步骤:
- 构建数据管道
- 构建网络框架
- 使用损失函数评估架构
- 使用优化算法优化网络架构的权重
1. PyTorch 构建深度学习算法的方式(网络架构)
PyTorch中所有网络都实现为类,创建PyTorch类的子类要调用nn.Module
,并实现__init__
和forward
方法。在init
中初始化层,在forward中,利用输入数据传给init
中的初始化层,并返回最终值,通俗的讲,就是前向传播。
class MyFirstNetwork(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(MyFirstNetwork, self).__init__()
self.layer1 = nn.Linear(input_size, hidden_size)
self.layer2 = nn.Linear(hidden_size, output_size)
def __forward__(self, input):
out = self.layer1(input)
out = nn.ReLU(out)
out = self.layer2(out)
return out
注:继承父类,super方法用于将子类的参数传给父类。
2. 不同机器学习问题的模型框架(last_Lay)
基于要解决的问题类别,最后一层是确定的。使用机器学习或深度学习算法解决的问题通常由三类,最后一层的情况通常如下。
- 对于回归问题,如预测T恤衫的销售价格,最后使用的是一个输出的线性层,输出值是连续的。
- 将一张给定的图片归类为T恤衫或者衬衫,用到的是sigmoid激活函数,因为他的输出值不是接近于1就是接近于0,这种问题通常为二分类问题。
- 对于多类别分类问题,如必须把给定的图片归类为T恤、牛仔裤、衬衫或连衣裙,网络最后使用softmax层。
3. 损失函数
一旦定义好网络架构,还剩下最重要的两步。一步是评估网络执行特定的回归或分类任务时表现的优异程度(损失值),另一步时优化权重。
优化器(梯度下降)通常接受一个标量值,因而loss函数应生成一个标量值,并在其训练期间最小化。
回归问题经常使用的Loss函数是均方误差(MSE)(torch.nn.MSELoss)。
分类问题,经常使用交叉熵损失函数(torch.nn.CrossEntropyLoss()).
4. 优化网络结构
计算出网络的损失值后,需要优化权重以减少损失,并改善算法的准确率。
PyTorch提供的一些常用的优化器如下:
- ADADELTA
- Adagrad
- Adam
- SparseAdam
- Adamax
- ASGD
- LBFGS
- RMSProp
- Rprop
- SGD
optimizer = optim.SGD(model.parameters(), lr = 0.01)
for input, target in dataset:
optimizer.zero.grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward() # 计算梯度值
optimizer.step() # 用于真正改变调整学习参数