动手学深度学习学习笔记tf2.0版(5.9 含并行连结的网络(GoogLeNet))

2024-02-12 05:32

本文主要是介绍动手学深度学习学习笔记tf2.0版(5.9 含并行连结的网络(GoogLeNet)),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GoogLeNet学习笔记

github代码地址:https://github.com/taichuai/d2l_zh_tensorflow2.0

在这里插入图片描述

在这里插入图片描述
模型结构仔细理解一下
在这里插入图片描述

import tensorflow as tf
print(tf.__version__)for gpu in tf.config.experimental.list_physical_devices('GPU'):tf.config.experimental.set_memory_growth(gpu, True)class Inception(tf.keras.layers.Layer):def __init__(self,c1, c2, c3, c4):super().__init__()# 线路1,单1 x 1卷积层self.p1_1 = tf.keras.layers.Conv2D(c1, kernel_size=1, activation='relu', padding='same')# 线路2,1 x 1卷积层后接3 x 3卷积层self.p2_1 = tf.keras.layers.Conv2D(c2[0], kernel_size=1, padding='same', activation='relu')self.p2_2 = tf.keras.layers.Conv2D(c2[1], kernel_size=3, padding='same',activation='relu')# 线路3,1 x 1卷积层后接5 x 5卷积层self.p3_1 = tf.keras.layers.Conv2D(c3[0], kernel_size=1, padding='same', activation='relu')self.p3_2 = tf.keras.layers.Conv2D(c3[1], kernel_size=5, padding='same',activation='relu')# 线路4,3 x 3最大池化层后接1 x 1卷积层self.p4_1 = tf.keras.layers.MaxPool2D(pool_size=3, padding='same', strides=1)self.p4_2 = tf.keras.layers.Conv2D(c4, kernel_size=1, padding='same', activation='relu')def call(self, x):p1 = self.p1_1(x)p2 = self.p2_2(self.p2_1(x))p3 = self.p3_2(self.p3_1(x))p4 = self.p4_2(self.p4_1(x))return tf.concat([p1, p2, p3, p4], axis=-1)  # 在通道维上连结输出Inception(64, (96, 128), (16, 32), 32)

在这里插入图片描述

b1 = tf.keras.models.Sequential()
b1.add(tf.keras.layers.Conv2D(64, kernel_size=7, strides=2, padding='same', activation='relu'))
b1.add(tf.keras.layers.MaxPool2D(pool_size=3, strides=2, padding='same'))

第二模块使用2个卷积层:首先是64通道的1×11×1卷积层,然后是将通道增大3倍的3×33×3卷积层。它对应Inception块中的第二条线路。

b2 = tf.keras.models.Sequential()
b2.add(tf.keras.layers.Conv2D(64, kernel_size=1, padding='same', activation='relu'))
b2.add(tf.keras.layers.Conv2D(192, kernel_size=3, padding='same', activation='relu'))
b2.add(tf.keras.layers.MaxPool2D(pool_size=3, strides=2, padding='same'))

第三模块串联2个完整的Inception块。第一个Inception块的输出通道数为64+128+32+32=25664+128+32+32=256,其中4条线路的输出通道数比例为64:128:32:32=2:4:1:112832:32=241:164:128:32:32=2:4:1:1。其中第二、第三条线路先分别将输入通道数减小至96/192=1/296/192=1/2和16/192=1/1216/192=1/12后,再接上第二层卷积层。第二个Inception块输出通道数增至128+192+96+64=480128+192+96+64=480,每条线路的输出通道数之比为128:192:96:64=4:6:3:219296:64 = 463:2128:192:96:64=4:6:3:2。其中第二、第三条线路先分别将输入通道数减小至128/256=1/2128/256=1/2和32/256=1/832/256=1/8。

b3 = tf.keras.models.Sequential()
b3.add(Inception(64, (96, 128), (16, 32), 32))
b3.add(Inception(128, (128, 192), (32, 96), 64))
b3.add(tf.keras.layers.MaxPool2D(pool_size=3, strides=2, padding='same'))

第四模块更加复杂。它串联了5个Inception块,其输出通道数分别是192+208+48+64=512192+208+48+64=512、160+224+64+64=512160+224+64+64=512、128+256+64+64=512128+256+64+64=512、112+288+64+64=528112+288+64+64=528和256+320+128+128=832256+320+128+128=832。这些线路的通道数分配和第三模块中的类似,首先含3×33×3卷积层的第二条线路输出最多通道,其次是仅含1×11×1卷积层的第一条线路,之后是含5×55×5卷积层的第三条线路和含3×33×3最大池化层的第四条线路。其中第二、第三条线路都会先按比例减小通道数。这些比例在各个Inception块中都略有不同。

b4 = tf.keras.models.Sequential()
b4.add(Inception(192, (96, 208), (16, 48), 64))
b4.add(Inception(160, (112, 224), (24, 64), 64))
b4.add(Inception(128, (128, 256), (24, 64), 64))
b4.add(Inception(112, (144, 288), (32, 64), 64))
b4.add(Inception(256, (160, 320), (32, 128), 128))
b4.add(tf.keras.layers.MaxPool2D(pool_size=3, strides=2, padding='same'))

第五模块有输出通道数为256+320+128+128=832256+320+128+128=832和384+384+128+128=1024384+384+128+128=1024的两个Inception块。其中每条线路的通道数的分配思路和第三、第四模块中的一致,只是在具体数值上有所不同。需要注意的是,第五模块的后面紧跟输出层,该模块同NiN一样使用全局平均池化层来将每个通道的高和宽变成1。最后我们将输出变成二维数组后接上一个输出个数为标签类别数的全连接层。

b5 = tf.keras.models.Sequential()
b5.add(Inception(256, (160, 320), (32, 128), 128))
b5.add(Inception(384, (192, 384), (48, 128), 128))
b5.add(tf.keras.layers.GlobalAvgPool2D())net = tf.keras.models.Sequential([b1, b2, b3, b4, b5, tf.keras.layers.Dense(10)])

GoogLeNet模型的计算复杂,而且不如VGG那样便于修改通道数。本节里我们将输入的高和宽从224降到96来简化计算。下面演示各个模块之间的输出的形状变化。

X = tf.random.uniform(shape=(1, 96, 96, 1))
for layer in net.layers:X = layer(X)print(layer.name, 'output shape:\t', X.shape)
# 获取数据
from tensorflow.keras.datasets import fashion_mnist
import matplotlib.pyplot as plt(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()# 数据预处理
def data_scale(x, y):x = tf.cast(x, tf.float32)x = x / 255.0x = tf.reshape(x, (x.shape[0], x.shape[1], 1))x = tf.image.resize_with_pad(image=x, target_height=224,target_width=224)return x, y
# 由于笔记本训练太慢了,使用1000条数据,跑一下先,算力够的可以直接使用全部数据更加明显
train_db = tf.data.Dataset.from_tensor_slices((x_train,y_train)).shuffle(20).map(data_scale).batch(64)
test_db = tf.data.Dataset.from_tensor_slices((x_test,y_test)).shuffle(20).map(data_scale).batch(64)
# 定义优化器和损失函数
optimizer = tf.keras.optimizers.SGD(lr=1e-1)
loss = tf.keras.losses.sparse_categorical_crossentropy
net.compile(optimizer=optimizer, loss=loss, metrics=['accuracy'])
net.fit_generator(train_db, epochs=10, validation_data=test_db)    # 这里就不跑太多轮了,有机器可以自己调参跑个好的结果
net.summary()

在这里插入图片描述
由于网络提取特征能力强,所以收敛很快,再看一下中间特征层:

# 展示其中的前八层的特征图
X = next(iter(train_db))[0][0]def show(X, k,i):print(X.shape)X = tf.expand_dims(X, axis=-1)# 将每个图转换为 200 * 200的像素,但这个不是图大小X = tf.image.resize(X,  [200,200], method='bilinear')X_ = tf.squeeze(X)plt.subplot(4, 4,  4*k + i + 1)plt.imshow(X_)X = tf.expand_dims(X, axis=0)# 设置图纸大小
plt.figure(figsize=(10, 10))
# 打印前 4 层的部分特征图
for k,blk in enumerate(net.layers[0:4]):print(blk.name,'itput shape:\t',X.shape)
#     show(X[0,:,:,0])X = blk(X)print(blk.name, 'output shape:\t', X.shape)for i in range(4):show(X[0,:,:,i], k, i)plt.show()

在这里插入图片描述

这篇关于动手学深度学习学习笔记tf2.0版(5.9 含并行连结的网络(GoogLeNet))的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Linux网络配置之网桥和虚拟网络的配置指南

《Linux网络配置之网桥和虚拟网络的配置指南》这篇文章主要为大家详细介绍了Linux中配置网桥和虚拟网络的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、网桥的配置在linux系统中配置一个新的网桥主要涉及以下几个步骤:1.为yum仓库做准备,安装组件epel-re

Spring Boot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)

《SpringBoot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)》:本文主要介绍SpringBoot拦截器Interceptor与过滤器Filter深度解析... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实

MyBatis分页插件PageHelper深度解析与实践指南

《MyBatis分页插件PageHelper深度解析与实践指南》在数据库操作中,分页查询是最常见的需求之一,传统的分页方式通常有两种内存分页和SQL分页,MyBatis作为优秀的ORM框架,本身并未提... 目录1. 为什么需要分页插件?2. PageHelper简介3. PageHelper集成与配置3.

python如何下载网络文件到本地指定文件夹

《python如何下载网络文件到本地指定文件夹》这篇文章主要为大家详细介绍了python如何实现下载网络文件到本地指定文件夹,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...  在python中下载文件到本地指定文件夹可以通过以下步骤实现,使用requests库处理HTTP请求,并结合o

Maven 插件配置分层架构深度解析

《Maven插件配置分层架构深度解析》:本文主要介绍Maven插件配置分层架构深度解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Maven 插件配置分层架构深度解析引言:当构建逻辑遇上复杂配置第一章 Maven插件配置的三重境界1.1 插件配置的拓扑

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与