【深度学习_TensorFlow】卷积神经网络(CNN)

这篇具有很好参考价值的文章主要介绍了【深度学习_TensorFlow】卷积神经网络(CNN)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

写在前面

这篇文章的行文思路如下:

  1. 先根据视频了解卷积和卷积神经网络的整体框架

  2. 接着了解卷积神经网络构建过程中的一些重要操作,包括内积、填充、池化。

  3. 然后介绍卷积层如何实现。

  4. 最后用卷积神经网络的开山之作(LeNet-5)来进行上手练习。

一、初识卷积

最近学习信号与系统的时候,了解了卷积的相关概念,联想起此前学习opencv的时候也有卷积操作,到现在学到深度学习的时候又碰到了卷积神经网络,但是也一直搞不懂为什么要那样做,有什么意义,于是查阅相关博客视频,发现视频比博客直观的多,于是多分享几个制作精良的视频,帮你从数学定义、信号处理、图像处理、现实应用多维度了解卷积!

卷积在声乐中体现(了解即可) 卷积究竟卷了啥?——17分钟了解什么是卷积
卷积在图像中应用 【卷积神经网络】为什么卷积哪儿都能用?
卷积物理意义、卷积在矩阵运算 【卷积】直观形象的实例,10分钟彻底搞懂
卷积神经网络解释 【卷积神经网络】8分钟搞懂CNN,动画讲解喜闻乐见
卷积神经网络解释 什么是卷积神经网络CNN?【知多少】
卷积神经网络 【数之道 08】走进"卷积神经网络",了解图像识别背后的原理
神经网络可视化网站 https://poloclub.github.io/cnn-explainer/

虽然这些视频讲解不尽相同,但是里面有大量的共同点,我们就只讨论卷积在神经网络中应用,有几点可以串联补充

1. 卷积优势

全连接的劣势就是卷积的优势。全连接层的参数量极大,具体可以体现在:假设一张图像输入的像素量为 28×28=784,我们将权值 w 和偏置 b 视为参数(每两个节点之间的参数w和b不一定相同),对于输入节点为 784,输出节点为 256 的第一层网络来说,总参数量就为784×256 + 256 = 200960(后面的256是b),这仅仅只是28×28的图像在第一层的参数量,更大的图像,更多的层数,就意味着更加恐怖的参数量!更难的特征提取!

【深度学习_TensorFlow】卷积神经网络(CNN),# TensorFlow深度学习,深度学习,tensorflow,cnn
【深度学习_TensorFlow】卷积神经网络(CNN),# TensorFlow深度学习,深度学习,tensorflow,cnn

2. 局部相关

为解决全连接层的缺陷,我们引入局部相关的概念,其实也挺容易理解的,对于一张图像,并非所有像素点都是重要的,就如手写数字识别中,手写数字才是关键,其他的背景部分都是次要的。因此关注的中心可以进一步缩小。将全连接层替换为卷积层来简化特征提取。具体的卷积操作如下图所示
【深度学习_TensorFlow】卷积神经网络(CNN),# TensorFlow深度学习,深度学习,tensorflow,cnn

局部相关操作是指使用卷积层中的卷积核,在输入图像上进行滑动,对每个位置进行卷积运算(卷积核与感受野内的图像矩阵进行内积运算,不了解可以搜索内积相关文章)。和信号的卷积运算先反褶、时移、叠加还是稍有些不同的。

3. 填充与池化

先讲讲为什么要进行填充,很明显上面的卷积计算后原来5×5 的图像矩阵,转换为3×3的特征矩阵,这样可能会丢失一些提取出来的特征,例如第一幅图像‘7’未进行填充,经过两个不同的卷积核后,‘7’ 的竖直特征被提取出,但是水平特征却丢失了,解决的办法就是,将原图像矩阵周围填充(如右图),这样水平特征和竖直特征都被提取出来了。(后文实现卷积网络层的方法无需进行手动填充,tensorflow自动帮你实现)

【深度学习_TensorFlow】卷积神经网络(CNN),# TensorFlow深度学习,深度学习,tensorflow,cnn
【深度学习_TensorFlow】卷积神经网络(CNN),# TensorFlow深度学习,深度学习,tensorflow,cnn

