第J3周:DenseNet121算法实现01(Pytorch版)

embedded/2025/3/31 17:10:51/
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

目标

具体实现

(一)环境

语言环境:Python 3.10
编 译 器: PyCharm
框 架: Pytorch

(二)具体步骤
1. DenseNet121.py
import torch  
import torch.nn as nn  
import torch.nn.functional as F  
import math  # 实现DenseLayer(密集连接层)  
class DenseLayer(nn.Module):  def __init__(self, num_input_features, growth_rate, bn_size, drop_rate):  super(DenseLayer, self).__init__()  # BN -> ReLU -> Conv(1x1) -> BN -> ReLU -> Conv(3x3)  self.norm1 = nn.BatchNorm2d(num_input_features)  # 第一个批归一化层  self.relu1 = nn.ReLU(inplace=True)  # 第一个ReLU激活函数  self.conv1 = nn.Conv2d(num_input_features, bn_size * growth_rate,  kernel_size=1, stride=1, bias=False)  # 1x1卷积层  self.norm2 = nn.BatchNorm2d(bn_size * growth_rate)  # 第二个批归一化层  self.relu2 = nn.ReLU(inplace=True)  # 第二个ReLU激活函数  self.conv2 = nn.Conv2d(bn_size * growth_rate, growth_rate,  kernel_size=3, stride=1, padding=1, bias=False)  # 3x3卷积层  self.drop_rate = drop_rate  # Dropout率  def forward(self, x):  # 保存输入特征,用于后续的密集连接  new_features = self.norm1(x)  new_features = self.relu1(new_features)  new_features = self.conv1(new_features)  new_features = self.norm2(new_features)  new_features = self.relu2(new_features)  new_features = self.conv2(new_features)  # 如果设置了dropout,则应用dropout  if self.drop_rate > 0:  new_features = F.dropout(new_features, p=self.drop_rate, training=self.training)  # 将新特征与输入特征进行拼接,实现密集连接  return torch.cat([x, new_features], 1)  # 实现DenseBlock(密集块)  
class DenseBlock(nn.Module):  def __init__(self, num_layers, num_input_features, bn_size, growth_rate, drop_rate):  super(DenseBlock, self).__init__()  # 创建指定数量的DenseLayer,每一层的输入特征数量都会增加  self.layers = nn.ModuleList()  for i in range(num_layers):  layer = DenseLayer(  num_input_features + i * growth_rate,  growth_rate=growth_rate,  bn_size=bn_size,  drop_rate=drop_rate  )  self.layers.append(layer)  def forward(self, x):  # 依次通过所有的DenseLayer  features = x  for layer in self.layers:  features = layer(features)  return features  # 实现TransitionLayer(过渡层)  
class TransitionLayer(nn.Module):  def __init__(self, num_input_features, num_output_features):  super(TransitionLayer, self).__init__()  # BN -> Conv(1x1) -> AvgPool(2x2)  self.norm = nn.BatchNorm2d(num_input_features)  # 批归一化层  self.relu = nn.ReLU(inplace=True)  # ReLU激活函数  self.conv = nn.Conv2d(num_input_features, num_output_features,  kernel_size=1, stride=1, bias=False)  # 1x1卷积层  self.pool = nn.AvgPool2d(kernel_size=2, stride=2)  # 平均池化层  def forward(self, x):  x = self.norm(x)  x = self.relu(x)  x = self.conv(x)  x = self.pool(x)  return x  # 实现完整的DenseNet121模型  
class DenseNet121(nn.Module):  def __init__(self, growth_rate=32, block_config=(6, 12, 24, 16),  num_init_features=64, bn_size=4, drop_rate=0, num_classes=1000):  super(DenseNet121, self).__init__()  # 首先是一个7x7的卷积层,步长为2  self.features = nn.Sequential()  self.features.add_module('conv0',  nn.Conv2d(3, num_init_features, kernel_size=7, stride=2, padding=3, bias=False))  # 初始卷积层  self.features.add_module('norm0', nn.BatchNorm2d(num_init_features))  # 批归一化层  self.features.add_module('relu0', nn.ReLU(inplace=True))  # ReLU激活函数  self.features.add_module('pool0', nn.MaxPool2d(kernel_size=3, stride=2, padding=1))  # 最大池化层  # 依次添加DenseBlock和TransitionLayer  num_features = num_init_features  for i, num_layers in enumerate(block_config):  # 添加DenseBlock  block = DenseBlock(  num_layers=num_layers,  num_input_features=num_features,  bn_size=bn_size,  growth_rate=growth_rate,  drop_rate=drop_rate  )  self.features.add_module(f'denseblock{i + 1}', block)  num_features = num_features + num_layers * growth_rate  # 如果不是最后一个block,则添加TransitionLayer  if i != len(block_config) - 1:  # 过渡层将特征图数量减半  trans = TransitionLayer(  num_input_features=num_features,  num_output_features=num_features // 2  )  self.features.add_module(f'transition{i + 1}', trans)  num_features = num_features // 2  # 最后添加一个BatchNorm  self.features.add_module('norm5', nn.BatchNorm2d(num_features))  # 最终的批归一化层  # 全局平均池化和分类器  self.classifier = nn.Linear(num_features, num_classes)  # 全连接分类器  # 初始化权重  for m in self.modules():  if isinstance(m, nn.Conv2d):  nn.init.kaiming_normal_(m.weight)  # 使用Kaiming初始化卷积层权重  elif isinstance(m, nn.BatchNorm2d):  nn.init.constant_(m.weight, 1)  # 初始化批归一化层的权重为1  nn.init.constant_(m.bias, 0)  # 初始化批归一化层的偏置为0  elif isinstance(m, nn.Linear):  nn.init.constant_(m.bias, 0)  # 初始化全连接层的偏置为0  def forward(self, x):  features = self.features(x)  # 提取特征  out = F.relu(features, inplace=True)  # 应用ReLU激活函数  out = F.adaptive_avg_pool2d(out, (1, 1))  # 全局平均池化  out = torch.flatten(out, 1)  # 展平特征  out = self.classifier(out)  # 分类  return out  # 创建DenseNet121模型实例  
def create_densenet121(num_classes=1000, pretrained=False):  model = DenseNet121(num_classes=num_classes)  return model  # 使用示例  
if __name__ == "__main__":  # 创建模型  model = create_densenet121()  print(model)  # 创建随机输入张量 (batch_size, channels, height, width)    x = torch.randn(1, 3, 224, 224)  # 前向传播  output = model(x)  print(f"Input shape: {x.shape}")  print(f"Output shape: {output.shape}")

