TensorFlow2实战-系列教程14:Resnet实战2

2024-02-01 09:52

本文主要是介绍TensorFlow2实战-系列教程14:Resnet实战2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🧡💛💚TensorFlow2实战-系列教程 总目录

有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Jupyter Notebook中进行
本篇文章配套的代码资源已经上传

Resnet实战1
Resnet实战2
Resnet实战3

4、训练脚本train.py解读------创建模型

def get_model():model = resnet50.ResNet50()if config.model == "resnet34":model = resnet34.ResNet34()if config.model == "resnet101":model = resnet101.ResNet101()if config.model == "resnet152":model = resnet152.ResNet152()model.build(input_shape=(None, config.image_height, config.image_width, config.channels))model.summary()tf.keras.utils.plot_model(model, to_file='model.png')return model# create model
model = get_model()

调用get_model()函数构建模型

get_model()函数:

  1. 通过resnet50.py调用ResNet50类,构建ResNet50模型
  2. 如果在配置参数中设置的是"resnet34"、“resnet101”、“resnet152”,则会对应使用(resnet34.py调用ResNet34类,构建ResNet34模型)、(resnet101.py调用ResNet101类,构建ResNet101模型)、(resnet152.py调用ResNet152类,构建ResNet152模型)
  3. 准备模型以供训练或评估,
  4. 输出模型的概览
  5. 创建了模型的结构图,plot_model 函数从 Keras 工具包中生成模型的可视化表示,指定了保存路径

5、模型构建解析------models/resnet50.py

import tensorflow as tf
from models.residual_block import build_res_block_2
from config import NUM_CLASSESclass ResNet50(tf.keras.Model):def __init__(self, num_classes=NUM_CLASSES):super(ResNet50, self).__init__()self.pre1 = tf.keras.layers.Conv2D(filters=64, kernel_size=(7, 7), strides=2, padding='same')self.pre2 = tf.keras.layers.BatchNormalization()self.pre3 = tf.keras.layers.Activation(tf.keras.activations.relu)self.pre4 = tf.keras.layers.MaxPool2D(pool_size=(3, 3), strides=2)self.layer1 = build_res_block_2(filter_num=64, blocks=3)self.layer2 = build_res_block_2(filter_num=128, blocks=4, stride=2)self.layer3 = build_res_block_2(filter_num=256, blocks=6, stride=2)self.layer4 = build_res_block_2(filter_num=512, blocks=3, stride=2)self.avgpool = tf.keras.layers.GlobalAveragePooling2D()self.fc1 = tf.keras.layers.Dense(units=1000, activation=tf.keras.activations.relu)self.drop_out = tf.keras.layers.Dropout(rate=0.5)self.fc2 = tf.keras.layers.Dense(units=num_classes, activation=tf.keras.activations.softmax)def call(self, inputs, training=None, mask=None):pre1 = self.pre1(inputs)pre2 = self.pre2(pre1, training=training)pre3 = self.pre3(pre2)pre4 = self.pre4(pre3)l1 = self.layer1(pre4, training=training)l2 = self.layer2(l1, training=training)l3 = self.layer3(l2, training=training)l4 = self.layer4(l3, training=training)avgpool = self.avgpool(l4)fc1 = self.fc1(avgpool)drop = self.drop_out(fc1)out = self.fc2(drop)return out

class ResNet50(tf.keras.Model),这个类定义了ResNet50模型的结构,以及前向传播的方式、顺序

ResNet50类解析:

  1. 构造函数,传入了预测的类别数
  2. 初始化
  3. pre1 ,定义一个二维卷积,输出64个特征图,7x7的卷积,步长为2
  4. pre2 ,定义一个批归一化
  5. pre3,定义一个ReLU激活函数
  6. pre4,一个二维的最大池化
  7. 依次通过build_res_block_2()函数定义4个残差块
  8. 定义一个全局平均池化
  9. 定义一个全连接层,输出维度为1000
  10. 定义一个dropout
  11. 定义一个输出层的全连接层
  12. 前向传播函数,传入输入值
  13. 依次经过pre1、pre2、pre3、pre4,即卷积、批归一化、ReLU、最大池化
  14. 依次经过layer1 、layer2 、layer3 、layer4 等四个残差块
  15. 将layer4 的输出经过平局池化
  16. 依次经过两个全连接层