池化通常在卷积层之后,我们针对卷积过后的特征图中的小矩阵求最大值,就是最大池化;小矩阵中的数求平均值就是平均池化,从而减少模型参数,提高模型的计算效率和泛化能力,还可以在一定程度上防止过拟合,提高模型的鲁棒性
【深度学习_TensorFlow】卷积神经网络(CNN),# TensorFlow深度学习,深度学习,tensorflow,cnn

二、卷积神经网络

接下来,我们以一个经典的卷积模型 LeNet-5 来学习卷积神经网络。这个卷积模型是Yann LeCun 等人在1998年提出的,非常适合初学者学习,我们稍微修改这个模型,尝试使用 Tensorflow 复现出修改后的模型来,部分操作可能和下图模型不一致,但效果相差不大。
【深度学习_TensorFlow】卷积神经网络(CNN),# TensorFlow深度学习,深度学习,tensorflow,cnn

为了方便,我们仍然使用之前的 mnist 数据集来作为输入数据,图像的尺寸为 28×28,初始张量为[b, 28, 28, 1]:

 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 26, 26, 6)         60        
                                                                 
 max_pooling2d (MaxPooling2D  (None, 13, 13, 6)        0         
 )                                                               
                                                                 
 conv2d_1 (Conv2D)           (None, 11, 11, 16)        880       
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 5, 5, 16)         0         
 2D)                                                             
                                                                 
 flatten (Flatten)           (None, 400)               0         
                                                                 
 dense (Dense)               (None, 120)               48120     
                                                                 
 dense_1 (Dense)             (None, 84)                10164     
                                                                 
 dense_2 (Dense)             (None, 10)                850       
                                                                 
=================================================================
  1. 经过一个卷积层(convolution),得到[b, 26, 26, 6]形状的张量,由于代码没有填充,故张量尺寸会缩减,具体的计算公式如下:其中(b, h’, w’, c)的张量,卷积核的数量c,卷积核的大小k,步长s, p h p_h ph表示上下填充行数(只考虑两端相等), p w p_w pw表示左右填充列数(只考虑相等情况),在这里

h ′ = [ h + 2 ⋅ p h − k s ] + 1 h'=\left[\frac{h+2\cdot p_h-k}{s}\right]+1 h=[sh+2phk]+1

h ′ = [ h + 2 ⋅ p w − k s ] + 1 h'=\left[\frac{h+2\cdot p_w-k}{s}\right]+1 h=[sh+2pwk]+1

在第一层卷积,就可以使用上面的公式来计算,括号里面向下取整

h ′ = [ 28 + 2 ∗ 0 − 3 1 ] + 1 = ⌊ 25 ⌋ + 1 = 26 w ′ = [ 28 + 2 ∗ 0 − 3 1 ] + 1 = ⌊ 25 ⌋ + 1 = 26 \begin{aligned}h^{\prime} & =\left[\frac{28+2*0-3}{1}\right]+1=\lfloor25\rfloor+1=26\\ & \\ w^{\prime} & =\left[\frac{28+2*0-3}{1}\right]+1=\lfloor25\rfloor+1=26\end{aligned} hw=[128+203]+1=25+1=26=[128+203]+1=25+1=26


  1. 经过一个向下采样层,张量尺寸缩小为[b, 13, 13, 6],这里我们使用池化层来实现;

  2. 经过第二个卷积层,得到[b, 11, 11, 16]的张量;

  3. 经过第二个向下采样层,张量尺寸缩小为[b, 5, 5, 16],这里我们使用池化层实现;

  4. 将张量打平为[b, 400],之后进入三个节点为 120、84、10 的全连接层将结果矩阵输出


三、卷积实现

由于使用卷积神经网络进行手写数字识别和之前的使用全连接层实现的手写数字识别的代码极为相似,只需将网络层的地方修改即可,所以就不再介绍其它部分的代码,不了解的可以查阅**这篇文章 ,**在tensorflow中卷积的实现主要有下面两种方式,自定义方式函数的方式和卷积层的方式

1. 自定义权值

tf.nn.conv2d(input, kernel, strides=1, padding=[[0, 0], [0, 0], [0, 0], [0, 0]])

input:输入数据图像,例如[100, 28, 28, 3]表示 100 张 28×28的三通道图像。

