Pytorch框架,ResNet50,猫狗分类

直接上程序

network.py

#神经网络
import torch
import torch.nn as nn
from torch.autograd import Variable

class convolutional_block(nn.Module):#convolutional_block层
    def __init__(self,cn_input,cn_middle,cn_output,s=2):
        super(convolutional_block,self).__init__()
        self.step1=nn.Sequential(nn.Conv2d(cn_input,cn_middle,(1,1),(s,s),padding=0,bias=False),nn.BatchNorm2d(cn_middle,affine=False),nn.ReLU(inplace=True),
                            nn.Conv2d(cn_middle,cn_middle,(3,3),(1,1),padding=(1,1),bias=False),nn.BatchNorm2d(cn_middle,affine=False),nn.ReLU(inplace=True),
                            nn.Conv2d(cn_middle,cn_output,(1,1),(1,1),padding=0,bias=False),nn.BatchNorm2d(cn_output,affine=False))
        self.step2=nn.Sequential(nn.Conv2d(cn_input,cn_output,(1,1),(s,s),padding=0,bias=False),nn.BatchNorm2d(cn_output,affine=False))
        self.relu=nn.ReLU(inplace=True)
        
    def forward(self,x):
        x_tmp=x
        x=self.step1(x)
        x_tmp=self.step2(x_tmp)
        x=x+x_tmp
        x=self.relu(x)
        return x

class identity_block(nn.Module):#identity_block层
    def __init__(self,cn,cn_middle):
        super(identity_block,self).__init__()
        self.step=nn.Sequential(nn.Conv2d(cn,cn_middle,(1,1),(1,1),padding=0,bias=False),nn.BatchNorm2d(cn_middle,affine=False),nn.ReLU(inplace=True),
                            nn.Conv2d(cn_middle,cn_middle,(3,3),(1,1),padding=1,bias=False),nn.BatchNorm2d(cn_middle,affine=False),nn.ReLU(inplace=True),
                            nn.Conv2d(cn_middle,cn,(1,1),(1,1),padding=0,bias=False),nn.BatchNorm2d(cn,affine=False))
        self.relu=nn.ReLU(inplace=True)
    def forward(self,x):
        x_tmp=x
        x=self.step(x)
        x=x+x_tmp
        x=self.relu(x)
        return x


class Resnet(nn.Module):#主层
    def __init__(self,c_block,i_block):
        super(Resnet,self).__init__()
        self.conv=nn.Sequential(nn.Conv2d(3,64,(7,7),(2,2),padding=(3,3),bias=False),nn.BatchNorm2d(64,affine=False),nn.ReLU(inplace=True),nn.MaxPool2d((3,3),2,1))      
        self.layer1=c_block(64,64,256,1)
        self.layer2=i_block(256,64)
        self.layer3=c_block(256,128,512)
        self.layer4=i_block(512,128)
        self.layer5=c_block(512,256,1024)
        self.layer6=i_block(1024,256)
        self.layer7=c_block(1024,512,2048)
        self.layer8=i_block(2048,512)
        self.out=nn.Linear(2048,2,bias=False)
        self.avgpool=nn.AvgPool2d(7,7)
        

    def forward(self,input):
        x=self.conv(input)
        x=self.layer1(x)
        for i in range(2):            
            x=self.layer2(x)
        x=self.layer3(x)
        for i in range(3):
            x=self.layer4(x)
        x=self.layer5(x)
        for i in range(5):
            x=self.layer6(x)
        x=self.layer7(x)
        for i in range(2):
            x=self.layer8(x)
                            

        x=self.avgpool(x)
        x=x.view(x.size(0),-1)
        output=self.out(x)
        return output

net=Resnet(convolutional_block,identity_block).cuda()

main.py

#主程序
import numpy as np
import random
import os
import torch
import torchvision
from torchvision import datasets,transforms
import network
from PIL import Image
from torch.autograd import Variable
import torch.nn as nn
import time

def data_load(dir,batch,a=0,b=0,c=0):#读取图片文件
    normalize = transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
    transform = transforms.Compose([
        transforms.Resize(size=(224, 224)),
        transforms.RandomRotation(a),#旋转,增加训练样本数量
        transforms.RandomHorizontalFlip(b),#水平翻转,增加训练样本数量
        transforms.RandomVerticalFlip(c),#垂直翻转,增加训练样本数量
        transforms.ToTensor(),
        normalize
    ])
    train_dataset = torchvision.datasets.ImageFolder(root=dir,transform=transform)
    train_loader = torch.utils.data.DataLoader(train_dataset,batch_size=batch,shuffle=True)
    return train_loader