image.png


http://www.ppmy.cn/embedded/174368.html

相关文章

word插入Mathtype公式居中和自动更新

word插入公式自动更新 前提:安装Mathtype 1.word中查看页的宽度 出现如下 2.设置样式 出现这个窗口 给样式随便起个名字 3.修改样式 3.1 设置两个制表位 第二个 3.2 修改公式字体 如下所示 4. 修改公式格式 4.1在word中打开 Mathtype 4.2 修改公式的格式 变成…

区块链(Blockchain)

区块链(Blockchain)是一种去中心化、分布式的账本技术,它通过密码学保证数据的安全性和不可篡改性。它的核心特点包括去中心化、不可篡改性、可追溯性、智能合约等。 区块链的关键概念 区块(Block):每个区…

数据分析的12个挑战及其解决方法

俗话说得好“说起来容易做起来难。”数据分析对于风险管理者是极为重要的。我们可以利用数据分析结论,来为企业决策做有效协助,帮助企业改善财务状况,提升企业业务销售水平,帮助员工预测可能发生的问题,并协助监控企业…

将 YOLO 格式的标注文件(.txt)转换为 VOC 格式的 XML 标注文件

1. 函数定义和注释 def makexml(picPath, txtPath, xmlPath): """此函数用于将yolo格式txt标注文件转换为voc格式xml标注文件 在自己的标注图片文件夹下建三个子文件夹,分别命名为picture、txt、xml """ 函数接收三个参数…

解决 SQL Server 日常使用中的疑难杂症,提供实用解决方案

SQL Server 作为企业级关系型数据库管理系统,因其强大的功能和稳定性被广泛应用于数据存储与管理。然而,在日常使用中,用户难免会遇到性能瓶颈、连接问题或数据异常等“疑难杂症”。本文将针对 SQL Server 常见的实际问题,深入剖析…

如何实现一个分布式单例对象?什么场景需要分布式单例?

单例模式确保一个类在同一个进程中只有一个实例,并提供一个全局访问点。这意味着无论在哪里调用该类的实例化方法,返回的都是同一个对象实例。 在分布式系统中,无论是单台机器多个实例,还是多台机器多个实例,每个实例…

数学建模之数学模型-3:动态规划

文章目录 动态规划基本概念阶段状态决策策略状态转移方程指标函数最优指标函数 动态规划的求解前向算法后向算法二者比较 应用案例 一种中文分词的动态规划模型摘要引言动态规划的分词模型问题的数学描述消除状态的后效性选择优化条件 算法描述和计算实例算法的效率分析和评价结…

用Ollama部署大语言模型

引言 大语言模型(Large Language Models,LLMs)正在彻底改变我们与技术的交互方式。从自动化内容创建到复杂问题解答,LLMs的应用范围广泛且不断扩展。然而,部署这些强大的模型通常需要专业知识和大量计算资源。Ollama的…