这部分内容应该是以模型的训练以及调参为主,继上一篇神经网络介绍之后,这篇不主要将模型的训练和调参的方法,这篇讲讲pytorch模块的相关内容,毕竟。pytorch这个才是这次内容的重点模块。
1.简介PyTorch
PyTorch是Facebook发布的一款非常具有个性的深度学习框架,它和Tensorflow,Keras,Theano等其他深度学习框架都不同,它是动态计算图模式,其应用模型支持在运行过程中根据运行参数动态改变,而其他几种框架都是静态计算图模式,其模型在运行之前就已经确定。
2.PyTorch的使用
在 PyTorch 中 Tensor 代表多维数组,Tensor实际上就类似于 numpy 中的数组,两者可以自由转换。
import torch
from torch.autograd import Variable
x=Variable(torch.Tensor(2,2))
print("x variable: ",x)
print ("x.data: ",x.data, ",x.grad: ",x.grad)
#计算结果
x variable: tensor([[0.0000e+00, 0.0000e+00],
[2.1019e-44, 0.0000e+00]])
x.data: tensor([[0.0000e+00, 0.0000e+00],
[2.1019e-44, 0.0000e+00]]) ,x.grad: None
默认 Variable 是有导数 grad 的,x.data 是数据,这里 x.data 就是Tensor。x.grad 是计算过程中动态变化的导数。理解 pytorch,首先要理解求导的概念。求导的作用是用导数对神经网络的权重参数进行调整,Pytorch 中为求导提供了专门的包,包名叫 autograd。如果用autograd.Variable 来定义参数,则 Variable 自动定义了两个变量,data代表原始权重数据;而 grad 代表求导后的数据,也就是梯度。每次迭代过程就用这个 grad 对权重数据进行修正。再简介一个重点的概念,损失函数。损失函数又叫目标函数,是编译一个神经网络模型必须的两个参数之一。另一个必不可少的参数是优化器。损失函数是指用于计算标签值和预测值之间差异的函数,在机器学习过程中,有多种损失函数可供选择,典型的有距离向量,绝对值向量等。
import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F
sample = Variable(torch.ones(2,2))
a=torch.Tensor(2,2)
a[0,0]=0
a[0,1]=1
a[1,0]=2
a[1,1]=3
target = Variable (a)
简介几种常见的损失函数的计算方法:
nn.L1Loss:L1Loss 计算方法很简单,取预测值和真实值的绝对误差的平均数。
nn.SmoothL1Loss:SmoothL1Loss 也叫作 Huber Loss,误差在 (-1,1) 上是平方损失,其他情况是 L1 损失。
nn.MSELoss:平方损失函数。其计算公式是预测值和真实值之间的平方和的平均数。
nn.BCELoss:二分类用的交叉熵,其计算公式较复杂,这里主要是有个概念即可,一般情况下不会用到。
nn.CrossEntropyLoss:交叉熵损失函数,在图像分类神经网络模型中就常常用到,用于图像识别验证。
nn.NLLLoss:负对数似然损失函数,在前面接上一个 LogSoftMax 层就等价于交叉熵损失了。注意这里的xlabel 和上个交叉熵损失里的不一样,这里是经过 log 运算后的数值。这个损失函数一般也是用在图像识别模型上。
nn.NLLLoss2d:和上面类似,但是多了几个维度,一般用在图片上。比如用全卷积网络做分类时,最后图片的每个点都会预测一个类别标签。
简介优化器:
优化器用通俗的话来说就是一种算法,是一种计算导数的算法。各种优化器的目的和发明它们的初衷其实就是能让用户选择一种适合自己场景的优化器。优化器的最主要的衡量指标就是优化曲线的平稳度,最好的优化器就是每一轮样本数据的优化都让权重参数匀速的接近目标值,而不是忽上忽下跳跃的变化。因此损失值的平稳下降对于一个深度学习模型来说是一个非常重要的衡量指标。pytorch 的优化器都放在 torch.optim 包中。常见的优化器有:SGD,Adam,Adadelta,Adagrad,Adamax 等。这几种优化器足够现实世界中使用了,如果需要定制特殊的优化器,pytorch 也提供了定制化的手段,不过这里我们就不去深究了,毕竟预留的优化器已经足够强大了。
线性回归的模拟:Y=wX+b
import torch
from torch.autograd import Variable
import numpy as np
from numpy import random
import matplotlib.pyplot as plt
X = np.linspace(-1, 1, 200)
Y = 0.5 * X + 0.2* np.random.normal(0, 0.05, (200, ))
plt.scatter(X,Y)
plt.show()
#将X,Y转成200 batch大小,1维度的数据
X=Variable(torch.Tensor(X.reshape(200,1)))
Y=Variable(torch.Tensor(Y.reshape(200,1)))
# 神经网络结构
model = torch.nn.Sequential(
torch.nn.Linear(1, 1),)
optimizer = torch.optim.SGD(model.parameters(), lr=0.5)
loss_function = torch.nn.MSELoss()
for i in range(300):
prediction = model(X)
loss = loss_function(prediction, Y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
plt.figure(1, figsize=(10, 3))
plt.subplot(131)
plt.title('model')
plt.scatter(X.data.numpy(), Y.data.numpy())
plt.plot(X.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
plt.show()
在Pytorch中模型的保存和加载非常简单,比较常见的做法是保存和加载模型参数:torch.save(model_object.state_dict(), 'model.pt')
model.load_state_dict(torch.load(' model.pt'))
卷积层:卷积层是用一个固定大小的矩形区去席卷原始数据,将原始数据分成一个个和卷积核大小相同的小块,然后将这些小块和卷积核相乘输出一个卷积值。卷积的本质就是用卷积核的参数来提取原始数据的特征,通过矩阵点乘的运算,提取出和卷积核特征一致的值,如果卷积层有多个卷积核,则神经网络会自动学习卷积核的参数值,使得每个卷积核代表一个特征。
池化层:池化层比较容易理解,就是将多个元素用一个统计值来表示。比如对于二维最大值池化来说,用 torch.nn.functional. F.max_pool2d 方法来操作。
import torch.nn.functional as F
from torch.autograd import Variable
print("conv2d sample")
a=range(20)
x = Variable(torch.Tensor(a))
x=x.view(1,1,4,5)
print("x variable:", x)
y=F.max_pool2d(x, kernel_size=2,stride=2)
print ("y:",y)
总结:
机器学习博大精深,路很长,这次写的不知道是些啥。后面慢慢把yolov4这块搞搞。