ResNet18识别FashionMNIST数据集

在这里插入图片描述

本文使用18-layer结构

1导入常用的包

import time
import torch
import torchvision.transforms as transforms
import torch.nn as nn
import torchvision
import torch.nn.functional as F

2导入并处理数据

device =torch.device('cuda')

data_tansform={
    'train': transforms.Compose([
                transforms.ToTensor(),
                transforms.Resize((224,224))]
              )
    ,
    'test':transforms.Compose([
        transforms.ToTensor(),
        transforms.Resize((224,224))]
          )
}


train_data=torchvision.datasets.FashionMNIST(root='E:\PycharmProjects\data',train=True,transform=data_tansform['train'])
test_data=torchvision.datasets.FashionMNIST(root='E:\PycharmProjects\data',train=False,transform=data_tansform['test'])
print(len(train_data))
# 60000
batch_size=64
train_iter=torch.utils.data.DataLoader(train_data,batch_size,shuffle=True)
test_iter=torch.utils.data.DataLoader(test_data,batch_size,shuffle=True)

for x,y in train_iter:
    print(x.shape)
    break
# torch.Size([64, 1, 224, 224])

3构造单个残差网络Residual

class Residual(nn.Module):
    def __init__(self,in_channels,out_channels,use_1x1conv=False,stride=1):
        super(Residual, self).__init__()
        self.conv1=nn.Conv2d(in_channels,out_channels,kernel_size=3,padding=1,stride=stride)
        self.conv2=nn.Conv2d(out_channels,out_channels,kernel_size=3,padding=1)
        if use_1x1conv:
            self.conv3=nn.Conv2d(in_channels,out_channels,kernel_size=1,stride=stride)
        else :
            self.conv3=None
        self.bn1=nn.BatchNorm2d(out_channels)
        self.bn2=nn.BatchNorm2d(out_channels)

    def forward(self,x):
        y=F.relu(self.bn1(self.conv1(x)))
        y=self.bn2(self.conv2(y))
        if self.conv3:
            x=self.conv3(x)
        return F.relu(y+x)

4构造残差块

def resnet_block(in_channel,out_channel,num_residuals,first_block=False):
    if first_block:
        assert in_channel == out_channel
    blk =[]
    for i in range(num_residuals):
        if i==0 and not first_block:
            blk.append(Residual(in_channel,out_channel,use_1x1conv=True,stride=2))
        else :
            blk.append(Residual(out_channel,out_channel))
    return nn.Sequential(*blk)

5构造ResNet

net = nn.Sequential(
        nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),
        nn.BatchNorm2d(64),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
)

net.add_module("resnet_block1", resnet_block(64, 64, 2, first_block=True))
net.add_module("resnet_block2", resnet_block(64, 128, 2))
net.add_module("resnet_block3", resnet_block(128, 256, 2))
net.add_module("resnet_block4", resnet_block(256, 512, 2))

class GlobalAvgPool2d(nn.Module):
    # 全局平均池化层可通过将池化窗口形状设置成输入的高和宽实现
    def __init__(self):
        super(GlobalAvgPool2d, self).__init__()
    def forward(self, x):
        return F.avg_pool2d(x, kernel_size=x.size()[2:])



net.add_module("global_avg_pool", GlobalAvgPool2d()) # GlobalAvgPool2d的输出: (Batch, 512, 1, 1)
net.add_module("fc", nn.Sequential(torch.nn.Flatten(), nn.Linear(512, 10)))

6训练网络


def evaluate_accuracy(data_iter,net):
    with torch.no_grad():
        acc_sum,n=0.0,0
        net.eval()
        for x,y in data_iter:
            acc_sum += (net(x.to(device)).argmax(dim=1)==y.to(device)).float().sum().item()
            n+=len(y)
        net.train()
    return acc_sum / n


net=net.to(device)
Loss=nn.CrossEntropyLoss()
optimizer=torch.optim.Adam(net.parameters())
for epoch in range(1):
    acc_train,acc_test,loss=0.0,0.0,0.0
    start=time.time()
    n=0
    for x,y in train_iter:
        x=x.to(device)
        y=y.to(device)
        y_hat=net(x)
        loss=Loss(y_hat,y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    acc_train=evaluate_accuracy(train_iter,net)
    acc_test=evaluate_accuracy(test_iter,net)
    print('loss=%.4f, acc_train=%.4f, acc_test=%.4f, time=%.3f' % (loss.cpu(),acc_train,acc_test,time.time()-start))

loss=0.3769, acc_train=0.8844, acc_test=0.8757, time=327.016

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lins H

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值