计算机视觉CV-2

Convolution、ReLU and Maximum Pooling

The parts of a convnet: image, base, head, class; input, extract, classify, output.

base执行的特征提取包括三个基本操作:

  1. Filter:过滤图像的特定特征(卷积convolution)

  2. Detect:检测过滤图像中的该特征 (ReLU)

  3. Condense:压缩图像以增强特征(最大池化maximum pooling)

An example of the feature extraction process.

通常,网络将对单个图像并行执行多次提取。

Filter with Convolution

Weights

卷积核(kernel,也叫:内核):

A 3x3 kernel.

卷积核通过扫描图像并生成像素值的加权和来进行操作。卷积核的数量(Filters)也称为通道数(channels)。

A kernel acts as a kind of lens.

通过kernel_size=3的卷积核(kernel)对输入数据进行卷积操作。

kernels = [edge, bottom_sobel, emboss, sharpen]

  1. edge:这是一个卷积核,通常用于边缘检测。它可以帮助找到图像中的边界和轮廓。
  2. bottom_sobel:这是一个卷积核,也用于边缘检测,特别是检测垂直方向上的边缘。
  3. emboss:这是一个卷积核,通常用于图像浮雕效果。它可以使图像看起来有立体感,突出显示图像中的细节。
  4. sharpen:这是一个卷积核,用于增强图像的锐度。它可以使图像中的边缘更加清晰。

Activations

网络中的激活我们称为特征图。它们是我们对图像应用滤镜时的结果;它们包含卷积核提取的视觉特征。

不同卷积核得到的不同特征图:

Three kernels and the feature maps they produce.

一般来说,卷积在其输入中强调的内容将与内核中正数的形状相匹配。上面的左侧和中间的内核都会过滤水平形状。

使用filters参数,你可以告诉卷积层你希望它创建多少个特征图作为输出。

Detect with ReLU

ReLU(修正线性单元)作为激活函数。

ReLU是深度学习中常用的激活函数,它将负输入值置为零,而保留正输入值不变。这有助于引入非线性性质,使模型能够学习复杂的特征映射。

Graph of the ReLU activation function.

ReLU 激活表明负值并不重要,因此将它们设置为 0。(“所有不重要的事情都同样不重要。”)

将ReLU应用到以下特征图中:

ReLU applied to feature maps.

与其他激活函数一样,ReLU 函数是非线性的

Condense with Maximum Pooling

MaxPool2D 层与 Conv2D 层非常相似,不同之处在于它使用简单的最大值函数而不是内核,其中 pool_size 参数类似于 kernel_size。然而,MaxPool2D 层不像其内核中的卷积层那样具有任何可训练权重。

An example of the feature extraction process.

请注意,应用 ReLU 函数(检测)后,特征图最终会出现大量“死区”,即仅包含 0 的大区域(图像中的黑色区域)。必须在整个网络中携带这些 0 激活会增加模型的大小,而不会添加太多有用的信息。相反,我们希望压缩特征图以仅保留最有用的部分——特征本身。

Maximum pooling replaces a patch with the maximum value in that patch.

平移不变性

zero-pixels区域携带了位置信息,当使用池化操作去除这些pixels时,也就去除了特征图中存在的位置信息。

这赋予了卷积网络一种称为平移不变性的属性。意味着具有最大池化的卷积网络往往不会根据特征在图像中的位置来区分特征。

Pooling tends to destroy positional information.

经过反复池化后,原始图像中的两个点变得无法区分。换句话说,池化破坏了他们的一些位置信息。由于网络无法再在特征图中区分它们,因此它也无法在原始图像中区分它们:它对于位置的差异来说是不变的。。

But only over small distances. Two dots far apart stay separated

事实上,池化只会在网络中产生小距离的平移不变性,就像图像中的两个点一样。开始相距较远的特征在合并后仍将保持明显;仅丢失了部分位置信息,但并非全部。

典型代码

获取图片并处理图片数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import tensorflow as tf
import matplotlib.pyplot as plt
plt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',
titleweight='bold', titlesize=18, titlepad=10)
plt.rc('image', cmap='magma')

image_path = '../input/computer-vision-resources/car_feature.jpg'
image = tf.io.read_file(image_path)
image = tf.io.decode_jpeg(image)

