使用resnet进行cifar的分类

图像着增强的方法主要有:

Torchvision.transforms:

1,scale:对图像的尺度进行缩小和放大

2,centercrop:对图像的正中心给定大小的进行裁剪

3,randomcrop:对图片进行给定大小的随机裁剪

4,randomhorizaontaflip:对图片进行概率为0.5的随机水平翻转

5,randomsizecrop:首先对图片进行随机水平的裁剪,然后对裁剪的图片进行一个随机比例的缩放,最后将图片变成给定大小

6,pad:对图片进行边界0填充

图像增强的方法一般是这样的:

data_tf=transforms.Compose([
transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))])
  • cifar10
  • 是一种60000张图片,每张图片的大小是32*32的三通道彩色图,一共是10类别,每种类别是6000张图片。

最初的通道数取决于图片的channel。卷积完成后的输出通道,取决于卷积核的通道数,卷积核的输入通道就是上上一次卷积的输出通道数。1*1 卷积可以降维就是这么计算的:

假设输入的是28*28*192的图片:左边的计算就是: 卷 积 核 参 数 为1×1×192×64+3×3×192×128+5×5×192×32(3a 模块中 1×1 卷积通道为 64,3×3 卷 积 通 道 为128, 5×5 卷 积 通 道 为 32 )

对 3×3 和 5×5 卷积层前分别加入了通道数为96 和 16 的 1×1 卷积层

右边的是:1×1×192×64+(1×1×192×96+3×3×96×128)+(1×1×192×16+5×5×16×32)

  • batch_size,iteration,epoch之间的关系

(1)iteration:表示1次迭代,每次迭代更新1次网络结构的参数,1个iteration等于使用batchsize个样本训练一次;
(2)batch_size:批大小,即1次迭代所使用的样本量。在深度学习中,一般采用SGD训练,即每次训练在训练集中取batchsize个样本训练;
(3)epoch:1个epoch等于使用训练集中的全部样本训练一次。

举个栗子,定义10000次迭代为1个epoch,若每次迭代的batch_size设为256,那么1个epoch相当于过了2560000个训练样本。再举个栗子,训练集有1000个样本,batchsize=10,那么训练完整个样本集需要100次iteration,1次epoch。

#导入必要的包
import sys
sys.path.append('..')

import numpy as np
import torch
from torch import nn
import torch.nn.functional as F
from torch.autograd import Variable
from torchvision.datasets import CIFAR10
#定义基本层
def conv3x3(in_channel, out_channel, stride=1):
    return nn.Conv2d(in_channel, out_channel, 3, stride=stride, padding=1, bias=False)
#定义残差层
class residual_block(nn.Module):
    def __init__(self, in_channel, out_channel, same_shape=True):
        super(residual_block, self).__init__()
        self.same_shape = same_shape
        stride=1 if self.same_shape else 2
        
        self.conv1 = conv3x3(in_channel, out_channel, stride=stride)
        self.bn1 = nn.BatchNorm2d(out_channel)
        
        self.conv2 = conv3x3(out_channel, out_channel)
        self.bn2 = nn.BatchNorm2d(out_channel)
        if not self.same_shape:
            self.conv3 = nn.Conv2d(in_channel, out_channel, 1, stride=stride)
        
    def forward(self, x):
        out = self.conv1(x)
        out = F.relu(self.bn1(out), True)
        out = self.conv2(out)
        out = F.relu(self.bn2(out), True)
        
        if not self.same_shape:
            x = self.conv3(x)
        return F.relu(x+out, True)
#训练
import torch
from torch.autograd import Variable
import numpy as np
import matplotlib.pyplot as plt
import argparse
from torch import nn,optim
from torch.utils.data import DataLoader
from torchvision import datasets,transforms
#定义一些超参数
batch_size=32
learning_rate=1e-2
num_epoches=200
#预处理
#data_tf=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
#data_tf=transforms.Compose([transforms.RandomHorizontalFlip(),
                            #transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
data_tf=transforms.Compose([
transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))])

    

#将图像转化成tensor,然后继续标准化,就是减均值,除以方差

#读取数据集
train_dataset=datasets.CIFAR10(root='./data1',train=True,transform=data_tf,download=True)
test_dataset=datasets.CIFAR10(root='./data1',train=False,transform=data_tf)
#使用内置的函数导入数据集
train_loader=DataLoader(train_dataset,batch_size=batch_size,shuffle=True)
test_loader=DataLoader(test_dataset,batch_size=batch_size,shuffle=False)

#导入网络,定义损失函数和优化方法
#model=Lenet()
#model=CNN()
model=resnet(3,10)
if torch.cuda.is_available():#是否使用cuda加速
    model=model.cuda()
criterion=nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=learning_rate)
n_epochs=50
for epoch in range(n_epochs):
    total=0
    running_loss=0.0
    running_correct=0
    print("epoch {}/{}".format(epoch,n_epochs))
    print("-"*100)
    for data in train_loader:
        img,label=data
        #img=img.view(img.size(0),-1)
        img = Variable(img)
        if torch.cuda.is_available():
            img=img.cuda()
            label=label.cuda()
        else:
            img=Variable(img)
            label=Variable(label)
        out=model(img)#得到前向传播的结果
        loss=criterion(out,label)#得到损失函数
        print_loss=loss.data.item()
        optimizer.zero_grad()#归0梯度
        loss.backward()#反向传播
        optimizer.step()#优化
        running_loss+=loss.item()
        epoch+=1
        if epoch%50==0:
            print('epoch:{},loss:{:.4f}'.format(epoch,loss.data.item()))
    _, predicted = torch.max(out.data, 1)
    total += label.size(0)
    running_correct += (predicted == label).sum()
    print('第%d个epoch的识别准确率为:%d%%' % (epoch + 1, (100 * running_correct / total)))

 

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值