第J3周:DenseNet算法实战与解析

news2024/12/23 22:38:05
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

    文章目录

    • 一、前期工作
    • 二、模型复现
      • 1、设置GPU
      • 2、导入数据
      • 3、加载数据
      • 4. 配置数据集
      • 5. 可视化数据
      • 6、构建DenseNet121网络
      • 7、编译
      • 8、训练模型
      • 9、模型评估
    • 三、总结

电脑环境:
语言环境:Python 3.8.0
编译器:Jupyter Notebook
深度学习环境:tensorflow 2.17.0

一、前期工作

DenseNet(稠密连接网络)是由Cornell大学的Gao Huang等人于2017年提出的深度学习网络架构。它的设计灵感来自于ResNet(残差网络)以及其前身 Highway Networks 的思想。

在深度卷积神经网络中,通常存在梯度消失或梯度爆炸等问题,尤其是随着网络层数的增加,残差网络引入了残差连接(跨层连接)来解决了这些问题,从而允许网络更深地训练,但是,ResNet中的跨层连接是通过相加的方式实现的,这意味着每一层只能直接访问前一层的输出。

DenseNet(密集卷积网络)的核心思想(创新之处)是密集连接,使得每一层都与所有之前的层直接连接,即某层的输入除了包含前一层的输出外还包含前面所有层的输出。
在这里插入图片描述

整个网络包含三个核心结构,DenseLayer、DenseBlock和Transition,通过上述的三个核心的结构的拼接加上其他层来完成整个模型的搭建。

如上图,共有5个DenseBlock,每个DenseBlock中有多个DenseLayer组成,每个DenseLayer层包含BN + Relu + 1x1Conv + BN + Relu + 3x3Conv,Transition模块包含BN + Relu + 1x1Conv + 2x2AvgPool。
在这里插入图片描述

二、模型复现

1、设置GPU

import tensorflow as tf

gpus = tf.config.list_physical_devices('GPU')

if gpus:
    tf.config.experimental.set_memory_growth(gpus[0], True)
    tf.config.set_visible_devices(gpus[0], 'GPU')

gpus

2、导入数据

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

import os, PIL, pathlib
import numpy as np

from tensorflow import keras
from keras import layers, models

data_dir = './bird_photos'
data_dir = pathlib.Path(data_dir)
image_count = len(list(data_dir.glob('*/*')))
image_count

3、加载数据

batch_size = 16
img_height = 224
img_width = 224

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=12,
    image_size=(img_height, img_width),
    batch_size=batch_size)

val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=12,
    image_size=(img_height, img_width),
    batch_size=batch_size)

我们可以通过class_names输出数据集的标签。标签将按字母顺序对应于目录名称。

class_names = train_ds.class_names
print(class_names)

输出:

[‘Bananaquit’, ‘Black Skimmer’, ‘Black Throated Bushtiti’, ‘Cockatoo’]

4. 配置数据集

AUTOTUNE = tf.data.experimental.AUTOTUNE

train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

5. 可视化数据

plt.figure(figsize=(10, 4))

for images, labels in train_ds.take(1):
    for i in range(8):
        ax = plt.subplot(2, 4, i+1)
        plt.imshow(images[i].numpy().astype('uint8'))
        plt.title(class_names[labels[i]])
        plt.axis('off')

在这里插入图片描述

6、构建DenseNet121网络

from keras import layers

def _DenseLayer(x, growth_rate, bn_size, drop_rate):

    y = layers.BatchNormalization()(x)
    y = layers.ReLU()(x)
    y = layers.Conv2D(bn_size * growth_rate, kernel_size=1, use_bias=False)(x)

    y = layers.BatchNormalization()(y)
    y = layers.ReLU()(y)
    y = layers.Conv2D(growth_rate, kernel_size=3, padding='same', use_bias=False)(y)

    if drop_rate > 0:
        y = layers.Dropout(drop_rate)(y)
    return layers.concatenate([x, y])

