当前位置: 首页> 教育> 培训 > 中小企业信息服务平台_建立一个小型网站多少钱_网站快速优化排名推荐_网络营销推广策划的步骤

中小企业信息服务平台_建立一个小型网站多少钱_网站快速优化排名推荐_网络营销推广策划的步骤

时间:2025/7/14 4:03:15来源:https://blog.csdn.net/weixin_74085818/article/details/146102290 浏览次数:0次
中小企业信息服务平台_建立一个小型网站多少钱_网站快速优化排名推荐_网络营销推广策划的步骤
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

前言

  • 如果说最经典的神经网络,ResNet肯定是一个,从ResNet发布后,很多人做了修改,denseNet网络无疑是最成功的一个,它采用密集型连接,将通道数连接在一起
  • 本文是复现DenseNet121模型,代码注释比较多,比较通俗易懂;
  • ResNet讲解: https://blog.csdn.net/weixin_74085818/article/details/145786990?spm=1001.2014.3001.5501
  • 欢迎收藏 + 关注,本人将会持续更新

文章目录

  • 简介
    • 设计理念
    • 减少维度
  • 模型搭建
    • 导入数据
    • 模型构建
    • 检测

简介

DenseNet是在ResNet之后发明出来的,从网络结构图来看,他类似采用残差的方式

在这里插入图片描述

设计理念

在ResNet网络中,提出残差连接,通过恒等映射实现。

而在DenseNet网络中,采用的是通道数连接,什么意思呢?

  • 在卷积神经网络中,图像数据维度是: [N, C, H, W],其中,N是批次的大小,C是通道数,H是图像高,W是图像宽像素,DenseNet网络就是通过在后面层的“C”通道数“加”前面“C”的通道数,达到后面层的效果不会比前面差(和ResNet网络一样)

特点

  • 在ResNet网络中,一层的残差连接,不会作用与后面的残差连接,但是在Denset网络中,通道数相加回一直叠加,如下图网络图示:

在这里插入图片描述

有点想数学的“组合”👀👀👀👀👀

减少维度

在Conv2d网络中,一般是通过Pooling和stride>1来降低维度,但是在DenseNet网络中提出Transition层降低维度,采用DenseBlock + Transition的结构:

Transition代码:

class _Transition(nn.Sequential):def __init__(self, num_init_features, num_out_features):super(_Transition, self).__init__()self.add_module("norm", nn.BatchNorm2d(num_init_features))self.add_module("relu", nn.ReLU(inplace=True))self.add_module("conv", nn.Conv2d(num_init_features, num_out_features, kernel_size=1, stride=1, bias=False))# 降维self.add_module("pool", nn.AvgPool2d(2, stride=2))

在这里插入图片描述

在DenseBlock中,采封装的DenseLayer层叠加而来,DenseNet-B结中,DenseLayer: BN+ReLU+1x1 Conv+BN+ReLU+3x3 Conv,如图一个DenseLayer结构:

在这里插入图片描述

模型搭建

导入数据

import torch  
import torch.nn as nn 
import torchvision
from collections import OrderedDict
import re
from torch.hub import load_state_dict_from_url

模型构建

在这里插入图片描述

DenseNet,首先实现DenseBlock结构,DenseBlock内部结构,这里采用:BN + ReLU + 1*1Conv + BN + ReLU + 3 * 3Conv, 大体结构如下:
在这里插入图片描述

这个代码很巧妙,值得研究,模仿,继承nn.Sequential类,将多层一样的,进行封装

👀 提示:注释过多,🤠🤠🤠🤠

