当前位置: 首页 > news >正文

网站优化seo是什么意思网站实施过程

网站优化seo是什么意思,网站实施过程,惠州网站制作设计,网站建设的公司哪家强预训练模型 CBAM注意力 现在我们思考下#xff0c;是否可以对于预训练模型增加模块来优化其效果#xff0c;这里我们会遇到一个问题#xff1a; 预训练模型的结构和权重是固定的#xff0c;如果修改其中的模型结构#xff0c;是否会大幅影响其性能。其次是训练的时候如何…预训练模型 CBAM注意力 现在我们思考下是否可以对于预训练模型增加模块来优化其效果这里我们会遇到一个问题 预训练模型的结构和权重是固定的如果修改其中的模型结构是否会大幅影响其性能。其次是训练的时候如何训练才可以更好的避免破坏原有的特征提取器的参数。 所以今天的内容我们需要回答2个问题。 resnet18中如何插入cbam模块采用什么样的预训练策略能够更好的提高效率 可以很明显的想到如果是resnet18cbam模块那么大多数地方的代码都是可以复用的模型定义部分需要重写。先继续之前的代码 所以很容易的想到之前第一次使用resnet的预训练策略先冻结预训练层然后训练其他层。之前的其它层是全连接层分类头现在其它层还包含了每一个残差块中的cbam注意力层 resnet结构解析 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pyplot as plt import numpy as np# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self, in_channels, ratio16):通道注意力机制初始化参数:in_channels: 输入特征图的通道数ratio: 降维比例用于减少参数量默认为16super().__init__()# 全局平均池化将每个通道的特征图压缩为1x1保留通道间的平均值信息self.avg_pool nn.AdaptiveAvgPool2d(1)# 全局最大池化将每个通道的特征图压缩为1x1保留通道间的最显著特征self.max_pool nn.AdaptiveMaxPool2d(1)# 共享全连接层用于学习通道间的关系# 先降维除以ratio再通过ReLU激活最后升维回原始通道数self.fc nn.Sequential(nn.Linear(in_channels, in_channels // ratio, biasFalse), # 降维层nn.ReLU(), # 非线性激活函数nn.Linear(in_channels // ratio, in_channels, biasFalse) # 升维层)# Sigmoid函数将输出映射到0-1之间作为各通道的权重self.sigmoid nn.Sigmoid()def forward(self, x):前向传播函数参数:x: 输入特征图形状为 [batch_size, channels, height, width]返回:调整后的特征图通道权重已应用# 获取输入特征图的维度信息这是一种元组的解包写法b, c, h, w x.shape# 对平均池化结果进行处理展平后通过全连接网络avg_out self.fc(self.avg_pool(x).view(b, c))# 对最大池化结果进行处理展平后通过全连接网络max_out self.fc(self.max_pool(x).view(b, c))# 将平均池化和最大池化的结果相加并通过sigmoid函数得到通道权重attention self.sigmoid(avg_out max_out).view(b, c, 1, 1)# 将注意力权重与原始特征相乘增强重要通道抑制不重要通道return x * attention #这个运算是pytorch的广播机制## 空间注意力模块 class SpatialAttention(nn.Module):def __init__(self, kernel_size7):super().__init__()self.conv nn.Conv2d(2, 1, kernel_size, paddingkernel_size//2, biasFalse)self.sigmoid nn.Sigmoid()def forward(self, x):# 通道维度池化avg_out torch.mean(x, dim1, keepdimTrue) # 平均池化(B,1,H,W)max_out, _ torch.max(x, dim1, keepdimTrue) # 最大池化(B,1,H,W)pool_out torch.cat([avg_out, max_out], dim1) # 拼接(B,2,H,W)attention self.conv(pool_out) # 卷积提取空间特征return x * self.sigmoid(attention) # 特征与空间权重相乘## CBAM模块 class CBAM(nn.Module):def __init__(self, in_channels, ratio16, kernel_size7):super().__init__()self.channel_attn ChannelAttention(in_channels, ratio)self.spatial_attn SpatialAttention(kernel_size)def forward(self, x):x self.channel_attn(x)x self.spatial_attn(x)return ximport torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pyplot as plt import numpy as np# 设置中文字体支持 plt.rcParams[font.family] [SimHei] plt.rcParams[axes.unicode_minus] False # 解决负号显示问题# 检查GPU是否可用 device torch.device(cuda if torch.cuda.is_available() else cpu) print(f使用设备: {device})# 数据预处理与原代码一致 train_transform transforms.Compose([transforms.RandomCrop(32, padding4),transforms.RandomHorizontalFlip(),transforms.ColorJitter(brightness0.2, contrast0.2, saturation0.2, hue0.1),transforms.RandomRotation(15),transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)) ])test_transform transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)) ])# 加载数据集与原代码一致 train_dataset datasets.CIFAR10(root./data, trainTrue, downloadTrue, transformtrain_transform) test_dataset datasets.CIFAR10(root./data, trainFalse, transformtest_transform) train_loader DataLoader(train_dataset, batch_size64, shuffleTrue) test_loader DataLoader(test_dataset, batch_size64, shuffleFalse) 通过与训练resnet18来查看模型结构 import torch import torchvision.models as models from torchinfo import summary #之前的内容说了推荐用他来可视化模型结构信息最全# 加载 ResNet18预训练 model models.resnet18(pretrainedTrue) model.eval()# 输出模型结构和参数概要 summary(model, input_size(1, 3, 224, 224)) Layer (type:depth-idx) Output Shape Param #ResNet [1, 1000] -- ├─Conv2d: 1-1 [1, 64, 112, 112] 9,408 ├─BatchNorm2d: 1-2 [1, 64, 112, 112] 128 ├─ReLU: 1-3 [1, 64, 112, 112] -- ├─MaxPool2d: 1-4 [1, 64, 56, 56] -- ├─Sequential: 1-5 [1, 64, 56, 56] -- │ └─BasicBlock: 2-1 [1, 64, 56, 56] -- │ │ └─Conv2d: 3-1 [1, 64, 56, 56] 36,864 │ │ └─BatchNorm2d: 3-2 [1, 64, 56, 56] 128 │ │ └─ReLU: 3-3 [1, 64, 56, 56] -- │ │ └─Conv2d: 3-4 [1, 64, 56, 56] 36,864 │ │ └─BatchNorm2d: 3-5 [1, 64, 56, 56] 128 │ │ └─ReLU: 3-6 [1, 64, 56, 56] -- │ └─BasicBlock: 2-2 [1, 64, 56, 56] -- │ │ └─Conv2d: 3-7 [1, 64, 56, 56] 36,864 │ │ └─BatchNorm2d: 3-8 [1, 64, 56, 56] 128 │ │ └─ReLU: 3-9 [1, 64, 56, 56] -- │ │ └─Conv2d: 3-10 [1, 64, 56, 56] 36,864 │ │ └─BatchNorm2d: 3-11 [1, 64, 56, 56] 128 │ │ └─ReLU: 3-12 [1, 64, 56, 56] -- ├─Sequential: 1-6 [1, 128, 28, 28] -- │ └─BasicBlock: 2-3 [1, 128, 28, 28] -- │ │ └─Conv2d: 3-13 [1, 128, 28, 28] 73,728 │ │ └─BatchNorm2d: 3-14 [1, 128, 28, 28] 256 │ │ └─ReLU: 3-15 [1, 128, 28, 28] -- │ │ └─Conv2d: 3-16 [1, 128, 28, 28] 147,456 │ │ └─BatchNorm2d: 3-17 [1, 128, 28, 28] 256 │ │ └─Sequential: 3-18 [1, 128, 28, 28] 8,448 │ │ └─ReLU: 3-19 [1, 128, 28, 28] -- │ └─BasicBlock: 2-4 [1, 128, 28, 28] -- │ │ └─Conv2d: 3-20 [1, 128, 28, 28] 147,456 │ │ └─BatchNorm2d: 3-21 [1, 128, 28, 28] 256 │ │ └─ReLU: 3-22 [1, 128, 28, 28] -- │ │ └─Conv2d: 3-23 [1, 128, 28, 28] 147,456 │ │ └─BatchNorm2d: 3-24 [1, 128, 28, 28] 256 │ │ └─ReLU: 3-25 [1, 128, 28, 28] -- ├─Sequential: 1-7 [1, 256, 14, 14] -- │ └─BasicBlock: 2-5 [1, 256, 14, 14] -- │ │ └─Conv2d: 3-26 [1, 256, 14, 14] 294,912 │ │ └─BatchNorm2d: 3-27 [1, 256, 14, 14] 512 │ │ └─ReLU: 3-28 [1, 256, 14, 14] -- │ │ └─Conv2d: 3-29 [1, 256, 14, 14] 589,824 │ │ └─BatchNorm2d: 3-30 [1, 256, 14, 14] 512 │ │ └─Sequential: 3-31 [1, 256, 14, 14] 33,280 │ │ └─ReLU: 3-32 [1, 256, 14, 14] -- │ └─BasicBlock: 2-6 [1, 256, 14, 14] -- │ │ └─Conv2d: 3-33 [1, 256, 14, 14] 589,824 │ │ └─BatchNorm2d: 3-34 [1, 256, 14, 14] 512 │ │ └─ReLU: 3-35 [1, 256, 14, 14] -- │ │ └─Conv2d: 3-36 [1, 256, 14, 14] 589,824 │ │ └─BatchNorm2d: 3-37 [1, 256, 14, 14] 512 │ │ └─ReLU: 3-38 [1, 256, 14, 14] -- ├─Sequential: 1-8 [1, 512, 7, 7] -- │ └─BasicBlock: 2-7 [1, 512, 7, 7] -- │ │ └─Conv2d: 3-39 [1, 512, 7, 7] 1,179,648 │ │ └─BatchNorm2d: 3-40 [1, 512, 7, 7] 1,024 │ │ └─ReLU: 3-41 [1, 512, 7, 7] -- │ │ └─Conv2d: 3-42 [1, 512, 7, 7] 2,359,296 │ │ └─BatchNorm2d: 3-43 [1, 512, 7, 7] 1,024 │ │ └─Sequential: 3-44 [1, 512, 7, 7] 132,096 │ │ └─ReLU: 3-45 [1, 512, 7, 7] -- │ └─BasicBlock: 2-8 [1, 512, 7, 7] -- │ │ └─Conv2d: 3-46 [1, 512, 7, 7] 2,359,296 │ │ └─BatchNorm2d: 3-47 [1, 512, 7, 7] 1,024 │ │ └─ReLU: 3-48 [1, 512, 7, 7] -- │ │ └─Conv2d: 3-49 [1, 512, 7, 7] 2,359,296 │ │ └─BatchNorm2d: 3-50 [1, 512, 7, 7] 1,024 │ │ └─ReLU: 3-51 [1, 512, 7, 7] -- ├─AdaptiveAvgPool2d: 1-9 [1, 512, 1, 1] -- ├─Linear: 1-10 [1, 1000] 513,000Total params: 11,689,512 Trainable params: 11,689,512 Non-trainable params: 0 Total mult-adds (G): 1.81Input size (MB): 0.60 Forward/backward pass size (MB): 39.75 Params size (MB): 46.76 Estimated Total Size (MB): 87.11经典的 ResNet-18 模型可以将其看作一个处理流水线图像数据从一端进去分类结果从另一端出来。整个过程可以分为三个主要部分 CBAM放置位置 import torch import torch.nn as nn from torchvision import models# 自定义ResNet18模型插入CBAM模块 class ResNet18_CBAM(nn.Module):def __init__(self, num_classes10, pretrainedTrue, cbam_ratio16, cbam_kernel7):super().__init__()# 加载预训练ResNet18self.backbone models.resnet18(pretrainedpretrained) # 修改首层卷积以适应32x32输入CIFAR10self.backbone.conv1 nn.Conv2d(in_channels3, out_channels64, kernel_size3, stride1, padding1, biasFalse)self.backbone.maxpool nn.Identity() # 移除原始MaxPool层因输入尺寸小# 在每个残差块组后添加CBAM模块self.cbam_layer1 CBAM(in_channels64, ratiocbam_ratio, kernel_sizecbam_kernel)self.cbam_layer2 CBAM(in_channels128, ratiocbam_ratio, kernel_sizecbam_kernel)self.cbam_layer3 CBAM(in_channels256, ratiocbam_ratio, kernel_sizecbam_kernel)self.cbam_layer4 CBAM(in_channels512, ratiocbam_ratio, kernel_sizecbam_kernel)# 修改分类头self.backbone.fc nn.Linear(in_features512, out_featuresnum_classes)def forward(self, x):# 主干特征提取x self.backbone.conv1(x)x self.backbone.bn1(x)x self.backbone.relu(x) # [B, 64, 32, 32]# 第一层残差块 CBAMx self.backbone.layer1(x) # [B, 64, 32, 32]x self.cbam_layer1(x)# 第二层残差块 CBAMx self.backbone.layer2(x) # [B, 128, 16, 16]x self.cbam_layer2(x)# 第三层残差块 CBAMx self.backbone.layer3(x) # [B, 256, 8, 8]x self.cbam_layer3(x)# 第四层残差块 CBAMx self.backbone.layer4(x) # [B, 512, 4, 4]x self.cbam_layer4(x)# 全局平均池化 分类x self.backbone.avgpool(x) # [B, 512, 1, 1]x torch.flatten(x, 1) # [B, 512]x self.backbone.fc(x) # [B, 10]return x# 初始化模型并移至设备 model ResNet18_CBAM().to(device) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) scheduler optim.lr_scheduler.ReduceLROnPlateau(optimizer, modemin, patience3, factor0.5) import time# # 4. 结合了分阶段策略和详细打印的训练函数 # def set_trainable_layers(model, trainable_parts):print(f\n--- 解冻以下部分并设为可训练: {trainable_parts})for name, param in model.named_parameters():param.requires_grad Falsefor part in trainable_parts:if part in name:param.requires_grad Truebreakdef train_staged_finetuning(model, criterion, train_loader, test_loader, device, epochs):optimizer None# 初始化历史记录列表与你的要求一致all_iter_losses, iter_indices [], []train_acc_history, test_acc_history [], []train_loss_history, test_loss_history [], []for epoch in range(1, epochs 1):epoch_start_time time.time()# --- 动态调整学习率和冻结层 ---if epoch 1:print(\n *50 \n **阶段 1训练注意力模块和分类头**\n *50)set_trainable_layers(model, [cbam, backbone.fc])optimizer optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr1e-3)elif epoch 6:print(\n *50 \n✈️ **阶段 2解冻高层卷积层 (layer3, layer4)**\n *50)set_trainable_layers(model, [cbam, backbone.fc, backbone.layer3, backbone.layer4])optimizer optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr1e-4)elif epoch 21:print(\n *50 \n️ **阶段 3解冻所有层进行全局微调**\n *50)for param in model.parameters(): param.requires_grad Trueoptimizer optim.Adam(model.parameters(), lr1e-5)# --- 训练循环 ---model.train()running_loss, correct, total 0.0, 0, 0for batch_idx, (data, target) in enumerate(train_loader):data, target data.to(device), target.to(device)optimizer.zero_grad()output model(data)loss criterion(output, target)loss.backward()optimizer.step()# 记录每个iteration的损失iter_loss loss.item()all_iter_losses.append(iter_loss)iter_indices.append((epoch - 1) * len(train_loader) batch_idx 1)running_loss iter_loss_, predicted output.max(1)total target.size(0)correct predicted.eq(target).sum().item()# 按你的要求每100个batch打印一次if (batch_idx 1) % 100 0:print(fEpoch: {epoch}/{epochs} | Batch: {batch_idx1}/{len(train_loader)} f| 单Batch损失: {iter_loss:.4f} | 累计平均损失: {running_loss/(batch_idx1):.4f})epoch_train_loss running_loss / len(train_loader)epoch_train_acc 100. * correct / totaltrain_loss_history.append(epoch_train_loss)train_acc_history.append(epoch_train_acc)# --- 测试循环 ---model.eval()test_loss, correct_test, total_test 0, 0, 0with torch.no_grad():for data, target in test_loader:data, target data.to(device), target.to(device)output model(data)test_loss criterion(output, target).item()_, predicted output.max(1)total_test target.size(0)correct_test predicted.eq(target).sum().item()epoch_test_loss test_loss / len(test_loader)epoch_test_acc 100. * correct_test / total_testtest_loss_history.append(epoch_test_loss)test_acc_history.append(epoch_test_acc)# 打印每个epoch的最终结果print(fEpoch {epoch}/{epochs} 完成 | 耗时: {time.time() - epoch_start_time:.2f}s | 训练准确率: {epoch_train_acc:.2f}% | 测试准确率: {epoch_test_acc:.2f}%)# 训练结束后调用绘图函数print(\n训练完成! 开始绘制结果图表...)plot_iter_losses(all_iter_losses, iter_indices)plot_epoch_metrics(train_acc_history, test_acc_history, train_loss_history, test_loss_history)# 返回最终的测试准确率return epoch_test_acc# # 5. 绘图函数定义 # def plot_iter_losses(losses, indices):plt.figure(figsize(10, 4))plt.plot(indices, losses, b-, alpha0.7, labelIteration Loss)plt.xlabel(IterationBatch序号)plt.ylabel(损失值)plt.title(每个 Iteration 的训练损失)plt.legend()plt.grid(True)plt.tight_layout()plt.show()def plot_epoch_metrics(train_acc, test_acc, train_loss, test_loss):epochs range(1, len(train_acc) 1)plt.figure(figsize(12, 4))plt.subplot(1, 2, 1)plt.plot(epochs, train_acc, b-, label训练准确率)plt.plot(epochs, test_acc, r-, label测试准确率)plt.xlabel(Epoch)plt.ylabel(准确率 (%))plt.title(训练和测试准确率)plt.legend(); plt.grid(True)plt.subplot(1, 2, 2)plt.plot(epochs, train_loss, b-, label训练损失)plt.plot(epochs, test_loss, r-, label测试损失)plt.xlabel(Epoch)plt.ylabel(损失值)plt.title(训练和测试损失)plt.legend(); plt.grid(True)plt.tight_layout()plt.show()# # 6. 执行训练 # model ResNet18_CBAM().to(device) criterion nn.CrossEntropyLoss() epochs 50print(开始使用带分阶段微调策略的ResNet18CBAM模型进行训练...) final_accuracy train_staged_finetuning(model, criterion, train_loader, test_loader, device, epochs) print(f训练完成最终测试准确率: {final_accuracy:.2f}%)# torch.save(model.state_dict(), resnet18_cbam_finetuned.pth) # print(模型已保存为: resnet18_cbam_finetuned.pth)
http://www.hkea.cn/news/14553360/

