栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

计算机视觉篇---图像分类实战+理论讲解(1)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

计算机视觉篇---图像分类实战+理论讲解(1)

LeNet 入门 构建模型

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 格式,那样就可以进行相应的数学运算了。
加油!李麦点

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/630958.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号