动手学深度学习学习笔记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

相关文章

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

Java之并行流(Parallel Stream)使用详解

《Java之并行流(ParallelStream)使用详解》Java并行流(ParallelStream)通过多线程并行处理集合数据,利用Fork/Join框架加速计算,适用于大规模数据集和计算密集... 目录Java并行流(Parallel Stream)1. 核心概念与原理2. 创建并行流的方式3. 适

Python与DeepSeek的深度融合实战

《Python与DeepSeek的深度融合实战》Python作为最受欢迎的编程语言之一,以其简洁易读的语法、丰富的库和广泛的应用场景,成为了无数开发者的首选,而DeepSeek,作为人工智能领域的新星... 目录一、python与DeepSeek的结合优势二、模型训练1. 数据准备2. 模型架构与参数设置3

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

五大特性引领创新! 深度操作系统 deepin 25 Preview预览版发布

《五大特性引领创新!深度操作系统deepin25Preview预览版发布》今日,深度操作系统正式推出deepin25Preview版本,该版本集成了五大核心特性:磐石系统、全新DDE、Tr... 深度操作系统今日发布了 deepin 25 Preview,新版本囊括五大特性:磐石系统、全新 DDE、Tree

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如