plt.figure(figsize=(6, 6))
plt.imshow(tf.squeeze(image), cmap='gray')
plt.axis('off')
plt.show();
img

定义卷积核:

1
2
3
4
5
6
7
8
9
10
import tensorflow as tf

kernel = tf.constant([
[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1],
])

plt.figure(figsize=(3, 3))
show_kernel(kernel)
img

定义卷积层:

1
2
3
4
5
6
7
8
9
10
11
12
image_filter = tf.nn.conv2d(
input=image,
filters=kernel,
# we'll talk about these two in lesson 4!
strides=1,
padding='SAME',
)

plt.figure(figsize=(6, 6))
plt.imshow(tf.squeeze(image_filter))
plt.axis('off')
plt.show();
img

ReLU 函数的检测步骤:

1
2
3
4
5
6
image_detect = tf.nn.relu(image_filter)

plt.figure(figsize=(6, 6))
plt.imshow(tf.squeeze(image_detect))
plt.axis('off')
plt.show();
img

池化操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import tensorflow as tf

image_condense = tf.nn.pool(
input=image_detect, # image in the Detect step above
window_shape=(2, 2),
pooling_type='MAX',
# we'll see what these do in the next lesson!
strides=(2, 2),
padding='SAME',
)

plt.figure(figsize=(6, 6))
plt.imshow(tf.squeeze(image_condense))
plt.axis('off')
plt.show();
img

Global Average Pooling

GlobalAvgPool2D方法

在卷积网络的头部广泛使用的一种平均池化方法——全局平均池化。 GlobalAvgPool2D 层通常用作网络头部部分或全部隐藏 Dense 层的替代。

  1. GlobalAveragePooling2D

    • 工作方式GlobalAveragePooling2D 是一种池化操作,它在整个特征图上计算平均值。具体来说,对于每个特征通道,它计算特征通道内所有值的平均值,然后输出每个特征通道的平均值作为结果。这个操作会将特征图的高度和宽度维度降为 1x1。
    • 效果GlobalAveragePooling2D 有助于捕获整个特征图中的全局信息,因此在一些图像分类任务中表现良好。它可以减少模型的参数数量,降低过拟合风险,并提高模型的泛化能力。
  2. Flatten

    • 工作方式Flatten 操作将特征图的所有元素拉平成一个一维向量,不进行任何池化或平均操作。它将特征图的高度、宽度和通道维度都展平成一个长向量。
    • 效果Flatten 操作不捕获全局信息,它将特征图中的每个像素都视为独立的特征。通常在卷积层之后,用于连接全连接层之前,以将特征图转换为全连接层可以处理的格式。

如果你的任务是图像分类GlobalAveragePooling2D 是一个较好的选择,因为它有助于捕获全局信息并减少参数数量。而如果你的任务是对象检测或图像分割等需要空间信息的任务,你可能需要保留特征图的空间结构,可以选择使用 Flatten 将特征图展平,然后连接到全连接层进行进一步处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.preprocessing import image_dataset_from_directory

# Load VGG16
pretrained_base = tf.keras.models.load_model(
'../input/cv-course-models/cv-course-models/vgg16-pretrained-base',
)

model = keras.Sequential([
pretrained_base,
# Attach a global average pooling layer after the base
layers.GlobalAvgPool2D(),
])

# Load dataset
ds = image_dataset_from_directory(
'../input/car-or-truck/train',
labels='inferred',
label_mode='binary',
image_size=[128, 128],
interpolation='nearest',
batch_size=1,
shuffle=True,
)

ds_iter = iter(ds)

VGG16 库产生 512 个特征图。我们可以将每个特征图视为代表原始图像中的一些高级视觉特征——可能是车轮或窗户。池化地图为我们提供了一个数字,我们可以将其视为该功能的分数:如果该功能存在则较大,如果不存在则较小。汽车往往在一组功能上得分较高,而卡车则在另一组功能上得分较高。现在,头部不必尝试将原始特征映射到类,而只需处理 GlobalAvgPool2D 生成的这些分数,这对它来说是一个更容易解决的问题。

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2024 Guijie Wang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信