def _DenseBlock(x, num_layers, growth_rate, bn_size, drop_rate):
    for i in range(num_layers):
        x = _DenseLayer(x, growth_rate, bn_size, drop_rate)

    return x

def _Transition(x, reduction):
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
    x = layers.Conv2D(int(x.shape[-1] * reduction), kernel_size=1, use_bias=False)(x)
    x = layers.AveragePooling2D(pool_size=2, strides=2)(x)
    return x


def DenseNet121(input_shape=(224, 224, 3), growth_rate=32, num_init_features=64, drop_rate=0.0, num_classes=1000):

    img_input = layers.Input(shape=input_shape)

    x = layers.Conv2D(num_init_features, kernel_size=7, strides=2, padding='same')(img_input)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
    x = layers.MaxPooling2D((3, 3), strides=2, padding='same')(x)


    x = _DenseBlock(x, num_layers=6, growth_rate=growth_rate, bn_size=4, drop_rate=drop_rate)
    x = _Transition(x, reduction=0.5)

    x = _DenseBlock(x, num_layers=12, growth_rate=growth_rate, bn_size=4, drop_rate=drop_rate)
    x = _Transition(x, reduction=0.5)

    x = _DenseBlock(x, num_layers=24, growth_rate=growth_rate, bn_size=4, drop_rate=drop_rate)
    x = _Transition(x, reduction=0.5)

    x = _DenseBlock(x, num_layers=16, growth_rate=growth_rate, bn_size=4, drop_rate=drop_rate)

    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)

    x = layers.GlobalAveragePooling2D()(x)
    x = layers.Dense(num_classes, activation='softmax')(x)

    model = keras.Model(inputs=img_input, outputs=x)
    return model

model = DenseNet121(input_shape=(224, 224, 3), num_classes=1000)
model.summary()

7、编译

opt = tf.keras.optimizers.Adam(learning_rate=1e-4)
model.compile(optimizer=opt,
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

8、训练模型

epochs = 20
history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=epochs
)
Epoch 1/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 111s 2s/step - accuracy: 0.3597 - loss: 5.3345 - val_accuracy: 0.3628 - val_loss: 7.0990
Epoch 2/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 15s 164ms/step - accuracy: 0.7643 - loss: 1.6243 - val_accuracy: 0.4513 - val_loss: 5.3195
Epoch 3/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 5s 150ms/step - accuracy: 0.8274 - loss: 0.8932 - val_accuracy: 0.2655 - val_loss: 9.8976
Epoch 4/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 5s 152ms/step - accuracy: 0.8788 - loss: 0.4807 - val_accuracy: 0.4071 - val_loss: 4.5555
Epoch 5/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 5s 159ms/step - accuracy: 0.9197 - loss: 0.2717 - val_accuracy: 0.4690 - val_loss: 2.9667
Epoch 6/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 5s 163ms/step - accuracy: 0.9485 - loss: 0.2375 - val_accuracy: 0.7168 - val_loss: 1.2835
Epoch 7/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 5s 150ms/step - accuracy: 0.9724 - loss: 0.1271 - val_accuracy: 0.7168 - val_loss: 1.0972
Epoch 8/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 4s 153ms/step - accuracy: 0.9792 - loss: 0.1039 - val_accuracy: 0.7080 - val_loss: 1.1467
Epoch 9/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 5s 148ms/step - accuracy: 0.9972 - loss: 0.0524 - val_accuracy: 0.8938 - val_loss: 0.4605
Epoch 10/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 5s 161ms/step - accuracy: 1.0000 - loss: 0.0273 - val_accuracy: 0.8584 - val_loss: 0.4196
Epoch 11/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 4s 148ms/step - accuracy: 1.0000 - loss: 0.0158 - val_accuracy: 0.9027 - val_loss: 0.3243
Epoch 12/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 4s 146ms/step - accuracy: 1.0000 - loss: 0.0092 - val_accuracy: 0.9027 - val_loss: 0.3552
Epoch 13/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 5s 151ms/step - accuracy: 1.0000 - loss: 0.0106 - val_accuracy: 0.9204 - val_loss: 0.3046
Epoch 14/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 4s 146ms/step - accuracy: 1.0000 - loss: 0.0067 - val_accuracy: 0.9027 - val_loss: 0.3239
Epoch 15/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 4s 146ms/step - accuracy: 1.0000 - loss: 0.0066 - val_accuracy: 0.9027 - val_loss: 0.3064
Epoch 16/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 6s 162ms/step - accuracy: 1.0000 - loss: 0.0053 - val_accuracy: 0.9027 - val_loss: 0.2987
Epoch 17/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 4s 146ms/step - accuracy: 1.0000 - loss: 0.0045 - val_accuracy: 0.9027 - val_loss: 0.3208
Epoch 18/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 4s 148ms/step - accuracy: 1.0000 - loss: 0.0046 - val_accuracy: 0.9027 - val_loss: 0.3119
Epoch 19/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 4s 152ms/step - accuracy: 1.0000 - loss: 0.0062 - val_accuracy: 0.9027 - val_loss: 0.3093
Epoch 20/20
29/29 ━━━━━━━━━━━━━━━━━━━━ 4s 148ms/step - accuracy: 1.0000 - loss: 0.0050 - val_accuracy: 0.9027 - val_loss: 0.3102