kernel:卷积核,例如[3, 3, 3, 4] 表示4个 3×3 的三通道的卷积核

strides:表示步长

padding:表示填充,填充的具体数量由tensorflow自动计算并完成

input = tf.random.normal([100, 28, 28, 3])
w = tf.random.normal([3, 3, 4, 3])

out = tf.nn.conv2d(x, w, strides=1, padding=[[0, 0], [0, 0], [0, 0], [0, 0]])

2. 卷积层的实现

还有更为常见的层方式实现:

# strides=1, padding='same',可得到输入输出同大小的卷积层,具体填充操作自动完成
layers = layers.Conv2D(4, kernel_size=3, strides=1, padding='SAME')

四、leNet-5实战

这套代码和之前使用全连接层实现mnist手写数字识别的代码框架是一致的,只是修改了网络层的部分。不了解的可以查看往期专栏文章。

# import tensorflow as tf
# from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics, regularizers
# from tensorflow.keras.callbacks import EarlyStopping
# # 处理每一张图像
# def preprocess(x, y):
#
#     x = tf.cast(x, dtype=tf.float32) / 255.
#     y = tf.one_hot(y, depth=10)
#
#     return x, y
#
# # 数据集读取
# (x, y), (x_test, y_test) = datasets.mnist.load_data()
#
# # 交叉验证切分,防止过拟合的有效手段
# idx = tf.range(60000)  # 按顺序生成索引0~59999
# idx = tf.random.shuffle(idx)  # 将索引打乱
# x_train, y_train = tf.gather(x, idx[:50000]), tf.gather(y, idx[:50000])
# x_val, y_val = tf.gather(x, idx[-10000:]), tf.gather(y, idx[-10000:])
#
# # 训练集
# train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train))
# train_db = train_db.map(preprocess).shuffle(10000).batch(128).repeat(5)  # 这里粗暴的重复数据增加数据集,repeat改小训练时间缩短
#
# # 验证集
# val_db = tf.data.Dataset.from_tensor_slices((x_val, y_val))
# val_db = val_db.map(preprocess).shuffle(10000).batch(128)
#
# # 测试集
# test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test))
# test_db = test_db.map(preprocess).shuffle(10000).batch(128)
#
# # 定义早停法回调函数
# early_stopping = EarlyStopping(monitor='val_loss',  # 监视验证集loss
#                                patience=3,  # 当验证集loss在2个epoch内都没有改善则停止训练
#                                mode='min',  # 监测loss时一般设置为min,监测准确值时一般设置为max
#                                verbose=1,  # 检测值改善时打印一条信息
#                                restore_best_weights=True  # 将权重恢复到最好的一个epoch
#                                )
#
# # 网络构建
# # 正则化:在模型损失函数中加入权重参数的L2范数作为惩罚项,力度由0.001控制。
# network = Sequential([
#                       layers.Reshape(target_shape=(28, 28, 1), input_shape=(28, 28)),  # 这里指定了层,就不需要在process里进行reshape了,也不需要built构建参数了
#                       layers.Conv2D(6, kernel_size=3, strides=1),  # 6个3×3的卷积核,步长设置为1
#                       layers.MaxPooling2D(pool_size=(2, 2), strides=2),  # 高宽减半的池化层
#                       layers.Conv2D(16, kernel_size=3, strides=1),  # 第二个卷积层,16个3×3的卷积核
#                       layers.MaxPooling2D(pool_size=(2, 2), strides=2),  # 高宽减半的池化层
#                       layers.Flatten(),  # 打平,方便连接全连接层
#                       layers.Dense(120, kernel_regularizer=regularizers.l2(0.001), activation='relu'),
#                       layers.Dense(84, kernel_regularizer=regularizers.l2(0.001), activation='relu'),
#                       layers.Dense(10)
#                     ])
#
# # 参数构建
# # network.build(input_shape=(None, 28, 28, 1))  # 由于第一层已经指定好大小了,所以这里不构建也可以
# # 模型展示
# network.summary()
# # 模型装配
# network.compile(optimizer=optimizers.Adam(learning_rate=0.01),
#                 loss=tf.losses.CategoricalCrossentropy(from_logits=True),
#                 metrics=['accuracy'])
# # 模型训练,这里控制训练次数
# network.fit(train_db, epochs=50,
#             validation_data=val_db, validation_steps=10,
#             callbacks=[early_stopping])
# # 模型评估
# print('模型评估:')
# network.evaluate(test_db)

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# 这两段代码框架一致,只是在不同位置进行了数据处理,注意辨别
import tensorflow as tf
from tensorflow.keras import datasets, layers, optimizers, Sequential, regularizers
from tensorflow.keras.callbacks import EarlyStopping