def train(optimizer):
    loss_function=nn.CrossEntropyLoss().cuda()
    time1=time.time()
    epco=2
    batch=16
    miss=0
    add=0
    loss_all=0
    loss_down=0
    loss_add=0
    train_pic=0
    train_loader=data_load(dir="train",batch=16,a=90,b=0.5,c=0.5)
    if train_pic>0:
        print(train_pic)
    else:
        print(str(len(train_loader)*epco))
    for e in range(epco):     
        z=[]
        x=[]
        for i,(images,labels) in enumerate(train_loader):           
            x=Variable(images.cuda())
            z=Variable(labels.cuda())
            out=network.net.forward(x)      
            loss=loss_function(out,z)
            optimizer.zero_grad()
            loss.backward()     
            optimizer.step()
            out=network.net.forward(x)
            loss1=loss_function(out,z)
            loss_all+=loss.item()
            loss_down+=(loss.item()-loss1.item())
            if loss1>loss:
                loss_add=(loss1.item()-loss.item())
                add+=1
            if loss>=0.5/batch:
                print(loss1)
                print("===="+str(loss))
                miss+=1
                print("----------------------------------------------------------")
            if (i+1)%100==0:
                if train_pic>0:
                    print(str((e*train_pic+i+1)/(epco*train_pic)*100)+"%")
                else:
                    print(str((e*len(train_loader)+i+1)/(epco*len(train_loader))*100)+"%")
            if i%3000==0 and i!=0:
                state = {"net":network.net.state_dict(), "optimizer":optimizer.state_dict()}
                torch.save(state,"net.pth")
            if train_pic>0 and i>=train_pic:
                break
    #下面是一些监控输出,可以不用管
    print("add="+str(add))
    if train_pic>0:
        print("acc="+str((epco*train_pic-miss)/(epco*train_pic)*100)+"%")
        print("avgloss="+str(loss_all/(epco*train_pic)))
        print("avgloss_down="+str(loss_down/(epco*train_pic)))
    else:
        print("acc="+str((epco*len(train_loader)-miss)/(epco*len(train_loader))*100)+"%")
        print("avgloss="+str(loss_all/(epco*len(train_loader))))
        print("avgloss_down="+str(loss_down/(epco*len(train_loader))))
    if add>0:
        print("avgloss_add="+str(loss_add/add))
    print(str(time.time()-time1)+"秒")
    #保存参数和模型
    state = {"net":network.net.state_dict(), "optimizer":optimizer.state_dict()}
    torch.save(state,"net.pth")

def test():#单张测试
    train_loader=data_load(dir="test",batch=1)
    for i,(images,labels) in enumerate(train_loader):
        x=Variable(images.cuda())
        z=Variable(labels.cuda())
        out=network.net.forward(x)
        print(z)
        print(out)
        break
    if out.argmax()==z:
        print("正确")
    else:
        print("错误")

def acc(s):#多张测试,分成训练集和验证集
    if s==0:
        dir="train"
        type="训练集"
    else:
        dir="test"
        type="验证集"
    train_loader=data_load(dir,batch=1)
    corret=0
    all=300
    if all>len(train_loader):
        all=len(train_loader)
    for i,(images,labels) in enumerate(train_loader):
        x=Variable(images.cuda())
        z=Variable(labels.cuda())
        out=network.net.forward(x)
        if out.argmax()==z:
            corret+=1
        if i>=all:
            break
    print(type+"正确率:==============================================================================="+str(corret/all*100)+"%")

while True:
    rate=0.0001
    optimizer=torch.optim.Adam(network.net.parameters())
    if not os.path.exists("net.pth"):
        state = {"net":network.net.state_dict(), "optimizer":optimizer.state_dict()}
        torch.save(state,"net.pth")     
    else:
        checkpoint = torch.load("net.pth")
        network.net.load_state_dict(checkpoint["net"])
        optimizer.load_state_dict(checkpoint["optimizer"])
    optimizer=torch.optim.Adam(network.net.parameters(),rate)
    s=input("1:训练   2:分析   3:正确率(300张)   0:退出:")
    while s!="1" and s!="2" and s!="3" and  s!="0":
        s=input("输入错误,重新输入:1:训练   2:分析   3:正确率(300张)   0:退出:")
    if s=="1":
        train(optimizer)
    elif s=="2":
        test()
    elif s=="3":
        acc(0)
        acc(1)
    elif s=="0":
        break

文件夹,包括train,test,里面分别包括cat,dog两个文件夹,train里cat,dog各11000张,test里cat,dog各1500张

实测不加
transforms.RandomRotation()
transforms.RandomHorizontalFlip()
transforms.RandomVerticalFlip()
5轮后(epco=5),训练集和验证集都能打到95%左右

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值