9、模型评估

acc = history.history['accuracy']
val_acc = history.history['val_accuracy']

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs_range = range(epochs)

plt.figure(figsize=(12, 4))

plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

在这里插入图片描述

三、总结

ResNet引入了残差模块,每个模块中都有一个恒等映射(identity mapping),即输入 x 加到输出中:F(x) + x,其中 F(x) 是卷积后的结果。这样,网络可以通过学习残差函数来加速收敛,而不是直接学习完整的映射;

而DenseNet 的核心思想是密集连接,DenseNet 中每一层与之前所有层的输出相连。即对于每一层,它都接收之前所有层的特征图作为输入,并将自己的输出传递给后面的所有层。这种结构保证了特征重用,并减少了网络参数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2205910.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

H3C IPsec over GRE VPN 实验

H3C IPsec over GRE VPN 实验 实验拓扑 ​​ 实验需求 按照图示配置 IP 地址,R1 和 R3 配置 Loopback0 口模拟业务网段R1 和 R3 上配置默认路由连通公网R1 和 R3 上配置 IPsec over GRE VPN 来连通两端内网R1 和 R3 配置 OSPF 来传递内网路由实验步骤 按照图示配置 IP 地址…

b站视频下载, b站视频下载助手 如何下载哔哩哔哩视频

1. 链接: 哔哩哔哩(bilibili)视频解析下载 - 保存B站视频到手机、电脑 2. 下载即可

多线程——线程安全

目录 前言 一、观察线程不安全 二、线程安全概念 三、产生线程安全问题的原因 1.分析示例代码 2.线程随机调度 3.修改共享数据 4.原子性 5.可见性 6.指令重排序 四、解决示例代码的问题 结尾 前言 我们学习多线程编程的目的是为了能够实现“并发编程”,…

WAFER连接器在现代电子领域的多样化应用

WAFER连接器是一种广泛应用于现代电子设备中的连接组件,其设计和功能使其在多种应用场景中表现出色。作为一种高效、可靠的连接解决方案,WAFER连接器凭借其小巧、精密的设计赢得了工程师和设计师的青睐。这篇文章将探讨WAFER连接器在不同行业和应用领域中…

力扣第1题:两数之和(图解版)

Golang版本 func twoSum(nums []int, target int) []int {m : make(map[int]int)for i : range nums {if _, ok : m[target - nums[i]]; ok {return []int{i, m[target - nums[i]]}} m[nums[i]] i}return nil }

pip install ERROR: Could not install packages due to an OSError

问题解决 pip install xxx报错: WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) ERROR: Could not install packages due to an OSError 使用 pip install xxx --user 安装

游离的 HEAD 如何解决

简介 问题描述:使用 IDEA 在提交代码时,禁止提交 如何解决:迁出分支再提交,最后合并到 main 或 master 上 如何解决

面向抽象和面向接口的区别

‌1.概念 01、抽象类 在 Java 中,通过关键字 abstract 定义的类叫做抽象类。Java 是一门面向对象的语言,因此所有的对象都是通过类来描述的;但反过来,并不是所有的类都是用来描述对象的,抽象类就是其中的一种。 以下示…

接口测试常用工具及测试方法

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。 系统对外的接口:比如你要从别的网站或服务器上获取资源或信…

vue基础语法的用法(API组合式风格)

一、项目文件结构 .vscode我们在那个编辑器中编辑时就会有对应的这个文件夹,不是固定的 进行编写代码前先把资源自带的页面删除,以防误导,可以像我一样的删除内容 vue文件结构 二、你好 vue el插值 script代码 v-text插值 script代码 三、…

A2P云短信应用场景

中国联通国际公司产品之 A2P 云短信 在当今这个全球化的商业环境中,企业要想在激烈的市场竞争中脱颖而出,不仅需要提供优质的产品和服务,还需要建立起与客户之间的紧密沟通桥梁。中国联通国际公司凭借其强大的国际通信能力和丰富的行业经验&…

麒麟信安参编《信息技术应用创新 移动智能终端操作系统测试规范》

9月20日,广州信创协会团体标准编制培训会暨参编证书颁发仪式在北京举行。会上颁发了T/GZXC 003-2024《信息技术应用创新 移动智能终端操作系统测试规范》团体标准参编证书。麒麟信安作为重点参编单位之一,凭借在移动智能终端操作系统测试领域的丰富实践经…

Python微震波频散相速分析

🎯要点 在二维均匀介质均匀源中合成互相关函数以便构建波层析成像。闭环系统中微积分计算情景:完美弹性体震波、随机外力对模式的能量分配。开环系统中微积分计算情景:无数震源激发波方程、闭合曲线上的随机源、不相关平面波事件。整理地震波…

鸿蒙NEXT开发-面试题库(最新)

注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…

LUCEDA IPKISS Tutorial 77:在版图一定范围内填充dummy

案例分享:在给定的Shape内填充dummy 所有代码如下: from si_fab import all as pdk from ipkiss3 import all as i3 from shapely.geometry import Polygon, MultiPolygon import numpy as np import matplotlib.pyplot as pltclass CellFilledWithCon…

【AI换脸】Rope一键整合包,实现视频多人实时换脸

随着人工智能技术的发展,人们越来越注重人机交互的趣味性和实用性。AI换脸技术正是在这种背景下兴起的一种创新应用。Rope换脸工具以其易用性和卓越的效果,成为了众多用户和专业人士青睐的对象。 Rope是什么? Rope是一款开源的deepfake软件&…

Redis 的安装与部署(图文)

前言 Redis 暂不支持Windows 系统,官网上只能下载Linux 环境的安装包。但是启用WSL2 就可以在Windows 上运行Linux 二进制文件。[要使此方法工作,需要运行Windows 10 2004版及更高版本或Windows 11]。本文在CentOS Linux 系统上安装最新版Redis&#xf…

健身房预约小程序开发,高效管理健身场馆!

随着社会生活的提高,健身成为了人们在日常生活中的必要选择,而健身房也随之成为了大众经常光顾的地方。健身房预约管理系统是一个便捷预约健身的平台,可以让大众灵活预约,提高健身的便捷性和服务体验。同时,健身场馆也…

JAVA 并发八股

线程与进程区别 进程是正在运行的程序的实例,进程中包含了线程,每个线程执行不同的任务 不同进程使用不同的内存空间,在当前进程下所有线程可以共享内存空间 线程更轻量,线程上下文切换成本一般上要比进程上下文切换低&#xff0…