P2:彩色图片识别

>- **🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/AtyZUu_j2k_ScNH6e732ow) 中的学习记录博客**

>- **🍦 参考文章:[365天深度学习训练营-第P2周:彩色识别](https://mp.weixin.qq.com/s/BKsTrlOtu32bQzgORaMLEw)**

>- **🍖 原作者:[K同学啊](https://mtyjkh.blog.csdn.net/)**

目录

一、前期准备

1.1 设置GPU

1.2  导入数据

1.3 数据可视化 

二、构建简单的CNN网络

2.1 torch.nn.Conv2d()

2.2  torch.nn.Linear()

2.3 torch.nn.MaxPool2d() 

2.4 构建模型 

2.5 打印模型参数

 三、训练模型

3.1 设置超参数 

3.2 编写训练函数

3.3 编写测试函数

3.4 训练

四、结果可视化


一、前期准备

1.1 设置GPU

import torch
import torch.nn as nn
import torchvision.transforms as transforms
import  torchvision
import tqdm as tqdm
from torchvision import datasets, models, transforms
import os,PIL,pathlib
import torch.nn.functional as F
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device

 device(type='cuda')

1.2  导入数据

使用dataset下载CIFAR10数据集,并划分好训练集与测试集,使用dataloader加载数据。

train_ds = torchvision.datasets.CIFAR10('data',
                                        train=True,
                                        transform=torchvision.transforms.ToTensor(),
                                        download=True)
test_ds = torchvision.datasets.CIFAR10('data',
                                        train=False,
                                        transform=torchvision.transforms.ToTensor(),
                                        download=True)
batch_size = 32
trian_dl = torch.utils.data.DataLoader(train_ds, batch_size=batch_size, shuffle=True)
test_dl = torch.utils.data.DataLoader(test_ds, batch_size=batch_size, shuffle=False)
imgs ,labels = next(iter(trian_dl))

1.3 数据可视化 

plt.figure(figsize=(20,5))
for i , imgs in enumerate(imgs[:20]):
    npimg = imgs.numpy().transpose((1,2,0))
    plt.subplot(2,10,i+1)
    plt.imshow(npimg,cmap=plt.cm.binary)
    plt.axis('off')

  

二、构建简单的CNN网络

2.1 torch.nn.Conv2d()

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros', device=None, dtype=None)

参数说明: 

in_channels – 输入图像中的通道数
out_channels – 卷积产生的通道数
kernel_size  – 卷积核的大小
stride  – 卷积的步幅。默认值:1
padding  – 添加到输入的所有四个边的填充。默认值:0
dilation  - 扩张操作:控制kernel点(卷积核点)的间距,默认值:1。
padding_mode  – 'zeros', 'reflect', 'replicate'或'circular'. 默认:'zeros'

2.2  torch.nn.Linear()

torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)

2.3 torch.nn.MaxPool2d() 

torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

kernel_size:最大的窗口大小
stride:窗口的步幅,默认值为kernel_size
padding:填充值,默认为0
dilation:控制窗口中元素步幅的参数

2.4 构建模型 

num_classes = 10
class Model(nn.Module):
    def __init__(self):
        super().__init__()

        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)
        self.pool1 = nn.MaxPool2d(kernel_size=2)
        self.conv2 = nn.Conv2d(64, 64, kernel_size=3)
        self.pool2 = nn.MaxPool2d(kernel_size=2)
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3)
        self.pool3 = nn.MaxPool2d(kernel_size=2)

        self.fc1 = nn.Linear(128*2*2, 256)
        self.fc2 = nn.Linear(256, 128)
        self.fc3 = nn.Linear(128, num_classes)
    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.relu(self.conv2(x)))
        x = self.pool3(F.relu(self.conv3(x)))

        x = torch.flatten(x,start_dim=1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)

        return x

2.5 打印模型参数

from torchinfo import summary
model = Model().to(device)
summary(model)

 Model                                            --