# 处理每一张图像
def preprocess(x, y):
    x = tf.cast(x, dtype=tf.float32) / 255.
    x = tf.reshape(x, [28, 28, 1])
    y = tf.cast(y, dtype=tf.int32)
    y = tf.one_hot(y, depth=10)
    return x, y

# 数据集读取
(x, y), (x_test, y_test) = datasets.mnist.load_data()

# 交叉验证切分,防止过拟合的有效手段
idx = tf.range(60000)  # 按顺序生成索引0~59999
idx = tf.random.shuffle(idx)  # 将索引打乱
x_train, y_train = tf.gather(x, idx[:50000]), tf.gather(y, idx[:50000])
x_val, y_val = tf.gather(x, idx[-10000:]), tf.gather(y, idx[-10000:])

# 训练集
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_db = train_db.map(preprocess).shuffle(10000).batch(128).repeat(10)

# 验证集
val_db = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_db = val_db.map(preprocess).shuffle(10000).batch(128)

# 测试集
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_db = test_db.map(preprocess).shuffle(10000).batch(128)

# 定义早停法回调函数
early_stopping = EarlyStopping(monitor='val_loss',  # 监视验证集loss
                               patience=3,  # 当验证集loss在2个epoch内都没有改善则停止训练
                               mode='min',  # 监测loss时一般设置为min,监测准确值时一般设置为max
                               verbose=1,  # 检测值改善时打印一条信息
                               restore_best_weights=True  # 将权重恢复到最好的一个epoch
                               )

network = Sequential([
                      layers.Conv2D(6, kernel_size=3, strides=1),  # 6个3×3的卷积核,步长设置为1
                      layers.MaxPooling2D(pool_size=(2, 2), strides=2),  # 高宽减半的池化层
                      layers.Conv2D(16, kernel_size=3, strides=1),  # 第二个卷积层,16个3×3的卷积核
                      layers.MaxPooling2D(pool_size=(2, 2), strides=2),  # 高宽减半的池化层
                      layers.Flatten(),  # 打平,方便连接全连接层
                      layers.Dense(120, kernel_regularizer=regularizers.l2(0.001), activation='relu'),
                      layers.Dense(84, kernel_regularizer=regularizers.l2(0.001), activation='relu'),
                      layers.Dense(10)
                    ])

# 参数构建
network.build(input_shape=(None, 28, 28, 1))
# 模型展示
network.summary()

# 模型装配
network.compile(optimizer=optimizers.Adam(learning_rate=0.01),
                loss=tf.losses.CategoricalCrossentropy(from_logits=True),
                metrics=['accuracy'])
# 模型训练,这里控制训练次数
network.fit(train_db, epochs=50,
            validation_data=val_db, validation_steps=10,
            callbacks=[early_stopping])
# 模型评估
print('模型评估:')
network.evaluate(test_db)

写在最后

👍🏻点赞,你的认可是我创作的动力!
⭐收藏,你的青睐是我努力的方向!
✏️评论,你的意见是我进步的财富!文章来源地址https://www.toymoban.com/news/detail-730119.html