6、模型构建解析------models/residual_block.py

  • BottleNeck类
  • build_res_block_2()函数
  • build_res_block_2()函数通过调用BottleNeck类构建残差块
class BottleNeck(tf.keras.layers.Layer):def __init__(self, filter_num, stride=1,with_downsample=True):super(BottleNeck, self).__init__()self.with_downsample = with_downsampleself.conv1 = tf.keras.layers.Conv2D(filters=filter_num, kernel_size=(1, 1), strides=1, padding='same')self.bn1 = tf.keras.layers.BatchNormalization()self.conv2 = tf.keras.layers.Conv2D(filters=filter_num, kernel_size=(3, 3), strides=stride, padding='same')self.bn2 = tf.keras.layers.BatchNormalization()self.conv3 = tf.keras.layers.Conv2D(filters=filter_num * 4, kernel_size=(1, 1), strides=1, padding='same')self.bn3 = tf.keras.layers.BatchNormalization()self.downsample = tf.keras.Sequential()self.downsample.add(tf.keras.layers.Conv2D(filters=filter_num * 4, kernel_size=(1, 1), strides=stride))self.downsample.add(tf.keras.layers.BatchNormalization())def call(self, inputs, training=None):identity = self.downsample(inputs)conv1 = self.conv1(inputs)bn1 = self.bn1(conv1, training=training)relu1 = tf.nn.relu(bn1)conv2 = self.conv2(relu1)bn2 = self.bn2(conv2, training=training)relu2 = tf.nn.relu(bn2)conv3 = self.conv3(relu2)bn3 = self.bn3(conv3, training=training)if self.with_downsample == True:output = tf.nn.relu(tf.keras.layers.add([identity, bn3]))else:output = tf.nn.relu(tf.keras.layers.add([inputs, bn3]))return output

BottleNeck类解析:

  1. 继承tf.keras.layers.Layer
  2. 构造函数,传入 特征图个数、步长、是否下采样等参数
  3. 初始化
  4. 是否进行下采样参数
  5. 定义一个1x1,步长为1的二维卷积conv1
  6. conv1 对应的批归一化
  7. 定义一个3x3,步长为1的二维卷积conv2
  8. conv2 对应的批归一化
  9. 定义一个3x3,步长为1的二维卷积conv2
  10. conv3 对应的批归一化
  11. 定义一个下采样层(self.downsample),这个层是一个包含卷积层和批量归一化的 Sequential 模型,用于匹配输入和残差的维度
  12. call()函数为前向传播
  13. 应用下采样
  14. 应用三层卷积和批量归一化以及对应的ReLU
  15. with_downsample == True:
  16. 启用下采样,将下采样后的输入(identity)与最后一个卷积层的输出(bn3)相加
  17. 没有启用下采样,将原始输入(inputs)与最后一个卷积层的输出(bn3)相加
def build_res_block_2(filter_num, blocks, stride=1):res_block = tf.keras.Sequential()res_block.add(BottleNeck(filter_num, stride=stride))for _ in range(1, blocks):res_block.add(BottleNeck(filter_num, stride=1,with_downsample=False))    return res_block

build_res_block_2函数解析:

  1. 这个函数构建了一个包含多个BottleNeck层的残差块
  2. filter_num 是每个瓶颈层内卷积层的过滤器数量
  3. blocks 是要添加到顺序模型中的瓶颈层的数量
  4. stride 是卷积的步长,默认为 1
  5. 该函数初始化一个 Sequential 模型,并添加一个 BottleNeck 层作为第一层
  6. 然后,它迭代地添加额外的 BottleNeck 层,每个层的 stride=1 且
    with_downsample=False(除第一个之外)
  7. 此函数返回组装好的顺序模型,代表一个残差块

Resnet实战1
Resnet实战2
Resnet实战3

这篇关于TensorFlow2实战-系列教程14:Resnet实战2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/666884

相关文章

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Java 正则表达式的使用实战案例

《Java正则表达式的使用实战案例》本文详细介绍了Java正则表达式的使用方法,涵盖语法细节、核心类方法、高级特性及实战案例,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、正则表达式语法详解1. 基础字符匹配2. 字符类([]定义)3. 量词(控制匹配次数)4. 边

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变