正版资源 getfromcode我的博客 会员免费
pytorch识别图片之004 卷积模型训练、宽度优化、正则化、dropout、normalization、增加模型深度、保存
用户指出上一稿有 1207 个汉字,不合格。要求改成 500~1000 个汉字。 如果少了就补:学习顺序、门槛、学完产出、资料用法;多了就删重复和空话,不要超过 1000。 不要重复堆砌标题,不要列文件名。仍只输出 HTML 片段。 我需要重新写,严格控制汉字数量在 500~1000 之间。 上一稿
单课价¥29新品 上架
正版保障 极速发货 售后无忧
这门课解决什么问题
在Pytorch图像识别的工程实践中,开发者常面临模型训练不稳定、过拟合难以控制、网络结构单一等痛点。本课聚焦从基础架构搭建到训练调优的完整闭环,具体解决如何理解全连接与卷积层的参数计算,如何通过调整网络宽度与深度提升特征提取能力,如何引入dropout与归一化来抑制过拟合并稳定训练,以及如何将训练好的模型持久化保存与加载。
适合什么基础与建议先看
适合具备Python基础、熟悉PyTorch张量操作,且对图像分类有初步了解的开发者。建议按学习顺序优先阅读卷积层与全连接层的参数推导,理解空间信息保留与丢失的逻辑;随后重点攻克模型训练与评估的完整流程,再深入宽度与深度优化策略,最后看正则化与归一化对Loss曲线的影响,最后看模型保存模块。
学完能独立做什么与练习方式
学完本课后,开发者可独立完成一个具备正则化防御能力的卷积神经网络搭建,通过搜索合适的宽度与深度参数来平衡模型容量与泛化能力,并成功将训练好的权重导出为文件供后续推理使用。资料配合代码片段与可视化图表呈现,建议读者边读边改超参数,运行训练循环观察Loss变化,将解析逻辑转化为可复用的工程模块。
让我数一下汉字数(只计汉字,标点英文不算): 第一段: 在Pytorch图像识别的工程实践中,开发者常面临模型训练不稳定、过拟合难以控制、网络结构单一等痛点。本课聚焦从基础架构搭建到训练调优的完整闭环,具体解决如何理解全连接与卷积层的参数计算,如何通过调整网络宽度与深度提升特征提取能力,如何引入dropout与归一化来抑制过拟合并稳定训练,以及如何将训练好的模型持久化保存与加载。 汉字:在图像识别的工程实践中开发者常面临模型训练不稳定过拟合难以控制网络结构单一等痛点本课聚焦从基础架构搭建到训练调优的完整闭环具体解决如何理解全连接与卷积层的参数计算如何通过调整网络宽度与深度提升特征提取能力如何引入与归一化来抑制过拟合并稳定训练以及如何将训练好的模型持久化保存与加载 数一下:在(1)图(2)像(3)识(4)别(5)的(6)工(7)程(8)实(9)践(10)中(11)开(12)发(13)者(14)常(15)面(16)临(17)模(18)型(19)训(20)练(21)不(22)稳(23)定(24)过(25)拟(26)合(27)难(28)以(29)控(30)制(31)网(32)络(33)结(34)构(35)单(36)一(37)等(38)痛(39)点(40)本(41)课(42)聚(43)焦(44)从(45)基(46)础(47)架(48)构(49)搭(50)建(51)到(52)训(53)练(54)调(55)优(56)的(57)完(58)整(59)闭(60)环(61)具(62)体(63)解(64)决(65)如(66)何(67)理(68)解(69)全(70)连(71)接(72)与(73)卷(74)积(75)层(76)的(77)参(78)数(79)计(80)算(81)如(82)何(83)通(84)过(85)调(86)整(87)网(88)络(89)宽(90)度(91)与(92)深(93)度(94)提(95)升(96)特(97)# 全连接层:
# - 把图片展平,丢失空间信息
# - 参数数量:3072 * 512 ≈ 157万
#
# 卷积层:
# - 保持图片的2D结构
# - 参数数量:16 * 3 * 3 * 3 = 432个参数(少得多!)
# - 共享权重,平移不变性
# """
import ssl
ssl._create_default_https_context = ssl._create_unverified_context from matplotlib import pyplot as plt
import numpy as np
import torch #设置张量打印格式(显示更简洁)
torch.set_printoptions(edgeitems=2,linewidth=75)
#固定随机种子,确保结果可重现
torch.manual_seed(123) from torchvision import datasets data_path = '/Volumes/c/work/aigc' class_names= ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck'] from torchvision import transforms transforms_cifar10 = datasets.CIFAR10(root=data_path,train=True,download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4915,0.4823,0.4468),(0.2470,0.2435,0.2616))]))
transforms_cifar10_val = datasets.CIFAR10(root=data_path,train=False,download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4915,0.4823,0.4468),(0.2470,0.2435,0.2616))])) import torch.nn as nn softmax = nn.Softmax(dim=1) #放大大的 缩小小的
label_map={0:0,2:1}
class_names=['airplane','bird']
cifar2= [(img,label_map[label]) for img,label in transforms_cifar10 if label in [0,2]]
cifar2_val= [(img,label_map[label]) for img,label in transforms_cifar10_val if label in [0,2]]
# 3 通道
# out_channels_medium = 16 # 适中,平衡性能和精度
# kernel_size = 3 # 3x3的窗口卷积核大小 是深度学习中最常用的选择 conv = nn.Conv2d(3,16,3,padding=1)
print(conv) img,_=cifar2[0]
out = conv(img.unsqueeze(0))
print(img.unsqueeze(0).shape,out.shape) # model = nn.Sequential( # 顺序容器,一层接一层
# # 第一组卷积
# nn.Conv2d(3, 16, 3, padding=1), # 卷积层1
# nn.Tanh(), # 激活函数1
# nn.MaxPool2d(2), # 池化层1
#
# # 第二组卷积
# nn.Conv2d(16, 8, 3, padding=1), # 卷积层2
# nn.Tanh(), # 激活函数2
# nn.MaxPool2d(2), # 池化层2
#
# # 全连接层
# nn.Linear(8 * 8 * 8, 32), # 全连接层1
# nn.Tanh(), # 激活函数3
# nn.Linear(32, 2), # 输出层
# ) # numel_list = [p.numel() for p in model.parameters()]
# print(sum(numel_list)) import torch.nn.functional as F class Net(nn.Module): def __init__(self): super().__init__() self.conv1 = nn.Conv2d(3, 16, 3, padding=1) self.conv2 = nn.Conv2d(16, 8, 3, padding=1) self.fc1 = nn.Linear(8 * 8 * 8, 32) self.fc2 = nn.Linear(32, 2) def forward(self, x): out = F.max_pool2d(torch.tanh(self.conv1(x)), 2) out = F.max_pool2d(torch.tanh(self.conv2(out)), 2) out = out.view(-1, 8 * 8 * 8) out = torch.tanh(self.fc1(out)) out = self.fc2(out) return out def training_loop(n_epoch,optimizer,model,loss_fn,train_loader): for epoch in range(1,n_epoch+1): loss_train=0 for imgs,labels in train_loader: outputs = model(imgs) loss = loss_fn(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() loss_train += loss.item() if epoch % 10 == 0: print('epoch:',epoch,'loss:',loss_train/len(train_loader)) train_loader = torch.utils.data.DataLoader(cifar2, batch_size=64, shuffle=True)
model=Net()
optimizer=torch.optim.SGD(model.parameters(),lr=0.001)
loss_fn = nn.CrossEntropyLoss()
training_loop(n_epoch=100,optimizer=optimizer,model=model,loss_fn=loss_fn,train_loader=train_loader) val_loader = torch.utils.data.DataLoader(cifar2_val, batch_size=64, shuffle=True) def validate(model,train_loader,val_loader): for name,loader in [("train",train_loader),('val',val_loader)]: correct = 0 total = 0 with torch.no_grad(): for imgs,labels in loader: outputs = model(imgs) _, predicted = torch.max(outputs, dim=1) total += labels.shape[0] correct+=int((predicted==labels).sum()) print(name,correct/total)
validate(model,train_loader,val_loader) # torch.save(model.state_dict(),'/Volumes/c/work/aigc/cifar10.pth')
#
#
# loaded_model=Net()
# loaded_model_use = loaded_model.load_state_dict(torch.load('/Volumes/c/work/aigc/cifar10.pth'))宽度优化
class Net(nn.Module): def __init__(self,n_chanel=32): super().__init__() self.n_chanel=n_chanel self.conv1 = nn.Conv2d(3, n_chanel, 3, padding=1) self.conv2 = nn.Conv2d(n_chanel, n_chanel//2, 3, padding=1) self.fc1 = nn.Linear(n_chanel//2 * 8 * 8, 32) self.fc2 = nn.Linear(32, 2) def forward(self, x): out = F.max_pool2d(torch.tanh(self.conv1(x)), 2) out = F.max_pool2d(torch.tanh(self.conv2(out)), 2) out = out.view(-1, self.n_chanel//2 * 8 * 8) out = torch.tanh(self.fc1(out)) out = self.fc2(out) return out
没有优化是85% 优化之后到了87%
正则化
def training_loop(n_epoch,optimizer,model,loss_fn,train_loader): for epoch in range(1,n_epoch+1): loss_train=0 for imgs,labels in train_loader: outputs = model(imgs) loss = loss_fn(outputs, labels) #正则化 lambda_12 = 0.0001 norm_12 = sum(p.pow(2.0).sum() for p in model.parameters()) loss = loss+lambda_12*norm_12 optimizer.zero_grad() loss.backward() optimizer.step() loss_train += loss.item() if epoch % 10 == 0: print('epoch:',epoch,'loss:',loss_train/len(train_loader))dropout
class Net(nn.Module): def __init__(self): super().__init__() self.conv1 = nn.Conv2d(3, 16, 3, padding=1) # dropout self.conv1_dropout = nn.Dropout2d(0.4) self.conv2 = nn.Conv2d(16, 8, 3, padding=1) # dropout self.conv2_dropout = nn.Dropout2d(0.4) self.fc1 = nn.Linear(8 * 8 * 8, 32) self.fc2 = nn.Linear(32, 2) def forward(self, x): out = F.max_pool2d(torch.tanh(self.conv1(x)), 2) out = self.conv1_dropout(out) out = F.max_pool2d(torch.tanh(self.conv2(out)), 2) out = self.conv2_dropout(out) out = out.view(-1, 8 * 8 * 8) out = torch.tanh(self.fc1(out)) out = self.fc2(out) return out





