VGG16的模型



首先我们可以看到VGG一共有六个模型,每个模型根据卷积层和全连接层的层数进行分类,第二张图就是VGG16的基本模型.

代码实现

Vgg16Net.py

from torch import nnclass Vgg16_net(nn.Module):def __init__(self):super(Vgg16_net, self).__init__()self.layer1=nn.Sequential(nn.Conv2d(in_channels=3,out_channels=64,kernel_size=3,stride=1,padding=1), #(32-3+2)/1+1=32   32*32*64nn.BatchNorm2d(64),#inplace-选择是否进行覆盖运算#意思是是否将计算得到的值覆盖之前的值,比如nn.ReLU(inplace=True),#意思就是对从上层网络Conv2d中传递下来的tensor直接进行修改,#这样能够节省运算内存,不用多存储其他变量nn.Conv2d(in_channels=64,out_channels=64,kernel_size=3,stride=1,padding=1), #(32-3+2)/1+1=32    32*32*64#Batch Normalization强行将数据拉回到均值为0,方差为1的正太分布上,# 一方面使得数据分布一致,另一方面避免梯度消失。nn.BatchNorm2d(64),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=2,stride=2)   #(32-2)/2+1=16         16*16*64)self.layer2=nn.Sequential(nn.Conv2d(in_channels=64,out_channels=128,kernel_size=3,stride=1,padding=1),  #(16-3+2)/1+1=16  16*16*128nn.BatchNorm2d(128),nn.ReLU(inplace=True),nn.Conv2d(in_channels=128,out_channels=128,kernel_size=3,stride=1,padding=1), #(16-3+2)/1+1=16   16*16*128nn.BatchNorm2d(128),nn.ReLU(inplace=True),nn.MaxPool2d(2,2)    #(16-2)/2+1=8     8*8*128)self.layer3=nn.Sequential(nn.Conv2d(in_channels=128,out_channels=256,kernel_size=3,stride=1,padding=1),  #(8-3+2)/1+1=8   8*8*256nn.BatchNorm2d(256),nn.ReLU(inplace=True),nn.Conv2d(in_channels=256,out_channels=256,kernel_size=3,stride=1,padding=1),  #(8-3+2)/1+1=8   8*8*256nn.BatchNorm2d(256),nn.ReLU(inplace=True),nn.Conv2d(in_channels=256,out_channels=256,kernel_size=3,stride=1,padding=1),  #(8-3+2)/1+1=8   8*8*256nn.BatchNorm2d(256),nn.ReLU(inplace=True),nn.MaxPool2d(2,2)     #(8-2)/2+1=4      4*4*256)self.layer4=nn.Sequential(nn.Conv2d(in_channels=256,out_channels=512,kernel_size=3,stride=1,padding=1),  #(4-3+2)/1+1=4    4*4*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),   #(4-3+2)/1+1=4    4*4*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),   #(4-3+2)/1+1=4    4*4*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.MaxPool2d(2,2)    #(4-2)/2+1=2     2*2*512)self.layer5=nn.Sequential(nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),   #(2-3+2)/1+1=2    2*2*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),  #(2-3+2)/1+1=2     2*2*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),  #(2-3+2)/1+1=2      2*2*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.MaxPool2d(2,2)   #(2-2)/2+1=1      1*1*512)self.conv=nn.Sequential(self.layer1,self.layer2,self.layer3,self.layer4,self.layer5)self.fc=nn.Sequential(#y=xA^T+b  x是输入,A是权值,b是偏执,y是输出#nn.Liner(in_features,out_features,bias)#in_features:输入x的列数  输入数据:[batchsize,in_features]#out_freatures:线性变换后输出的y的列数,输出数据的大小是:[batchsize,out_features]#bias: bool  默认为True#线性变换不改变输入矩阵x的行数,仅改变列数nn.Linear(512,512),nn.ReLU(inplace=True),nn.Dropout(0.5),nn.Linear(512,256),nn.ReLU(inplace=True),nn.Dropout(0.5),nn.Linear(256,10))def forward(self,x):x=self.conv(x)#这里-1表示一个不确定的数,就是你如果不确定你想要reshape成几行,但是你很肯定要reshape成512列# 那不确定的地方就可以写成-1#如果出现x.size(0)表示的是batchsize的值# x=x.view(x.size(0),-1)x = x.view(-1, 512)x=self.fc(x)return x

train.py

import torch
from torch import nn,optim,tensor
from torch.utils.data import DataLoader
from torchvision.utils import  make_grid
from torchvision import datasets,transforms
import numpy as np
from matplotlib import pyplot as plt
import time#全局变量
batch_size=32   #每次喂入的数据量# num_print=int(50000//batch_size//4)
num_print=100epoch_num=30 #总迭代次数lr=0.01
step_size=10  #每n次epoch更新一次学习率#数据获取(数据增强,归一化)
def transforms_RandomHorizontalFlip():#transforms.Compose(),将一系列的transforms有序组合,实现按照这些方法依次对图像操作#ToTensor()使图片数据转换为tensor张量,这个过程包含了归一化,图像数据从0~255压缩到0~1,这个函数必须在Normalize之前使用#实现原理,即针对不同类型进行处理,原理即各值除以255,最后通过torch.from_numpy将PIL Image或者 numpy.ndarray()针对具体类型转成torch.tensor()数据类型#Normalize()是归一化过程,ToTensor()的作用是将图像数据转换为(0,1)之间的张量,Normalize()则使用公式(x-mean)/std#将每个元素分布到(-1,1). 归一化后数据转为标准格式,transform_train=transforms.Compose([transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize((0.485,0.456,0.406),(0.229,0.224,0.225))])transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.485,0.456,0.406),(0.226,0.224,0.225))])#root:cifar-10 的根目录,data_path#train:True=训练集, False=测试集#transform:(可调用,可选)-接收PIL图像并返回转换版本的函数#download:true=从互联网上下载数据,并将其放在root目录下,如果数据集已经下载,就什么都不干train_dataset=datasets.CIFAR10(root='../../data_hub/cifar10/data_1',train=True,transform=transform_train,download=True)test_dataset=datasets.CIFAR10(root='../../data_hub/cifar10/data_1',train=False,transform=transform,download=True)return train_dataset,test_dataset#数据增强:随机翻转
train_dataset,test_dataset=transforms_RandomHorizontalFlip()'''
#Dataloader(....)
dataset:就是pytorch已有的数据读取接口,或者自定义的数据接口的输出,该输出要么是torch.utils.data.Dataset类的对象,要么是继承自torch.utils.data.Dataset类的自定义类的对象batch_size:如果有50000张训练集,则相当于把训练集平均分成(50000/batch_size)份,每份batch_size张图片
train_loader中的每个元素相当于一个分组,一个组中batch_size图片,shuffle:设置为True时会在每个epoch重新打乱数据(默认:False),一般在训练数据中会采用
num_workers:这个参数必须>=0,0的话表示数据导入在主进程中进行,其他大于0的数表示通过多个进程来导入数据,可以加快数据导入速度
drop_last:设定为True如果数据集大小不能被批量大小整除的时候,将丢到最后一个不完整的batch(默认为False)
'''train_loader=DataLoader(train_dataset,batch_size=batch_size,shuffle=True)
test_loader=DataLoader(test_dataset,batch_size=batch_size,shuffle=False)#模型,优化器
device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
from VggNet import *
model=Vgg16_net().to(device)#在多分类情况下一般使用交叉熵
criterion=nn.CrossEntropyLoss()
'''
params(iterable)-待优化参数的iterable或者定义了参数组的dict
lr(float):学习率momentum(float)-动量因子weight_decay(float):权重衰减,使用的目的是防止过拟合.在损失函数中,weight decay是放在正则项前面的一个系数,正则项一般指示模型的复杂度
所以weight decay的作用是调节模型复杂度对损失函数的影响,若weight decay很大,则复杂的模型损失函数的值也就大.dampening:动量的有抑制因子optimizer.param_group:是长度为2的list,其中的元素是两个字典
optimzer.param_group:长度为6的字典,包括['amsgrad','params','lr','weight_decay',eps']
optimzer.param_group:表示优化器状态的一个字典'''
optimizer=optim.SGD(model.parameters(),lr=lr,momentum=0.8,weight_decay=0.001)'''
scheduler 就是为了调整学习率设置的,我这里设置的gamma衰减率为0.5,step_size为10,也就是每10个epoch将学习率衰减至原来的0.5倍。optimizer(Optimizer):要更改学习率的优化器
milestones(list):递增的list,存放要更新的lr的epoch
gamma:(float):更新lr的乘法因子
last_epoch::最后一个epoch的index,如果是训练了很多个epoch后中断了,继续训练,这个值就等于加载的模型的epoch。默认为-1表示从头开始训练,即从epoch=1
'''schedule=optim.lr_scheduler.StepLR(optimizer,step_size=step_size,gamma=0.5,last_epoch=-1)#训练
loss_list=[]  #为了后续画出损失图
start=time.time()#train
for epoch in range(epoch_num):ww = 0running_loss=0.0#0是对i的给值(循环次数从0开始技术还是从1开始计数的问题):#???for i,(inputs,labels) in enumerate(train_loader,0):#将数据从train_loader中读出来,一次读取的样本是32个inputs,labels=inputs.to(device),labels.to(device)#用于梯度清零,在每次应用新的梯度时,要把原来的梯度清零,否则梯度会累加optimizer.zero_grad()outputs = model(inputs)loss=criterion(outputs,labels).to(device)#反向传播,pytorch会自动计算反向传播的值loss.backward()#对反向传播以后对目标函数进行优化optimizer.step()running_loss+=loss.item()loss_list.append(loss.item())if(i+1)%num_print==0:print('[%d epoch,%d]  loss:%.6f' %(epoch+1,i+1,running_loss/num_print))running_loss=0.0lr_1=optimizer.param_groups[0]['lr']print("learn_rate:%.15f"%lr_1)schedule.step()end=time.time()
print("time:{}".format(end-start))#测试#由于训练集不需要梯度更新,于是进入测试模式
model.eval()
correct=0.0
total=0
with torch.no_grad(): #训练集不需要反向传播print("=======================test=======================")for inputs,labels in test_loader:inputs,labels=inputs.to(device),labels.to(device)outputs=model(inputs)pred=outputs.argmax(dim=1)  #返回每一行中最大值元素索引total+=inputs.size(0)correct+=torch.eq(pred,labels).sum().item()print("Accuracy of the network on the 10000 test images:%.2f %%" %(100*correct/total) )
print("===============================================")

训练结果

...
...[30 epoch,1200]  loss:0.064114
[30 epoch,1300]  loss:0.046721
[30 epoch,1400]  loss:0.070694
[30 epoch,1500]  loss:0.078124
learn_rate:0.002500000000000
time:1579.1085803508759
=======================test=======================
Accuracy of the network on the 10000 test images:87.97 %
===============================================

文章参考自:https://blog.csdn.net/weixin_43467711/article/details/105377584

使用pytorch实现VGG16模型(小白学习,详细注释)相关推荐

  1. 图注意网络GAT理解及Pytorch代码实现【PyGAT代码详细注释】

    文章目录 GAT 代码实现[PyGAT] GraphAttentionLayer[一个图注意力层实现] 用上面实现的单层网络测试 加入Multi-head机制的GAT 对数据集Cora的处理 csr_ ...

  2. CSS盒子模型-小白学习中

    CSS盒子模型 一.盒子模型的概念 一个独立的盒子模型由内容.边框(border).内边距(padding)和外边距(margin)4部分组成. 1.border是设定边框线条,盒子的其他部分是相对b ...

  3. 小白学习pytorch源码(二):setup.py最详细解读

    小白学习pytorch源码(二) pytorch setup.py最全解析 setup.py与setuptools setup.py最详细解读 setup.py 环境检查 setup.py setup ...

  4. 【小白学PyTorch】6.模型的构建访问遍历存储(附代码)

    <<小白学PyTorch>> 小白学PyTorch | 5 torchvision预训练模型与数据集全览 小白学PyTorch | 4 构建模型三要素与权重初始化 小白学PyT ...

  5. 断点续训 Pytorch 和 Tensorflow 框架 VGG16 模型 猫狗大战 鸢尾花分类

    神经网络训练模型的过程中,如果程序突然中断,竹篮打水一场空? >>>断点续训来解决! 目录 (1)Pytorch框架的断点续训(猫狗大战) (2)Tensorflow框架的断点续训( ...

  6. 小白学习freemark的过程(代码全贴+详细介绍)

    介绍 FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写 FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序 环境 学习工具 ...

  7. 视频教程-小白学习课程:梯度下降算法与公式详细推导-深度学习

    小白学习课程:梯度下降算法与公式详细推导 国内"双一流"大学博士研究生,计算机专业,研究方向和兴趣包括人工智能,深度学习,计算机视觉,群体智能算法,元胞自动机等,愿意分享自己的技术 ...

  8. 【小白学习PyTorch教程】八、使用图像数据增强手段,提升CIFAR-10 数据集精确度...

    「@Author:Runsen」 上次基于CIFAR-10 数据集,使用PyTorch构建图像分类模型的精确度是60%,对于如何提升精确度,方法就是常见的transforms图像数据增强手段. imp ...

  9. linux caffe生成的模型,深度学习之pytorch转caffe转ncnn模型转换(三)

    搭建caffe平台: 先在Linux系统下搭建caffe环境,安装依赖包: sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy- ...

最新文章

  1. git 比较两个版本之间的区别
  2. webservice python开发接口_基于Python的Webservice开发(四)-泛微OA的SOAP接口
  3. 【Tomcat】安装Tomcat服务器Tomcat的目录结构
  4. 【蓝桥杯】历届试题 分糖果
  5. Mac上Spotify 音乐添加到 djay Pro的详细教程
  6. mysql vc运行库,VC运行库版本 - robslove的个人页面 - OSCHINA - 中文开源技术交流社区...
  7. Pyspark:电影推荐
  8. ToStringBuilder学习总结
  9. IT前沿技术之node.js篇一:Node.js与javascript
  10. OSChina 周四乱弹 —— 开个程序门诊?
  11. Python原生服务端签名生成请求订单信息「orderString」
  12. 茶馆人物表(按字母顺序)
  13. 软件测试面试题避雷(HR面试题)最常见的面试问题和技巧性答复
  14. cuda编程思想和opencv_gpu图像处理
  15. windows10 1909 原版纯净系统分享
  16. debian linux iso下载工具,debian 8.7系统下载
  17. 算法竞赛进阶指南0x10练习7:Corral the Cows
  18. TZ环境变量,时区,夏令时
  19. Android SpannableString详细解析
  20. 使用第三方云通讯平台时,出现{'172001':'网络错误'}解决方法

热门文章

  1. R语言使用skimr包的skim_with函数自定义指定需要查看的统计信息、统计口径、查看dataframe特定数据列的summary信息、统计汇总信息(Specify statistics)
  2. 野小兽是谁?不止是小米领投的家庭健身科技品牌
  3. 墙裂推荐c++的学习网站(OJ)
  4. 个人技术博客--syz
  5. 中兴新支点操作系统的设计和功能怎样?
  6. 限制同一IP一段时间内访问次数
  7. 韩顺平Java:qq项目离线发送接收消息/文件扩展
  8. ubuntu16.04安装MATLAB R2017b过程中遇到的错误
  9. NLP系列:Word2Vec原始论文:Efficient Estimation of Word Representations in Vector Space
  10. 【神经网络】tenorflow实验11--人工神经网络(2)