- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
"""
python =3.12.4
编译器:jupyter notebook
深度学习环境:
pytorch == 2.5.1
pytorchvision == 0.20.1
显卡: NVIDIA GeForce RTX3050 laptop
数据:提供数据
"""
'\npython =3.12.4\n编译器:jupyter notebook\n深度学习环境:\n pytorch == 2.5.1\n pytorchvision == 0.20.1\n显卡: NVIDIA GeForce RTX3050 laptop\n数据:提供数据\n'
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms,datasets
import os,PIL,pathlib,warnings
# 忽略所有警告,偶尔可以用,有时候程序运行错误可能正是因为警告的某部分
warnings.filterwarnings("ignore")
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device
device(type='cpu')
import random
data_dir = "./48-data/"
data_dir = pathlib.Path(data_dir)
data_paths = list(data_dir.glob('*'))
classNames = [str(path).split('\\')[1] for path in data_paths]
classNames # 查看类别名称
['Angelina Jolie', 'Brad Pitt', 'Denzel Washington', 'Hugh Jackman', 'Jennifer Lawrence', 'Johnny Depp', 'Kate Winslet', 'Leonardo DiCaprio', 'Megan Fox', 'Natalie Portman', 'Nicole Kidman', 'Robert Downey Jr', 'Sandra Bullock', 'Scarlett Johansson', 'Tom Cruise', 'Tom Hanks', 'Will Smith']
train_transforms = transforms.Compose([
transforms.Resize([224,224]),# 将图片统一尺寸
transforms.RandomHorizontalFlip(), # 随机水平翻转,提高模型识别能力
transforms.ToTensor(),
transforms.Normalize(
mean=[0.488,0.456,0.406],
std =[0.229,0.224,0.225]
)
]) # 对图片处理方式
total_data = datasets.ImageFolder("./48-data/",transform=train_transforms) # 应用上述处理方式到本地数据
total_data
Dataset ImageFolder
Number of datapoints: 1800
Root location: ./48-data/
StandardTransform
Transform: Compose(
Resize(size=[224, 224], interpolation=bilinear, max_size=None, antialias=True)
RandomHorizontalFlip(p=0.5)
ToTensor()
Normalize(mean=[0.488, 0.456, 0.406], std=[0.229, 0.224, 0.225])
)
total_data.class_to_idx # 将每种数据进行简单离散化,给定一个标号
{'Angelina Jolie': 0,
'Brad Pitt': 1,
'Denzel Washington': 2,
'Hugh Jackman': 3,
'Jennifer Lawrence': 4,
'Johnny Depp': 5,
'Kate Winslet': 6,
'Leonardo DiCaprio': 7,
'Megan Fox': 8,
'Natalie Portman': 9,
'Nicole Kidman': 10,
'Robert Downey Jr': 11,
'Sandra Bullock': 12,
'Scarlett Johansson': 13,
'Tom Cruise': 14,
'Tom Hanks': 15,
'Will Smith': 16}
train_size = int(0.8*len(total_data)) # 80%的数据用于训练
test_size = len(total_data)-train_size
train_dataset,test_dataset = torch.utils.data.random_split(total_data,[train_size,test_size]) # 随机分割数据集
train_dataset,test_dataset
(<torch.utils.data.dataset.Subset at 0x213104cd3a0>,
<torch.utils.data.dataset.Subset at 0x213104ccce0>)
batch_size = 32
train_dl = torch.utils.data.DataLoader(
train_dataset,
batch_size=batch_size,
shuffle=True,
num_workers=1 # 控制多少个子进程加载本地数据
)
test_dl = torch.utils.data.DataLoader(
test_dataset,
batch_size=batch_size,
shuffle=True,
num_workers=1 # 控制多少个子进程加载本地数据
)
# 查看测试集数据类型
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
Shape of X [N,C,H,W]: torch.Size([32, 3, 224, 224])
Shape of y: torch.Size([32]) torch.int64
first_batch = next(iter(train_dl))
first_batch
[tensor([[[[-2.1139, -2.1139, -2.1139, ..., -2.1139, -2.1139, -2.1139],
[-2.0796, -2.0796, -2.0796, ..., -2.1139, -2.1139, -2.1139],
[-2.0625, -2.0625, -2.0796, ..., -2.1139, -2.1139, -2.1139],
...,
[-1.9940, -2.0283, -2.0283, ..., -1.9769, -1.9769, -1.9769],
[-1.9598, -1.9940, -1.9940, ..., -1.9598, -1.9426, -1.9598],
[-1.7543, -2.0111, -1.9598, ..., -1.9598, -1.9598, -1.6858]],
[[-1.9657, -1.9657, -1.9657, ..., -1.9657, -1.9657, -1.9657],
[-1.9307, -1.9307, -1.9307, ..., -1.9657, -1.9657, -1.9657],
[-1.9132, -1.9132, -1.9307, ..., -1.9657, -1.9657, -1.9657],
...,
[-1.8957, -1.9307, -1.9307, ..., -1.8256, -1.8256, -1.8256],
[-1.8431, -1.8957, -1.8957, ..., -1.8081, -1.7906, -1.8081],
[-1.6331, -1.9132, -1.8606, ..., -1.8081, -1.8081, -1.5280]],
[[-1.6127, -1.6127, -1.6127, ..., -1.6127, -1.6127, -1.6127],
[-1.5779, -1.5779, -1.5779, ..., -1.6127, -1.6127, -1.6127],
[-1.5604, -1.5604, -1.5779, ..., -1.6127, -1.6127, -1.6127],
...,
[-1.4907, -1.5256, -1.5256, ..., -1.4384, -1.4384, -1.4384],
[-1.4733, -1.5081, -1.4907, ..., -1.4210, -1.4036, -1.4210],
[-1.2990, -1.5256, -1.4559, ..., -1.4210, -1.4210, -1.1421]]],
[[[-1.4803, -1.4460, -1.3775, ..., 0.2665, 0.3007, 0.3178],
[-1.5145, -1.4803, -1.4118, ..., 0.2151, 0.2322, 0.2493],
[-1.5316, -1.4974, -1.4289, ..., 0.1808, 0.1808, 0.2151],
...,
[-1.8056, -1.8056, -1.8056, ..., -1.9426, -1.9426, -1.9426],
[-1.7714, -1.8056, -1.7714, ..., -1.9598, -1.9598, -1.9255],
[-1.5488, -1.8056, -1.8228, ..., -1.9598, -1.9598, -1.6858]],
[[-1.1078, -1.0728, -1.0203, ..., -0.4601, -0.4426, -0.4426],
[-1.1078, -1.0553, -1.0203, ..., -0.5126, -0.5126, -0.5126],
[-1.0378, -1.0203, -0.9853, ..., -0.5476, -0.5476, -0.5476],
...,
[-1.5455, -1.5455, -1.5280, ..., -1.8606, -1.8606, -1.8606],
[-1.5105, -1.5455, -1.5105, ..., -1.8606, -1.8606, -1.8256],
[-1.2829, -1.5455, -1.5630, ..., -1.8606, -1.8606, -1.5805]],
[[-0.8110, -0.8284, -0.8633, ..., -0.8807, -0.8981, -0.8981],
[-0.8633, -0.8807, -0.8981, ..., -0.9330, -0.9678, -0.9678],
[-0.9156, -0.9156, -0.8981, ..., -0.9678, -1.0027, -1.0027],
...,
[-1.1944, -1.1944, -1.1944, ..., -1.7173, -1.7173, -1.7173],
[-1.1596, -1.1944, -1.1596, ..., -1.6650, -1.6824, -1.6476],
[-0.9330, -1.1944, -1.2119, ..., -1.6650, -1.6650, -1.3861]]],
[[[ 0.0438, 0.0438, 0.0438, ..., 0.0438, 0.0267, -0.0075],
[ 0.0267, 0.0267, 0.0267, ..., 0.0267, 0.0267, 0.0096],
[ 0.0096, 0.0096, 0.0096, ..., 0.0096, 0.0096, 0.0267],
...,
[-1.6173, -1.6173, -1.6173, ..., -1.4289, -1.5145, -1.5659],
[-1.5145, -1.5488, -1.5830, ..., -1.5316, -1.5316, -1.5316],
[-1.4631, -1.5316, -1.5488, ..., -1.4803, -1.4289, -1.4803]],
[[ 0.1176, 0.1176, 0.1176, ..., 0.0301, 0.0126, -0.0224],
[ 0.1001, 0.1001, 0.1001, ..., 0.0126, 0.0126, -0.0049],
[ 0.0826, 0.0826, 0.0826, ..., -0.0049, -0.0049, 0.0126],
...,
[-1.6155, -1.6155, -1.6155, ..., -1.4230, -1.5105, -1.5630],
[-1.5105, -1.5630, -1.5805, ..., -1.5280, -1.5280, -1.5280],
[-1.5105, -1.5630, -1.5805, ..., -1.4755, -1.4230, -1.4755]],
[[ 0.3568, 0.3568, 0.3568, ..., 0.2696, 0.2522, 0.2173],
[ 0.3393, 0.3393, 0.3393, ..., 0.2522, 0.2522, 0.2348],
[ 0.3219, 0.3219, 0.3219, ..., 0.2348, 0.2348, 0.2522],
...,
[-1.3513, -1.3513, -1.3513, ..., -1.1944, -1.2816, -1.3339],
[-1.2467, -1.2990, -1.3164, ..., -1.2990, -1.2990, -1.2990],
[-1.2293, -1.2816, -1.3164, ..., -1.2467, -1.1770, -1.2293]]],
...,
[[[-1.9940, -1.9769, -1.9255, ..., -1.8741, -1.7200, -1.5316],
[-1.9084, -2.0283, -1.9940, ..., -1.8741, -1.7885, -1.6686],
[-1.8056, -1.9940, -2.0625, ..., -1.8741, -1.8913, -1.8228],
...,
[ 1.1569, 1.3967, 1.6707, ..., -1.8570, -1.8399, -1.8399],
[-1.1378, -0.9494, -0.4185, ..., -1.9084, -1.9255, -1.9084],
[-1.3433, -1.4803, -1.6001, ..., -1.9426, -1.9426, -1.6858]],
[[-1.3179, -1.3704, -1.3529, ..., -1.4930, -1.3004, -1.1078],
[-1.2304, -1.4230, -1.4405, ..., -1.4930, -1.3880, -1.2479],
[-1.1779, -1.4055, -1.4930, ..., -1.5105, -1.5105, -1.4405],
...,
[ 1.0455, 1.3957, 1.7808, ..., -1.3004, -1.3004, -1.3354],
[-0.9678, -0.6877, -0.0399, ..., -1.4055, -1.4580, -1.4930],
[-1.0903, -1.1779, -1.1954, ..., -1.4930, -1.5455, -1.3179]],
[[-1.3861, -1.4036, -1.3513, ..., -1.4559, -1.2816, -1.0898],
[-1.2990, -1.4559, -1.4384, ..., -1.4559, -1.3687, -1.2293],
[-1.2119, -1.4210, -1.4733, ..., -1.4559, -1.4733, -1.4036],
...,
[ 0.7576, 1.1585, 1.6465, ..., -1.7870, -1.7870, -1.7870],
[-0.8284, -0.5147, 0.1651, ..., -1.8044, -1.8044, -1.7696],
[-0.7761, -0.8633, -0.8807, ..., -1.7870, -1.7870, -1.5256]]],
[[[ 2.1673, 2.0646, 2.0474, ..., 1.8762, 1.8762, 1.9618],
[ 2.1159, 2.0303, 1.9961, ..., 1.8248, 1.8419, 1.9276],
[ 2.1159, 2.0303, 1.9961, ..., 1.8077, 1.8248, 1.8933],
...,
[ 1.2426, 1.2254, 1.2254, ..., 1.0542, 0.9686, 1.0884],
[ 1.1741, 1.1398, 1.0542, ..., 0.8316, 0.9001, 1.0371],
[ 1.2426, 1.1741, 1.0884, ..., 0.8316, 1.0028, 1.1056]],
[[ 2.3761, 2.2710, 2.2535, ..., 2.0434, 2.0609, 2.1310],
[ 2.3235, 2.2360, 2.2010, ..., 2.0259, 2.0434, 2.1310],
[ 2.3235, 2.2360, 2.2010, ..., 2.0609, 2.0609, 2.1485],
...,
[ 0.8354, 0.8179, 0.8179, ..., 0.6078, 0.5028, 0.6429],
[ 0.7479, 0.7129, 0.6429, ..., 0.3978, 0.5028, 0.6604],
[ 0.7829, 0.7304, 0.6604, ..., 0.4328, 0.6604, 0.8529]],
[[ 2.6226, 2.5529, 2.5354, ..., 2.2043, 2.2217, 2.3088],
[ 2.6051, 2.5180, 2.4831, ..., 2.2391, 2.2566, 2.3611],
[ 2.6051, 2.5180, 2.4831, ..., 2.3437, 2.3611, 2.4308],
...,
[ 0.4439, 0.4265, 0.4265, ..., 0.2173, 0.1128, 0.2696],
[ 0.3393, 0.3045, 0.2348, ..., 0.0431, 0.1825, 0.3916],
[ 0.3568, 0.3045, 0.2522, ..., 0.1302, 0.4265, 0.6705]]],
[[[ 0.1980, 0.2493, 0.2322, ..., 0.9343, 0.9343, 1.3624],
[ 0.1466, 0.1637, 0.1295, ..., 1.1912, 1.0542, 1.2254],
[ 0.1980, 0.0610, -0.0589, ..., 1.3624, 1.1912, 1.1398],
...,
[-1.3261, -1.3604, -1.3946, ..., -1.6858, -1.6515, -1.6344],
[-1.3090, -1.3433, -1.3775, ..., -1.7029, -1.6686, -1.6344],
[-1.1549, -1.3090, -1.3433, ..., -1.6686, -1.6515, -1.4289]],
[[ 0.3102, 0.3627, 0.3452, ..., 1.1681, 1.1681, 1.6057],
[ 0.2577, 0.2752, 0.2402, ..., 1.4307, 1.2906, 1.4657],
[ 0.3102, 0.1702, 0.0476, ..., 1.6057, 1.4307, 1.3782],
...,
[-1.2129, -1.2479, -1.2304, ..., -1.5980, -1.5630, -1.5455],
[-1.1954, -1.2304, -1.2129, ..., -1.6155, -1.5805, -1.5455],
[-1.0378, -1.1779, -1.1954, ..., -1.5805, -1.5630, -1.3354]],
[[ 0.7576, 0.8099, 0.7925, ..., 1.5768, 1.5768, 2.0125],
[ 0.7054, 0.7228, 0.6879, ..., 1.8383, 1.6988, 1.8731],
[ 0.7576, 0.6182, 0.4962, ..., 2.0125, 1.8383, 1.7860],
...,
[-0.8458, -0.8807, -0.8633, ..., -1.2293, -1.1944, -1.1770],
[-0.8284, -0.8284, -0.8284, ..., -1.2467, -1.2119, -1.1770],
[-0.6715, -0.7936, -0.7936, ..., -1.2119, -1.1944, -0.9678]]]]),
tensor([14, 7, 2, 3, 13, 15, 10, 10, 3, 4, 1, 3, 9, 13, 13, 7, 8, 11,
14, 1, 12, 5, 10, 14, 12, 3, 9, 14, 6, 10, 3, 14])]
from torchvision.utils import make_grid
import matplotlib.pyplot as plt
# 获取一个 batch 的图像
images, labels = next(iter(train_dl))
# 生成网格图像
grid = make_grid(images, nrow=8) # nrow 控制每行显示的图像数
# 转为 numpy 并调整维度
grid = grid.numpy().transpose(1, 2, 0)
# 反归一化
grid = grid * 0.5 + 0.5 # 假设归一化参数与之前一致
plt.imshow(grid)
plt.axis('off')
plt.show() # 查看第一批图片数据
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers). Got range [-0.56550217..1.82].
调用官方的VGG16模型
-
特点:
- 深度:VGG-16由16个卷积层和3个全连接层组成,因此具有相对较深的网络结构。这种深度有助于网络学习到更加抽象和复杂的特征
- 卷积层的设计:VGG-16的卷积层全部采用3x3的卷积核和步长为1的卷积操作,同时在卷积层之后都接有ReLU激活函数。这种设计的好处在于,通过堆叠多个较小的卷积核,可以提高网络的非线性建模能力,同时减少了参数数量,从而降低了过拟合的风险。
- 池化层:在卷积层之后,VGG-16使用最大池化层来减少特征图的空间尺寸,帮助提取更加显著的特征并减少计算量。
- 全连接层:VGG-16在卷积层之后接有3个全连接层,最后一个全连接层输出与类别数相对应的向量,用于进行分类。
-
结构说明:
- 13个卷积层(Convolutional Layer),分别用blockX_convX表示;
- 3个全连接层(Fully connected Layer),用classifier表示;
- 5个池化层(Pool layer)。
from torchvision.models import vgg16
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))
# 加载预训练模型,并且对模型进行微调
model = vgg16(pretrained = True).to(device) # 加载预训练的vgg16模型
for param in model.parameters():
param.requires_grad = False # 冻结模型参数,只训练模型最后一层,防止因为数据量太少导致模型不准确
# 修改classifier模块的第6层(即:(6): Linear(in_features=4096, out_features=2, bias=True))
# 注意查看我们下方打印出来的模型
model.classifier._modules['6'] = nn.Linear(4096,len(classNames)) # 修改vgg16模型中最后一层全连接层,输出目标类别个数
model.to(device)
model
Using cpu device
VGG(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace=True)
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(3): ReLU(inplace=True)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(6): ReLU(inplace=True)
(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): ReLU(inplace=True)
(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(13): ReLU(inplace=True)
(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(15): ReLU(inplace=True)
(16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(18): ReLU(inplace=True)
(19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(20): ReLU(inplace=True)
(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(22): ReLU(inplace=True)
(23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(25): ReLU(inplace=True)
(26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(27): ReLU(inplace=True)
(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(29): ReLU(inplace=True)
(30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
(classifier): Sequential(
(0): Linear(in_features=25088, out_features=4096, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=4096, out_features=4096, bias=True)
(4): ReLU(inplace=True)
(5): Dropout(p=0.5, inplace=False)
(6): Linear(in_features=4096, out_features=17, bias=True)
)
)
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() # 每一步自动更新
# 记录acc和loss
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)
num_batches = len(dataloader)
test_loss,test_acc = 0,0
with torch.no_grad():
for imgs,target in dataloader:
imgs,target = imgs.to(device),target.to(device)
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
# def adjust_learning_rate(optimizer, epoch, start_lr):
# # 每 2 个epoch衰减到原来的 0.98
# lr = start_lr * (0.92 ** (epoch // 2))
# for param_group in optimizer.param_groups:
# param_group['lr'] = lr
learn_rate = 1e-4 # 初始学习率
# optimizer = torch.optim.SGD(model.parameters(), lr=learn_rate)
# 之前用过的动态调整学习率的方法
# 学习调用官方动态学习率接口
lambda1 = lambda epoch:0.92 ** (epoch //4)
optimizer = torch.optim.SGD(model.parameters(),lr=learn_rate)
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer,lr_lambda=lambda1)
import copy
loss_fn = nn.CrossEntropyLoss() # 创建损失函数
epochs = 8
train_loss = []
train_acc = []
test_loss = []
test_acc = []
best_acc = 0 # 设置一个最佳准确率,作为最佳模型的判别指标
for epoch in range(epochs):
# 更新学习率(使用自定义学习率时使用)
# adjust_learning_rate(optimizer, epoch, learn_rate)
model.train()
epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, optimizer)
scheduler.step() # 更新学习率(调用官方动态学习率接口时使用)
model.eval()
epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
# 保存最佳模型到 best_model
if epoch_test_acc > best_acc:
best_acc = epoch_test_acc
best_model = copy.deepcopy(model)
train_acc.append(epoch_train_acc)
train_loss.append(epoch_train_loss)
test_acc.append(epoch_test_acc)
test_loss.append(epoch_test_loss)
# 获取当前的学习率
lr = optimizer.state_dict()['param_groups'][0]['lr']
template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}, Lr:{:.2E}')
print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss,
epoch_test_acc*100, epoch_test_loss, lr))
# 保存最佳模型到文件中
PATH = './best_model.pth' # 保存的参数文件名
torch.save(model.state_dict(), PATH)
print('Done')
Epoch: 1, Train_acc:5.0%, Train_loss:2.955, Test_acc:8.1%, Test_loss:2.866, Lr:1.00E-04
Epoch: 2, Train_acc:6.1%, Train_loss:2.906, Test_acc:9.2%, Test_loss:2.813, Lr:1.00E-04
Epoch: 3, Train_acc:7.6%, Train_loss:2.876, Test_acc:8.9%, Test_loss:2.788, Lr:1.00E-04
Epoch: 4, Train_acc:9.4%, Train_loss:2.819, Test_acc:9.7%, Test_loss:2.779, Lr:9.20E-05
Epoch: 5, Train_acc:9.7%, Train_loss:2.789, Test_acc:11.4%, Test_loss:2.727, Lr:9.20E-05
Epoch: 6, Train_acc:8.5%, Train_loss:2.791, Test_acc:13.9%, Test_loss:2.733, Lr:9.20E-05
Epoch: 7, Train_acc:12.0%, Train_loss:2.760, Test_acc:16.4%, Test_loss:2.709, Lr:9.20E-05
Epoch: 8, Train_acc:12.2%, Train_loss:2.736, Test_acc:16.7%, Test_loss:2.680, Lr:8.46E-05
Done
import matplotlib.pyplot as plt
#隐藏警告
import warnings
warnings.filterwarnings("ignore") #忽略警告信息
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rcParams['figure.dpi'] = 100 #分辨率
from datetime import datetime
current_time = datetime.now() # 获取当前时间
epochs_range = range(epochs)
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='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.xlabel(current_time) # 打卡请带上时间戳,否则代码截图无效
plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
总结
- 因为电脑机能不行,本地运行的时候过久会导致电脑崩溃,所以epoch从40缩减到10
- 了解如何调用官方的VGG16模型,如何使用官方方法进行学习率的动态调整
- 熟悉了torch的使用方法以及加深了和tensorflow之间的关联和区别理解