import torch.nn.functional as F# 实现DenseBlock中的部件:DenseLayer
'''  
1、BN + ReLU: 处理部分,首先进行归一化,然后在用激活函数ReLU
2、Bottlenck Layer:称为瓶颈层,这个层在yolov5中常用,但是yolov5中主要用于特征提取+维度降维,这里采用1 * 1卷积核 + 3 * 3的卷积核进行卷积操作,目的:减少输入输入特征维度
3、BN + ReLU:对 瓶颈层 数据进行归一化,ReLU激活函数,归一化可以确保梯度下降的时候较为平稳
4、3 * 3 生成新的特征图
'''
class _DenseLayer(nn.Sequential):def __init__(self, num_input_features, growth_rate, bn_size, drop_rate):'''  num_input_features: 输入特征数,也就是通道数,在DenseNet中,每一层都会接受之前层的输出作为输入,故,这个数值通常会随着网络深度增加而增加growth_rate: 增长率,这个是 DenseNet的核心概念,决定了每一层为全局状态贡献的特征数量,他的用处主要在于决定了中间瓶颈层的输出通道,需要结合代码去研究bn_size: 瓶颈层中输出通道大小,含义:在使用1 * 1卷积核去提取特征数时,目标通道需要扩展到growth_rate的多少倍倍数, bn_size * growth_rate(输出维度)drop_rate: 使用Dropout的参数'''super(_DenseLayer, self).__init__()self.add_module("norm1", nn.BatchNorm2d(num_input_features))self.add_module("relu1", nn.ReLU(inplace=True))# 输出维度: bn_size * growth_rate, 1 * 1卷积核,步伐为1,只起到特征提取作用self.add_module("conv1", nn.Conv2d(num_input_features, bn_size * growth_rate, stride=1, kernel_size=1, bias=False))self.add_module("norm2", nn.BatchNorm2d(bn_size * growth_rate))self.add_module("relu2", nn.ReLU(inplace=True))# 输出通道:growth_rate, 维度计算:不变self.add_module("conv2", nn.Conv2d(bn_size * growth_rate, growth_rate, stride=1, kernel_size=3, padding=1, bias=False))self.drop_rate = drop_ratedef forward(self, x):new_features = super(_DenseLayer, self).forward(x)  # 传播if self.drop_rate > 0:new_features = F.dropout(new_features, p=self.drop_rate, training=self.training)  # self.training 继承nn.Sequential,是否训练模式# 模型融合,即,特征通道融合,形成新的特征图return torch.cat([x, new_features], dim=1)  # (N, C, H, W)  # 即 C1 + C2,通道上融合'''  
DenseNet网络核心由DenseBlock模块组成,DenseBlock网络由DenseLayer组成,从 DenseLayer 可以看出,DenseBlock是密集连接,每一层的输入不仅包含前一层的输出,还包含网络中所有之前层的输出
'''
# 构建DenseBlock模块, 通过上图
class _DenseBlock(nn.Sequential):# num_layers 几层DenseLayer模块def __init__(self, num_layers, num_input_features, bn_size, growth_rate, drop_rate):super(_DenseBlock, self).__init__()for i in range(num_layers):layer = _DenseLayer(num_input_features + i * growth_rate, growth_rate, bn_size, drop_rate)self.add_module("denselayer%d" % (i + 1), layer)# Transition层,用于维度压缩# 组成:一个卷积层 + 一个池化层
class _Transition(nn.Sequential):def __init__(self, num_init_features, num_out_features):super(_Transition, self).__init__()self.add_module("norm", nn.BatchNorm2d(num_init_features))self.add_module("relu", nn.ReLU(inplace=True))self.add_module("conv", nn.Conv2d(num_init_features, num_out_features, kernel_size=1, stride=1, bias=False))# 降维self.add_module("pool", nn.AvgPool2d(2, stride=2))# 搭建DenseNet网络
class DenseNet(nn.Module):def __init__(self, growth_rate=32, block_config=(6, 12, 24, 16), num_init_features=64, bn_size=4, compression_rate=0.5, drop_rate=0.5, num_classes=1000):'''  growth_rate、num_init_features、num_init_features、drop_rate 和denselayer一样block_config : 参数在 DenseNet 架构中用于指定每个 Dense Block 中包含的层数, 如:DenseNet-121: block_config=(6, 12, 24, 16) 表示第一个 Dense Block 包含 6 层,第二个包含 12 层,第三个包含 24 层,第四个包含 16 层。DenseNet-169: block_config=(6, 12, 32, 32)DenseNet-201: block_config=(6, 12, 48, 32)DenseNet-264: block_config=(6, 12, 64, 48)compression_rate: 压缩维度, DenseNet 中用于 Transition Layer(过渡层)的一个重要参数,它控制了从一个 Dense Block 到下一个 Dense Block 之间特征维度的压缩程度'''super(DenseNet, self).__init__()# 第一层卷积# OrderedDict,让模型层有序排列self.features = nn.Sequential(OrderedDict([# 输出维度:((w - k + 2 * p) / s) + 1("conv0", nn.Conv2d(3, num_init_features, kernel_size=7, stride=2, padding=3, bias=False)),("norm0", nn.BatchNorm2d(num_init_features)),("relu0", nn.ReLU(inplace=True)),("pool0", nn.MaxPool2d(3, stride=2, padding=1))  # 降维]))# 搭建DenseBlock层num_features = num_init_features# num_layers: 层数for i, num_layers in enumerate(block_config):block = _DenseBlock(num_layers, num_features, bn_size, growth_rate, drop_rate)# nn.Module 中features封装了nn.Sequentialself.features.add_module("denseblock%d" % (i + 1), block)'''  # 这个计算反映了 DenseNet 中的一个关键特性:每一层输出的特征图(即新增加的通道数)由 growth_rate 决定,# 并且这些新生成的特征图会被传递给该 Dense Block 中的所有后续层以及下一个 Dense Block。'''num_features += num_layers * growth_rate  # 叠加,每一次叠加# 判断是否需要使用Transition层if i != len(block_config) - 1:transition = _Transition(num_features, int(num_features*compression_rate)) # compression_rate 作用self.features.add_module("transition%d" % (i + 1), transition)num_features = int(num_features*compression_rate)  # 更新维度# 最后一层self.features.add_module("norm5", nn.BatchNorm2d(num_features))self.features.add_module("relu5", nn.ReLU(inplace=True))# 分类层         self.classifier = nn.Linear(num_features, num_classes)# params initialization         for m in self.modules():             if isinstance(m, nn.Conv2d):         '''如果当前模块是一个二维卷积层 (nn.Conv2d),那么它的权重 (m.weight) 将通过 Kaiming 正态分布 (kaiming_normal_) 进行初始化。这种初始化方式特别适合与ReLU激活函数一起使用,有助于缓解深度网络中的梯度消失问题,促进有效的训练。  '''       nn.init.kaiming_normal_(m.weight)             elif isinstance(m, nn.BatchNorm2d):      '''  对于二维批归一化层 (nn.BatchNorm2d),偏置项 (m.bias) 被初始化为0,而尺度因子 (m.weight) 被初始化为1。这意味着在没有数据经过的情况下,批归一化层不会对输入进行额外的缩放或偏移,保持输入不变。'''           nn.init.constant_(m.bias, 0)                 nn.init.constant_(m.weight, 1)             elif isinstance(m, nn.Linear):        '''  对于全连接层 (nn.Linear),只对其偏置项 (m.bias) 进行了初始化,设置为0'''         nn.init.constant_(m.bias, 0)def forward(self, x):features = self.features(x)out = F.avg_pool2d(features, 7, stride=1).view(x.size(0), -1)out = self.classifier(out)return out

