🍨 本文为[🔗365天深度学习训练营] 中的学习记录博客
一、 前期准备
1. 设置GPU
如果设备上支持GPU就使用GPU,否则使用CPU
import torch
import torch.nn as nn
import pathlib, warnings
from torchvision import transforms, datasets
warnings.filterwarnings("ignore")
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
2.导入数据
import os,PIL,random,pathlib
data_dir = '../J1/bird_photos'
data_dir = pathlib.Path(data_dir)
data_paths = list(data_dir.glob('*'))
classeNames = [str(path).split("/")[-1] for path in data_paths]
print(classeNames)
print(total_data.class_to_idx)
3. 划分数据集
train_size = int(0.8 * len(total_data))
test_size = len(total_data) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])
for X, y in test_dl:
print("Shape of X [N, C, H, W]: ", X.shape)
print("Shape of y: ", y.shape, y.dtype)
break
batch_size = 32
train_dl = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=0)
test_dl = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=True, num_workers=0)
二、搭建模型
1.搭建模型
import torch
import torch.nn as nn
import torch.nn.functional as F
class Block2(nn.Module):
def __init__(self, in_channel, filters, kernel_size=3, stride=1, conv_shortcut=False):
super(Block2, self).__init__()
self.preact = nn.Sequential(
nn.BatchNorm2d(in_channel),
nn.ReLU(inplace=True)
)
self.conv_shortcut = conv_shortcut
if self.conv_shortcut:
self.short = nn.Conv2d(in_channel, 4 * filters, 1, stride=stride, padding=0, bias=False)
elif stride > 1:
self.short = nn.MaxPool2d(kernel_size=1, stride=stride, padding=0)
else:
self.short = nn.Identity()
self.conv1 = nn.Sequential(
nn.Conv2d(in_channel, filters, 1, stride=stride, bias=False),
nn.BatchNorm2d(filters),
nn.ReLU(inplace=True)
)
self.conv2 = nn.Sequential(
nn.Conv2d(filters, filters, kernel_size, stride=1, padding=1, bias=False), # 添加填充以保持尺寸
nn.BatchNorm2d(filters),
nn.ReLU(inplace=True)
)
self.conv3 = nn.Conv2d(filters, 4 * filters, 1, bias=False)
def forward(self, x):
x_short = self.short(self.preact(x)) if self.conv_shortcut else self.short(x)
x = self.conv1(self.preact(x))
x = self.conv2(x)
x = self.conv3(x)
x = x + x_short
return x
class Stack2(nn.Module):
def __init__(self, in_channel, filters, blocks, stride=2):
super(Stack2, self).__init__()
self.conv = nn.Sequential()
self.conv.add_module('block0', Block2(in_channel, filters, conv_shortcut=True, stride=stride))
for i in range(1, blocks - 1):
self.conv.add_module('block' + str(i), Block2(4 * filters, filters))
self.conv.add_module('block' + str(blocks - 1), Block2(4 * filters, filters))
def forward(self, x):
x = self.conv(x)
return x
class ResNet50V2(nn.Module):
def __init__(self, include_top=True, preact=True, use_bias=True, input_shape=[224, 224, 3], classes=1000, pooling=None):
super(ResNet50V2, self).__init__()
self.conv1 = nn.Sequential()
self.conv1.add_module('conv', nn.Conv2d(3, 64, 7, stride=2, padding=3, bias=use_bias, padding_mode='zeros'))
if not preact:
self.conv1.add_module('bn', nn.BatchNorm2d(64))
self.conv1.add_module('relu', nn.ReLU())
self.conv1.add_module('max_pool', nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
self.conv2 = Stack2(64, 64, 3)
self.conv3 = Stack2(256, 128, 4)
self.conv4 = Stack2(51