├─Conv2d: 1-1                            1,792
├─MaxPool2d: 1-2                         --
├─Conv2d: 1-3                            36,928
├─MaxPool2d: 1-4                         --
├─Conv2d: 1-5                            73,856
├─MaxPool2d: 1-6                         --
├─Linear: 1-7                            131,328
├─Linear: 1-8                            32,896
├─Linear: 1-9                            1,290
=================================================================
Total params: 278,090
Trainable params: 278,090
Non-trainable params: 0
=================================================================

 三、训练模型

3.1 设置超参数 

import tqdm as tqdm
loss_fn = nn.CrossEntropyLoss()
learning_rate = 0.001
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

3.2 编写训练函数

def train(dataloader, model ,loss_fn,optimizer):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    train_loss = 0.0
    train_acc = 0.0
    par = tqdm.tqdm(dataloader)
    for x, y in par:
        x, y = x.to(device), y.to(device)
        pred = model(x)
        loss = loss_fn(pred, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        train_acc += (pred.argmax(1) == y).type(torch.float).sum().item()
        train_loss += loss.item()
    train_acc /= size
    train_loss /= num_batches
    return train_acc, train_loss

3.3 编写测试函数

def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    test_loss = 0.0
    test_acc = 0.0
    par = tqdm.tqdm(dataloader)
    with torch.no_grad():
        for imgs, target in par:
            imgs, target = imgs.to(device), target.to(device)
            pred = model(imgs)
            loss = loss_fn(pred, target)
            test_acc += (pred.argmax(1) == target).type(torch.float).sum().item()
            test_loss += loss.item()
    test_acc /= size
    test_loss /= num_batches
    par.set_description(desc=f'loss={test_loss:.4f} acc={test_acc:.4f}')
    return test_acc, test_loss

3.4 训练

 

epochs = 10
train_loss = []
train_acc = []
test_loss = []
test_acc = []
for epoch in range(epochs):
    model.train()
    epoch_train_acc , epoch_train_loss = train(trian_dl, model, loss_fn, optimizer)
    model.eval()
    epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
    train_acc.append(epoch_train_acc)
    train_loss.append(epoch_train_loss)
    test_acc.append(epoch_test_acc)
    test_loss.append(epoch_test_loss)
    tmp = ('Epoch: {:2d}, Train Loss: {:.4f}, Train Acc: {:.4f}%, Test Loss: {:.4f}, Test Acc: {:.4f}%')
    print(tmp.format(epoch+1, epoch_train_loss, epoch_train_acc*100, epoch_test_loss,epoch_test_acc*100))

Epoch:  1, Train Loss: 1.6013, Train Acc: 40.4180%, Test Loss: 1.3290, Test Acc:51.2500%

Epoch:  2, Train Loss: 1.2079, Train Acc: 56.6840%, Test Loss: 1.1471, Test Acc: 58.6500%

Epoch:  3, Train Loss: 1.0413, Train Acc: 63.1600%, Test Loss: 0.9907, Test Acc: 64.8000%

Epoch:  4, Train Loss: 0.9288, Train Acc: 67.3680%, Test Loss: 0.9407, Test Acc: 66.8700%

Epoch:  5, Train Loss: 0.8405, Train Acc: 70.4920%, Test Loss: 0.9245, Test Acc: 67.6900%

Epoch:  6, Train Loss: 0.7689, Train Acc: 72.8200%, Test Loss: 0.8776, Test Acc: 69.6500%

Epoch:  7, Train Loss: 0.7106, Train Acc: 74.9640%, Test Loss: 0.8722, Test Acc: 70.3700%

Epoch:  8, Train Loss: 0.6574, Train Acc: 76.7360%, Test Loss: 0.9029, Test Acc: 69.3400%

Epoch:  9, Train Loss: 0.6136, Train Acc: 78.2980%, Test Loss: 0.9080, Test Acc: 69.7000%

Epoch: 10, Train Loss: 0.5699, Train Acc: 79.8440%, Test Loss: 0.8913, Test Acc:71.0000%

四、结果可视化

plt.figure(dpi=600)
epochs_range = range(1, epochs+1)
plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值