搭建DenseNet-121网络,pytorch提供了参数

# 定义包含预训练模型URL的字典
model_urls = {'densenet121': 'https://download.pytorch.org/models/densenet121-a639ec97.pth',
}def densent121(pretrained=False, **kwargs):model = DenseNet(num_init_features=64, growth_rate=32, block_config=(6, 12, 12, 16), **kwargs)# 否加载预训练的权重if pretrained:pattern = re.compile(r'^(.*denselayer\d+\.(?:norm|relu|conv))\.((?:[12])\.(?:weight|bias|running_mean|running_var))$')# 加载预训练模型的状态字典state_dict = load_state_dict_from_url(model_urls['densenet121'])# 处理状态字典中的键名,以适应当前模型定义的要求for key in list(state_dict.keys()):  # 处理参数res = pattern.match(key)if res:new_key = res.group(1) + res.group(2)state_dict[new_key] = state_dict[key]del state_dict[key]# 将处理后的状态字典(模型的参数,神经网络权重么)加载到模型中model.load_state_dict(state_dict)return model

检测

model = densent121(False)# 测试
print(model(torch.randn(32, 3, 224, 224)).shape)
torch.Size([32, 1000])
关键字:中小企业信息服务平台_建立一个小型网站多少钱_网站快速优化排名推荐_网络营销推广策划的步骤

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: