深度学习入门,Keras Conv2D类参数详解

image-20211029211449671

图4: ResNet“残差模块”使用 1×1 和 3×3 过滤器进行降维。 这有助于用更少的参数使整个网络更小。

那么,您应该如何选择 filter_size ? 首先,检查你的输入图像——它是否大于 128×128? 如果是这样,请考虑使用 5×5 或 7×7 内核来学习更大的特征,然后快速减少空间维度——然后开始使用 3×3 内核:

model.add(Conv2D(32, (7, 7), activation=“relu”))

model.add(Conv2D(32, (3, 3), activation=“relu”))

如果您的图像小于 128×128,您可能需要考虑坚持使用小点的 1×1 和 3×3 过滤器。

strides

==================================================================

strides 参数是一个 2 元组整数,指定沿输入体积的 x 和 y 轴的卷积“步长”。

strides 值默认为 (1, 1) ,这意味着:

  • 给定的卷积滤波器应用于输入体积的当前位置

  • 过滤器向右移动 1 个像素,然后过滤器再次应用于输入体积

  • 这个过程一直执行,直到我们到达体积的最右侧边界,我们将过滤器向下移动一个像素,然后从最左侧重新开始

通常,您会将 strides 参数保留为默认 (1, 1) 值; 但是,您可以偶尔将其增加到 (2, 2) 以帮助减小输出体积的大小(因为滤波器的步长较大)。 通常,您会看到 2×2 步幅作为最大池化的替代:

model.add(Conv2D(128, (3, 3), strides=(1, 1), activation=“relu”))

model.add(Conv2D(128, (3, 3), strides=(1, 1), activation=“relu”))

model.add(Conv2D(128, (3, 3), strides=(2, 2), activation=“relu”))

在这里我们可以看到前两个 Conv2D 层的步幅为 1×1。 最终的 Conv2D 层; 然而,它代替了最大池化层,而是通过跨步卷积减少了输出体积的空间维度。

2014 年,Springenber 等人。 发表了一篇题为 Striving for Simplicity: The All Convolutional Net 的论文,该论文证明在某些情况下用跨步卷积替换池化层可以提高准确性。

ResNet 是一种流行的 CNN,已经接受了这一发现——如果您查看 ResNet 实现的源代码(或自己实现它),您会看到 ResNet 响应跨步卷积而不是最大池化以减少两者之间的空间维度 残余模块。

padding

==================================================================

img

图5: 应用于带有填充的图像的 3×3 内核。 Keras Conv2D 填充参数接受“valid”(无填充)或“same”(填充 + 保留空间维度)。 此动画贡献给 StackOverflow。

Keras Conv2D 类的填充参数可以采用以下两个值之一: valid 或 same 。 使用有效参数,输入体积不会被零填充,并且空间维度可以通过卷积的自然应用减少。 下面的例子自然会减少我们体积的空间维度:

model.add(Conv2D(32, (3, 3), padding=“valid”))

如果您想要保留体积的空间尺寸,以便输出体积大小与输入体积大小匹配,那么您需要为 padding 提供“same”的值:

model.add(Conv2D(32, (3, 3), padding=“same”))

虽然默认的 Keras Conv2D 值是有效的,但我通常会将其设置为网络中大多数层的相同值,

然后通过以下任一方式减少我的体积的空间维度:

​ 最大池化

​ - 跨步卷积

我建议您也使用类似的方法来填充 Keras Conv2D 类。

data_format

=======================================================================

image-20211029211617490

图 6: Keras 作为高级框架,支持多个深度学习后端。 因此,它包括对“channels last”和“channels last”通道排序的支持。

Conv2D 类中的数据格式值可以是 channels_last 或 channels_first : Keras 的 TensorFlow 后端使用最后排序的通道。 Theano 后端使用通道优先排序。

由于以下两个原因,您通常不必像 Keras 那样触及此值:

​ - 您很有可能使用 TensorFlow 后端到 Keras

​ - 如果没有,你可能已经更新了你的 ~/.keras/keras.json 配置文件来设置你的后端和相关的频道排序

我的建议是永远不要在你的 Conv2D 类中明确设置 data_format ,除非你有很好的理由这样做。

dilation_rate

=========================================================================

image-20211029211658301