相关文章:

  • 网站开发薪酬北京学电脑的培训机构
  • 电子商务网站建设需要哪些步骤西部虚拟主机网站后台不能访问
  • 网站怎么做认证吗企业咨询属于什么行业
  • 如何网站专题策划青海建设厅网站通知
  • 用dw做网站怎么添加背景图片江苏建设教育网站
  • 建设网站服务器端环境要求网站形式
  • 株洲网站建设费用seo下载站
  • 海口市做网站的公司wordpress超级密码破解
  • 山东建设机械协会网站wordpress 返利 插件
  • 医院网站制作公司大连建设学院网站
  • 网站建设编码做一个网站需要多少钱大概费用
  • 陆金所网站开发二部设计公司入川备案
  • 营销导向的网站建设的主要流程装饰工程
  • 响应式做的好的网站有哪些windows8 网站建站命令
  • 做教师章节试题哪个网站优化wordpress后台速度
  • 服装网站论文wordpress admin空白
  • 网页制作中网站名称怎么做梯子
  • 关于网站建设的调查报告宝应网站设计
  • 杭州 网站制作微信推广网站
  • 图片无版权网站上海网站建设科技公司
  • 3733手游网站在哪里做的百度热词搜索指数
  • 福州网站建设要找嘉艺网络高校建设网站的特色
  • 网站建设制作费用预算表怎么搞免费的网站
  • 河南做网站公司汉狮洛阳网站设计公司
  • 东营智能网站设计seo北京公司
  • 菏泽做网站建设找哪家建设专业网站网络
  • 金泉网做网站找谁sae安装WordPress4.4
  • 小企业怎么做网站公司网站建设应注意事项
  • 系统花钱做任务的小说魅网站外贸网站建设 东莞
  • 用flash做网站超链接百度用户服务中心