pytorch 与tensorflow都是将深度学习的网络构造,训练,集成封装的,我们使用Pytorch 进行实例化,torch 官方测试案例Lenet。
import torch.nn as nn import torch.nn.functional as F
一般深度学习都需要torch的这两个大库,一个用于构建神经网络、卷积神经网络、残差网络。深度学习其实核心要素就是构建网络,训练数据,使得神经网络学习到一系列参数,使得神经网络看见我们传进去的参数就会输出预测的东西,一般来说入门都是先进行图像分类,因为输出只输出相应的类别.其他也类似,我们想得到图像中目标的位置信息,那么在训练过程中就将信息输入然后进行训练,而目标跟踪则是一张张目标检测,
开始创建模型
model.py
对于模型都是使用类进行编写,方便后续调用,模型继承torch的torch.nn.Module。
复写init 与forward函数
构成分类网络的基本组成单元为 卷继层 全连接层 池化层
import torch.nn as nn
import torch.nn.functional as F
class LeNet(nn.Module):
def __init__(LeNet,self).__init__():
# 从这句中可以看出self就是构造的模型本身,初始化传入的参数为无。
self.conv1=nn.Conv2d(3,16,5)
#__init__中定义的就是模型中的变量信息
#卷积层nn.Conv2d(3,16,5)第一个参数是输入特征层的维度,第二个为输出特征层的维数,第三个参数是进行卷积的卷积核的大小为5*5
self.pool1=nn.MaxPool2d(2,2)
#最大池化层在2*2区域进行最大值池化
self.conv2=nn.Conv2d(16,32,5)
self.pool2=nn.MaxPool2d(2,2)
self.fc1=nn.Linear(32*5*5,120)
#这是一个卷积层到全连接层的交接处,也是二维矩阵到一维度向量的变换处,通过全连接层进行分类,5*5是通过一系列卷积层和池化层的矩阵大小
self.fc2=nn.Linear(120,84)
self.fc3=nn.Linear(84,10)
#到这里模型的组件已经构造好了,接下来就是用线条将这些组件进行连接起来了,forward进行登场;
def forward(self,x):
x=F.relu(self.conv1(x))
x=self.pool1(x)
x=F.relu(self.conv2(x))
x=self.pool2(x)
x=x.view(-1,32*5*5)
x=F.relu(self.fc1(x))
x=F.relu(self.fc2(x))
x=self.fc3(x)
return x
卷积的目的就是为了提取图像中的特征,卷积的特性就是拥有局部感知的机制,权值共享。卷积中的理解两个点
1.卷积核经过运算的矩阵大小公式:
2.卷积通道与卷积核个数,
卷积核的通道数与输入特征图的channel相同
输出的特征矩阵通道与卷积核个数相同
假如输入28283的图像,进行一次卷积,用3335的卷积核作用就会得到输出特征图的通道数是5,至于输出的特征图的大小,利用公式计算可以得到。W=28,K=3,P=0,S=1 那么输出特征图大小 out=2626*5
至于池化层和全连接很容易理解,在此不再赘述。全连接层输出的每一个神经元都是所有神经元的加求和。
在其中还有激活函数,激活函数就是为了增加网络的非线性从而达到模拟万物规律的目的。后面我会抽一个章节,对激活函数,平均池化,最大值池化,优化器,不同的损失函数进行讲解。
构建好模型后,我们就要小试牛刀训练图像,让我们的网络记住所有的类别信息,识别图像,所谓记住其实就是通过神经网络的权重来达到记忆的作用。
我们还从头分析代码
import torch import torchvision #torchvision 主要用于对输入图像的处理 import torch.nn as nn import model import LeNet #由于LeNet 模型的文件叫model.py因此import model import torch.optim as optim #optim 是训练的优化器,也就是反向传播优化模型的参数 import torchvision.transforms as transforms
相应的库引入之后我们就开始创建我们的魔高大楼
无论是JAVA C++还是PYTHON,作为编程语言,在执行的时候都需要进行定义Main函数,从而开始程序的运行。
def main():
transform=transforms.Compose([transform.ToTensor(),
transforms.Normalize((0.5,0.5,0.5)(0.5,0.5,0.5)])
#计算机视觉都是处理的二维图像一维向量是一维,二维是图像,然而处理的都是图像块,那么命名为tensor
#Normalize,就是对图像进行归一化和方差处理,使得我们处理的图像像素小一点进行训练
train_set=torchvision.datasets.CIFAR10(root='./data',train=True,download=False,transform=transform)
#torchvision中会有很多数据集合,可以选择使用和下载,transform就是对图像进行处理,此时图像还是一张张图像,不过是像数值是归一化像数值
train_loader=torch.utils.data.Dataloader(train_set,batch_size=36,shuffle=True,num_workers=0)
#torch.utils.data.Dataloder就是为了适用深度网络而采取的,将数据进行处理成批次的数据。
val_set=torchvision.datasets.CIFAR10(root='./data',train=False,download=True,transform=transform)
val_loader=torch.utils.data.Dataloder(val_set,batch_size=5000,shuffle=False,num_workers=0)
val_data_iter=iter(val_loader)
#将数据装入迭代器中
val_image,val_label=val_data_iter.next()
net=LeNet()
loss_function=nn.CrossEntropyLoss()
#目前已经定义好了数据和模型 损失函数
optimizer=optim.Adam(net.parameters(),lr=0.001)
#只是用优化器所以要告诉优化器要优化的参数信息
#接下来重头戏就是开始训练
for epoch in range(5):
running_loss=0.0
for step,data in enumerate(train_loader,start=0):
#使用enumeterate之后就将数据迭代的进行训练,每一个批次成为一个step
inputs,labels=data
optimizer.zero_grad()
outputs=net(input)
#前向传播
loss=loss_function(outputs,labels)
#输出与标签进行计算损失值,之后利用优化器根据损失值进行优化网络参数
loss.backward()
optimizer.step()
#优化器更新参数
running_loss+=loss.item()
if step%500==499:
with torch.no_grad():
outputs=net(val_image)
#每间隔500个批次,验证一下
predict_y=torch.max(outputs,dim=1)[1]
accuracy=torch.eq(predict_y,val_label).sum().item()/val_label.size(0)
#对整个测试集进行验证
print('[%d,#5d] train_loss:%.3f test_accuracy:%.3f'%(epoch+1,step+1,running_loss/500,accuracy)
running_loss=0.0
print('Finished Training')
sava_path='./Lenet.pth'
torch.save(net.state_dict(),save_path)
#将训练的模型进行报错,之后在实际应用的时候应用
if __name__=='__main__':
main()
#开启训练
接下来开始测试阶段
predict.py
显而易见我们要导入模型+权重以及相应的验证图像验证奇迹的时候到了
import torch
import torchvision.transform
form PIL import Image
from model import LeNet
def main():
transform=transform.Compose([transform.Resize((32,32)),transforms.ToTensor(),
transform.Normalize((0.5,0.5,05),(0.5,0.5,0.5))])
classes=('plane','car','bird','car','deer')
net=LeNet()
net.load_state_dict(torch.load('LeNet.pth‘))
im=Image.open('1.jpg')
im=transform(im)
im=torch.unsqueeze(im,dim=0)
with torch.no_grad():
outputs=net(im)
predict=torch.max(outputs,dim=1)[1].data.numpy()
print(classes[int(predict)])
if__name__==__main__
main()
其实分析下来还是挺简单的with torch.no_grad(),其实就是不更新的意思,进行神经网络的正向传播。得出的分值,进行取最大值,进行转换成numpy 格式,那样就可以进行相应的数学运算了。
加油!李麦点