Figure 7: Keras 深度学习 Conv2D 参数 dilation_rate 接受一个 2 元组整数来控制膨胀卷积。

Conv2D 类的 dilation_rate 参数是一个二元组整数,控制膨胀卷积的膨胀率。 扩张卷积是一种基本卷积,仅应用于具有定义间隙的输入体积,如上图 7 所示。 您可以在以下情况下使用扩张卷积:

​ 1、您正在处理更高分辨率的图像,但细粒度的细节仍然很重要

​ 2、 您正在构建一个参数较少的网络

activation

=====================================================================

image-20211029211807347

图8: Keras 提供了许多常见的激活函数。 Conv2D 的激活参数是一个方便的问题,它允许指定卷积后使用的激活函数。

Conv2D 类的激活参数只是一个方便的参数,允许您提供一个字符串,指定执行卷积后要应用的激活函数的名称。 在以下示例中,我们执行卷积,然后应用 ReLU 激活函数:

model.add(Conv2D(32, (3, 3), activation=“relu”))

等效于:

model.add(Conv2D(32, (3, 3)))

model.add(Activation(“relu”))

我的建议? 如果您可以使用激活参数,并且它有助于保持您的代码更清晰——这完全取决于您,并且不会影响您的卷积神经网络的性能。

use_bias

====================================================================

Conv2D 类的 use_bias 参数控制是否向卷积层添加偏置向量。 通常,您希望将此值保留为 True ,尽管 ResNet 的某些实现会忽略偏差参数。 我建议保持偏见,除非你有充分的理由不这样做。

kernel_initializer 和bias_initializer

=================================================================================================

image-20211029211855079

图9: Keras 为 Conv2D 类提供了许多初始化器。 初始化器可用于帮助更有效地训练更深的神经网络。

kernel_initializer 控制用于在实际训练网络之前初始化 Conv2D 类中的所有值的初始化方法。 类似地,bias_initializer 控制在训练开始之前如何初始化偏置向量。 完整的初始化器列表可以在 Keras 文档中找到; 但是,这是我的建议:

1、不理会bias_initialization——默认情况下它会用零填充(你很少,如果有的话,必须改变bias初始化方法)。

2、kernel_initializer 默认为 glorot_uniform ,这是 Xavier Glorot 统一初始化方法,对于大多数任务来说是完美的; 然而,对于更深层的神经网络,您可能希望使用 he_normal(MSRA/He 等人的初始化),当您的网络具有大量参数(即 VGGNet)时,该方法特别有效。

在我实现的绝大多数 CNN 中,我要么使用 glorot_uniform 要么使用 he_normal——我建议你也这样做,除非你有特定的理由使用不同的初始化程序。

kernel_regularizer、bias_regularizer 和 activity_regularizer

========================================================================================================================

image-20211029211911166

图10: 应该调整正则化超参数,尤其是在处理大型数据集和非常深的网络时。 我经常调整 kernel_regularizer 参数以减少过度拟合并增加模型泛化到不熟悉的图像的能力。

kernel_regularizer 、bias_regularizer 和 activity_regularizer 控制应用于 Conv2D 层的正则化方法的类型和数量。 应用正则化可以帮助您: 减少过拟合的影响 提高模型的泛化能力 在处理大型数据集和深度神经网络时,应用正则化通常是必须的。 通常你会遇到应用 L1 或 L2 正则化的情况——如果我检测到过度拟合的迹象,我将在我的网络上使用 L2 正则化:

from tensorflow.keras.regularizers import l2

model.add(Conv2D(32, (3, 3), activation=“relu”),

kernel_regularizer=l2(0.0005))

您应用的正则化量是您需要针对自己的数据集进行调整的超参数,但我发现 0.0001-0.001 的值是一个很好的开始范围。

我建议不要管你的偏差正则化器——正则化偏差通常对减少过度拟合的影响很小。

我还建议将 activity_regularizer 保留为其默认值(即,没有活动正则化)。

虽然权重正则化方法对权重本身进行操作,f(W),其中 f 是激活函数,W 是权重,但活动正则化器对输出 f(O) 进行操作,其中 O 是层的输出。

除非有非常具体的原因,您希望对输出进行正则化,否则最好不要理会这个参数。

kernel_constraint 和bias_constraint

===============================================================================================

Keras Conv2D 类的最后两个参数是 kernel_constraint 和 bias_constraint 。

这些参数允许您对 Conv2D 层施加约束,包括非负性、单位归一化和最小-最大归一化。

您可以在 Keras 文档中查看受支持约束的完整列表。

同样,除非您有特定原因对 Conv2D 层施加约束,否则我建议您单独保留内核约束和偏差约束。

CALTECH-101(子集)数据集

=============================================================================

image-20211029211938358

图11: CALTECH-101 数据集包含 101 个对象类别,每个类别有 40-80 张图像。 今天博客文章示例的数据集仅包含其中 4 个类:人脸、豹子、摩托车和飞机(来源)。

CALTECH-101 数据集是一个包含 101 个对象类别的数据集,每个类别有 40 到 800 张图像。

大多数图像每类大约有 50 张图像。

数据集的目标是训练一个能够预测目标类别的模型。 在神经网络和深度学习重新兴起之前,最先进的准确率仅为约 65%。

然而,通过使用卷积神经网络,可以达到 90% 以上的准确率(正如 He 等人在他们 2014 年的论文《用于视觉识别的深度卷积网络中的空间金字塔池化》中所证明的那样)。

今天,我们将在数据集的 4 类子集上实现一个简单而有效的 CNN,它能够达到 96% 以上的准确率:

  • Faces: 436 images

  • Leopards: 201 images

  • Motorbikes: 799 images

  • Airplanes: 801 images

我们使用数据集的子集的原因是,即使您没有 GPU,您也可以轻松地按照此示例从头开始训练网络。

同样,本教程的目的并不是要在 CALTECH-101 上提供最先进的结果——而是要教您如何使用 Keras 的 Conv2D 类来实现和训练自定义卷积神经网络的基础知识 .

项目结构

===============================================================

数据集地址:

http://www.vision.caltech.edu/Image_Datasets/Caltech101/101_ObjectCategories.tar.gz

linux下载指令:

$ wget http://www.vision.caltech.edu/Image_Datasets/Caltech101/101_ObjectCategories.tar.gz

$ tar -zxvf 101_ObjectCategories.tar.gz

项目的树结构

$ tree --dirsfirst -L 2 -v

.

├── 101_ObjectCategories

│ ├── Faces [436 entries]

│ ├── Leopards [201 entries]

│ ├── Motorbikes [799 entries]

│ ├── airplanes [801 entries]

├── pyimagesearch

│ ├── init.py

│ └── stridednet.py

├── 101_ObjectCategories.tar.gz

├── train.py

└── plot.png

第一个目录 101_ObjectCategories/ 是我们在上一节中提取的数据集。 它包含 102 个文件夹,因此我删除了今天的博客文章我们不关心的行。 剩下的是前面讨论过的四个对象类别的子集。

pyimagesearch/ 模块不可通过 pip 安装。 您必须使用“下载”来获取文件。 在该模块中,您将找到包含 StrdedNet 类的 stridendet.py。

除了 stridednet.py 之外,我们还将查看根文件夹中的 train.py。 我们的训练脚本将使用 StridedNet 和我们的小数据集来训练模型以用于示例目的。

训练脚本将生成训练历史图 plot.png 。

Keras Conv2D 示例

==========================================================================

image-20211029212011620

图12: 一个名为“StridedNet”的深度学习 CNN 作为今天关于 Keras Conv2D 参数的博客文章的示例。 点击 展开。

现在我们已经回顾了 (1) Keras Conv2D 类的工作原理和 (2) 我们将训练网络的数据集,让我们继续实施我们将训练的卷积神经网络。 我们今天将使用的 CNN,“StridedNet”,是我为本教程的目的而编写的。 StridedNet 具有三个重要的特性:

它使用跨步卷积而不是池化操作来减小体积大小

第一个 CONV 层使用 7×7 过滤器,但网络中的所有其他层使用 3×3 过滤器(类似于 VGG)

MSRA/He 等人。 正态分布算法用于初始化网络中的所有权重

现在让我们继续并实施 StridedNet。

打开一个新文件,将其命名为 stridednet.py ,并插入以下代码:

import the necessary packages

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import BatchNormalization

from tensorflow.keras.layers import Conv2D

from tensorflow.keras.layers import Activation

from tensorflow.keras.layers import Flatten

from tensorflow.keras.layers import Dropout