到了这里,关于【深度学习_TensorFlow】卷积神经网络(CNN)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深度学习03-卷积神经网络(CNN)

    CNN,即卷积神经网络(Convolutional Neural Network),是一种常用于图像和视频处理的深度学习模型。与传统神经网络相比,CNN 有着更好的处理图像和序列数据的能力,因为它能够自动学习图像中的特征,并提取出最有用的信息。 CNN 的一个核心特点是卷积操作,它可以在图像上进

    2024年02月05日
    浏览(54)
  • 深度学习入门教学——卷积神经网络CNN

    1、应用领域 检测任务 分类与检索 超分辨率重构 2、卷积网络与传统网咯的区别 传统神经网络和卷积神经网络都是用来 提取特征 的。 神经网络: 可以将其看作是一个二维的。 卷积神经网络: 可以将其看作是一个三维的。  3、整体框架 该层主要是对原始图像数据进行预处

    2024年02月10日
    浏览(24)
  • 深度学习入门(三):卷积神经网络(CNN)

    给定一张图片,计算机需要模型判断图里的东西是什么? (car、truck、airplane、ship、horse) CONV:卷积计算层,线性乘积求和 RELU:激励层,激活函数 POOL:池化层,取区域平均或最大(MAX POOL) PC:全连接层 对CNN来说,它是一块一块进行对比的,“小块”称之为Features特征。

    2024年02月11日
    浏览(28)
  • 【深度学习】最强算法之:卷积神经网络(CNN)

    小屌丝 :鱼哥, 看下这个流程图,我没看明白 小鱼 :啥流程图。 小屌丝 :你看,就是这个。 小鱼 :嗯,不错,不错。 小屌丝 :能不能给我讲一讲这个? 小鱼 :你要了解CNN ? 小屌丝 :CNN 是? 小鱼 :…你这… 深度学习知道吗? 小屌丝 :知道啊 小鱼 :你都知道深度

    2024年04月09日
    浏览(28)
  • 学习笔记:深度学习(3)——卷积神经网络(CNN)理论篇

    学习时间:2022.04.10~2022.04.12 CNN(Convolutional Neural Networks, ConvNets, 卷积神经网络)是神经网络的一种,是理解图像内容的最佳学习算法之一,并且在图像分割、分类、检测和检索相关任务中表现出色。 3.1.1 什么是CNN? CNN是一种带有卷积结构的前馈神经网络, 卷积结构 可以减少

    2024年02月03日
    浏览(69)
  • 深度学习入门——卷积神经网络CNN基本原理+实战

    ​ 卷积神经网络(Convolutional Neural Network,CNN)是深度学习技术中最基础的网络结构,模拟人脑工作,具备强大的特征学习能力。CNN结构主要由两部分组成:特征提取部分和分类部分color{blue}{特征提取部分和分类部分}特征提取部分和分类部分。特征提取部分网络将执行一系列

    2024年01月21日
    浏览(36)
  • 【深度学习】6-4 卷积神经网络 - CNN的实现

    CNN的实现 网络的构成是“Convolution - ReLU - Pooling -Affine - ReLU - Affine - Softmax”,我们将它实现为名为 SimpleConvNet 的类。 首先来看一下 SimpleConvNet的初始化( init ),取下面这些参数。 input_dim——输入数据的维度:(通道,高,长) conv_param——卷积层的超参数(字典)。字典的

    2024年02月10日
    浏览(34)
  • Pytorch 与 Tensorflow对比学习 第3周:进阶主题 Day 15-16: 卷积神经网络(CNN)

    第3周:进阶主题 Day 15-16: 卷积神经网络(CNN) 在这两天中,我专注于学习卷积神经网络(CNN)的基础知识,包括卷积层和池化层的工作原理以及它们在图像处理中的应用。 卷积神经网络基础: 卷积层:学习了卷积层如何通过滤波器(或称为核)提取图像的特征。每个滤波器

    2024年01月20日
    浏览(32)
  • 深度学习实战——卷积神经网络/CNN实践(LeNet、Resnet)

          忆如完整项目/代码详见github: https://github.com/yiru1225 (转载标明出处 勿白嫖 star for projects thanks) 本系列博客重点在深度学习相关实践(有问题欢迎在评论区讨论指出,或直接私信联系我)。 第一章  深度学习实战——不同方式的模型部署(CNN、Yolo)_如何部署cnn_

    2023年04月11日
    浏览(29)
  • 文本分类系统Python,基于深度学习CNN卷积神经网络

    文本分类系统,使用Python作为主要开发语言,通过TensorFlow搭建CNN卷积神经网络对十余种不同种类的文本数据集进行训练,最后得到一个h5格式的本地模型文件,然后采用Django开发网页界面,实现用户在界面中输入一段文字,识别其所属的文本种类。 在我们的日常生活和工作中

    2024年02月08日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包