第P2周:CIFAR10彩色图片识别

  1. 学习如何编写一个完整的深度学习程序
  2. 手动推导卷积层与池化层的计算过程

🔔本次的重点在于学会构建CNN网络

我的环境:在这里插入图片描述
1.代码:
一、 前期准备

  1. 设置GPU

如果设备上支持GPU就使用GPU,否则使用CPU
在这里插入图片描述
2. 导入数据

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

使用dataloader加载数据,并设置好基本的batch_size
在这里插入图片描述
3. 数据可视化

squeeze()函数的功能是从矩阵shape中,去掉维度为1的。例如一个矩阵是的shape是(5, 1),使用过这个函数后,结果为(5, )。
在这里插入图片描述
二、构建简单的CNN网络

对于一般的CNN网络来说,都是由特征提取网络和分类网络构成,其中特征提取网络用于提取图片的特征,分类网络用于将图片进行分类。
在这里插入图片描述
在这里插入图片描述
三、 训练模型

  1. 设置超参数
    在这里插入图片描述
  2. 编写训练函数

在这里插入图片描述
3. 编写测试函数
4.
在这里插入图片描述
四、 结果可视化
在这里插入图片描述
五总结
1.在编写训练和测试的函数那里有两段是自己尝试在去编写,可能会有点乱,不过可以很好的和原代码作为比较,发现自己哪里有问题。
3.对卷积计算的过程有了清晰的了解。N=(W-F+2P)/S+1
2.自己在pycharm上动手写了一下,与源代码不同的是,并没有编写一个训练和测试的函数,而是自己将它作为一部分,放入了epoch循环里面了。附源码。另外还有如何替换自己的数据集源码。

@Time:2024/4/1016:10

#1.设置gpu
import torch
import matplotlib.pyplot as plt
device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)
print(device)

#2.导入数据
import torchvision
train_ds = torchvision.datasets.CIFAR10(‘./data’,train=True,transform=torchvision.transforms.ToTensor(),download=False)
test_ds = torchvision.datasets.CIFAR10(‘./data’,train=False,transform=torchvision.transforms.ToTensor(),download=False)#这个train = False
“”"
import torchvision.transforms as transforms
from torchvision.datasets import ImageFolder
import torch
import os

数据集根目录

dataset_root = ‘./your_dataset_root’

数据预处理

transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

加载数据集

train_dataset = ImageFolder(root=os.path.join(dataset_root, ‘train’), transform=transform)
test_dataset = ImageFolder(root=os.path.join(dataset_root, ‘test’), transform=transform)
“”"

batch_size = 32
train_dl = torch.utils.data.DataLoader(train_ds,batch_size=batch_size,shuffle=True)
test_dl = torch.utils.data.DataLoader(test_ds,batch_size)
imgs,labels = next(iter(train_dl))
print(labels.shape)

import torch.nn.functional as F
import torch.nn as nn
num_classes = 10 # 图片的类别数

class Model(nn.Module):
def init(self):
super().init()
# 特征提取网络
self.conv1 = nn.Conv2d(3, 64, kernel_size=3) # 第一层卷积,卷积核大小为33
self.pool1 = nn.MaxPool2d(kernel_size=2) # 设置池化层,池化核大小为2
2
self.conv2 = nn.Conv2d(64, 64, kernel_size=3) # 第二层卷积,卷积核大小为33
self.pool2 = nn.MaxPool2d(kernel_size=2)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3) # 第二层卷积,卷积核大小为3
3
self.pool3 = nn.MaxPool2d(kernel_size=2)

    # 分类网络
    self.fc1 = nn.Linear(512, 256)
    self.fc2 = nn.Linear(256, 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 = self.fc2(x)

    return x

model = Model().to(device)
loss_fn = nn.CrossEntropyLoss()
learn_rate = 1e-2
opt = torch.optim.SGD(model.parameters(),lr=learn_rate)

#编写训练损失函数

def train(dataloader,model,loss_fn,optimizer):

size = len(dataloader.dataset)

num_batches = len(dataloader)

train_loss,train_acc =0,0

for X,y in dataloader:

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

def test(dataloader, model, loss_fn):

size = len(dataloader.dataset) # 测试集的大小,一共10000张图片

num_batches = len(dataloader) # 批次数目,313(10000/32=312.5,向上取整)

test_loss, test_acc = 0, 0

# 当不进行训练时,停止梯度更新,节省计算内存消耗

with torch.no_grad():

for imgs, target in dataloader:

imgs, target = imgs.to(device), target.to(device)

# 计算loss

target_pred = model(imgs)

loss = loss_fn(target_pred, target)

test_loss += loss.item()

test_acc += (target_pred.argmax(1) == target).type(torch.float).sum().item()

test_acc /= size

test_loss /= num_batches

return test_acc, test_loss

epochs = 3
train_acc=[]
train_loss = []
test_acc= []
test_loss = []
best_accuracy = 0.0 # 初始化最佳准确率为0

for epoch in range(epochs):

model.train()

epoch_train_acc,epoch_train_loss = train(train_dl,model,loss_fn,opt)

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)

template = (‘Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}’)

print(template.format(epoch + 1, epoch_train_acc * 100, epoch_train_loss, epoch_test_acc * 100, epoch_test_loss))

if epoch_test_acc > best_accuracy:

best_accuracy = epoch_test_acc

torch.save(model.state_dict(), ‘best_model.pth’) # 保存当前最佳模型权重

print(‘Best model weights saved successfully.’)

print(‘Done’)

保存模型权重

torch.save(model.state_dict(), ‘model.pth’)

print(‘Model weights saved successfully.’)

for epoch in range(epochs):
train_acc1 =0
train_loss1 =0
for X,y in train_dl:
X,y = X.to(device),y.to(device)
pred = model(X)
loss = loss_fn(pred,y)

    opt.zero_grad()
    loss.backward()
    opt.step()
    train_acc1 +=(pred.argmax(1)==y).type(torch.float).sum().item()
    train_loss1 += loss.item()
train_acc1 /=len(train_dl.dataset)
train_loss1 /= len(train_dl)

train_acc.append(train_acc1)
train_loss.append(train_loss1)
print(f'Epoch:{epoch+1},Train_acc:{train_acc},Tran_loss:{train_loss}')
  • 29
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值