from tensorflow.keras.layers import Dense

from tensorflow.keras import backend as K

class StridedNet:

@staticmethod

def build(width, height, depth, classes, reg, init=“he_normal”):

initialize the model along with the input shape to be

“channels last” and the channels dimension itself

model = Sequential()

inputShape = (height, width, depth)

chanDim = -1

if we are using “channels first”, update the input shape

and channels dimension

if K.image_data_format() == “channels_first”:

inputShape = (depth, height, width)

chanDim = 1

我们所有的 Keras 模块都在第 2-9 行导入,即 Conv2D。

我们的 StrdedNet 类在第 11 行定义,在第 13 行使用单个构建方法。

build 方法接受六个参数:

​ width :图像宽度(以像素为单位)。

​ height :以像素为单位的图像高度。

​ depth :图像的通道数。

​ classes :模型需要预测的类数。

​ reg : 正则化方法。

​ init :内核初始化程序。

​ width 、 height 和 depth 参数影响输入体积形状。

对于“channels_last”排序,输入形状在第 17 行指定,其中深度是最后一个。 我们可以使用 Keras 后端检查 image_data_format 以查看我们是否需要适应“channels_first”排序(第 22-24 行)。 让我们看看如何构建前三个 CONV 层:

our first CONV layer will learn a total of 16 filters, each

Of which are 7x7 – we’ll then apply 2x2 strides to reduce

the spatial dimensions of the volume

model.add(Conv2D(16, (7, 7), strides=(2, 2), padding=“valid”,

kernel_initializer=init, kernel_regularizer=reg,

input_shape=inputShape))

here we stack two CONV layers on top of each other where

each layerswill learn a total of 32 (3x3) filters

model.add(Conv2D(32, (3, 3), padding=“same”,

kernel_initializer=init, kernel_regularizer=reg))

model.add(Activation(“relu”))

model.add(BatchNormalization(axis=chanDim))

model.add(Conv2D(32, (3, 3), strides=(2, 2), padding=“same”,

kernel_initializer=init, kernel_regularizer=reg))

model.add(Activation(“relu”))

model.add(BatchNormalization(axis=chanDim))

model.add(Dropout(0.25))

每个 Conv2D 都使用 model.add 堆叠在网络上。

请注意,对于第一个 Conv2D 层,我们已经明确指定了 inputShape,以便 CNN 架构可以在某个地方开始和构建。然后,从这里开始,每次调用 model.add 时,前一层都充当下一层的输入。

考虑到前面讨论的 Conv2D 参数,您会注意到我们使用跨步卷积来减少空间维度而不是池化操作。

应用 ReLU 激活(参见图 8)以及批量归一化和 dropout。

我几乎总是推荐批量归一化,因为它倾向于稳定训练并使调整超参数更容易。也就是说,它可以使您的训练时间增加一倍或三倍。明智地使用它。

Dropout 的目的是帮助你的网络泛化而不是过拟合。当前层的神经元以概率 p 与下一层的神经元随机断开连接,因此网络必须依赖现有的连接。我强烈建议使用 dropout。

我们来看看更多层的StridedNet:

our first CONV layer will learn a total of 16 filters, each

Of which are 7x7 – we’ll then apply 2x2 strides to reduce

the spatial dimensions of the volume

model.add(Conv2D(16, (7, 7), strides=(2, 2), padding=“valid”,

kernel_initializer=init, kernel_regularizer=reg,

input_shape=inputShape))

here we stack two CONV layers on top of each other where

each layerswill learn a total of 32 (3x3) filters

model.add(Conv2D(32, (3, 3), padding=“same”,

kernel_initializer=init, kernel_regularizer=reg))

model.add(Activation(“relu”))

model.add(BatchNormalization(axis=chanDim))

model.add(Conv2D(32, (3, 3), strides=(2, 2), padding=“same”,

kernel_initializer=init, kernel_regularizer=reg))

model.add(Activation(“relu”))

model.add(BatchNormalization(axis=chanDim))

model.add(Dropout(0.25))

网络越深,我们学习的过滤器就越多。 在大多数网络的末尾,我们添加了一个全连接层:

fully-connected layer

model.add(Flatten())

model.add(Dense(512, kernel_initializer=init))

model.add(Activation(“relu”))

model.add(BatchNormalization())

model.add(Dropout(0.5))

softmax classifier

model.add(Dense(classes))

model.add(Activation(“softmax”))

return the constructed network architecture

return model

具有 512 个节点的单个全连接层被附加到 CNN。

最后,一个“softmax”分类器被添加到网络中——这一层的输出是预测值本身。

这是一个包装。 如您所见,一旦您知道参数的含义(Conv2D 具有很多参数的潜力),Keras 语法就非常简单。

让我们学习如何编写脚本来使用一些数据训练 StridedNet!

实现训练脚本

=================================================================

现在我们已经实现了我们的 CNN 架构,让我们创建用于训练网络的驱动程序脚本。 打开 train.py 文件并插入以下代码:

set the matplotlib backend so figures can be saved in the background

import matplotlib

matplotlib.use(“Agg”)

import the necessary packages

from pyimagesearch.stridednet import StridedNet

from sklearn.preprocessing import LabelBinarizer

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from tensorflow.keras.preprocessing.image import ImageDataGenerator

from tensorflow.keras.optimizers import Adam

from tensorflow.keras.regularizers import l2

from imutils import paths

import matplotlib.pyplot as plt

import numpy as np

import argparse

import cv2

import os

我们在第 2-18 行导入我们的模块和包。 请注意,我们没有在任何地方导入 Conv2D。 我们的 CNN 实现包含在 stridednet.py 中,我们的 StridedNet 导入处理它(第 6 行)。

我们的 matplotlib 后端设置在第 3 行——这是必要的,这样我们可以将我们的绘图保存为图像文件,而不是在 GUI 中查看它。 我们在第 7-9 行从 sklearn 导入功能:

LabelBinarizer :用于“one-hot”编码我们的类标签。

​ train_test_split :用于拆分我们的数据,以便我们拥有训练和评估集。

category_report :我们将使用它来打印评估的统计信息。

在 keras 中,我们将使用:

​ ImageDataGenerator :用于数据增强。 有关 Keras 数据生成器的更多信息,请参阅上周的博客文章。

​ Adam:SGD 的优化器替代方案。

​ l2 :我们将使用的正则化器。 向上滚动以阅读有关正则化器的信息。 应用正则化可减少过拟合并有助于泛化。

我们将在运行时使用 argparse 来处理命令行参数,而 OpenCV (cv2) 将用于从数据集中加载和预处理图像。

construct the argument parser and parse the arguments

ap = argparse.ArgumentParser()

ap.add_argument(“-d”, “–dataset”, required=True,

help=“path to input dataset”)

ap.add_argument(“-e”, “–epochs”, type=int, default=50,

help=“# of epochs to train our network for”)

ap.add_argument(“-p”, “–plot”, type=str, default=“plot.png”,

help=“path to output loss/accuracy plot”)

args = vars(ap.parse_args())

我们的脚本可以接受三个命令行参数:

​ --dataset :输入数据集的路径。

​ --epochs :要训练的时期数。 默认情况下,我们将训练 50 个 epoch。

​ --plot :我们的损失/准确度图将输出到磁盘。 此参数包含文件路径。

默认情况下,它只是 “plot.png” 。 让我们准备加载我们的数据集:

initialize the set of labels from the CALTECH-101 dataset we are

going to train our network on

LABELS = set([“Faces”, “Leopards”, “Motorbikes”, “airplanes”])

grab the list of images in our dataset directory, then initialize

the list of data (i.e., images) and class images

print(“[INFO] loading images…”)

imagePaths = list(paths.list_images(args[“dataset”]))

data = []

labels = []

在我们实际加载数据集之前,我们将继续进行初始化:

​ LABELS :我们将用于训练的标签。

imagePaths :数据集目录的图像路径列表。 我们将很快根据文件路径中解析的类标签过滤这些。

​ data :一个列表,用于保存我们的网络将在其上训练的图像。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

们将继续进行初始化:

​ LABELS :我们将用于训练的标签。

imagePaths :数据集目录的图像路径列表。 我们将很快根据文件路径中解析的类标签过滤这些。

​ data :一个列表,用于保存我们的网络将在其上训练的图像。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-hcj1vufm-1712774149801)]

[外链图片转存中…(img-VDW0xKkC-1712774149802)]

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

img
  • 12
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值