政安晨:【Keras机器学习实践要点】(二十六)—— 内卷神经网络

目录

简介

设置

卷积

演变

测试逆卷积层

图像分类

获取 CIFAR10 数据集

数据可视化

卷积神经网络

逆向传播神经网络

比较

损失图和准确率图

可视化卷积核

结论


政安晨的个人主页政安晨

欢迎 👍点赞✍评论⭐收藏

收录专栏: TensorFlow与Keras机器学习实战

希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正!

本文目标:深入研究特定位置和渠道无关的“内卷”核函数。

简介


卷积是大多数现代计算机视觉神经网络的基础。卷积核具有空间无关性和通道特定性。因此,它无法适应不同空间位置的不同视觉模式。除了与位置相关的问题,卷积的作用范围也给捕捉远距离空间相互作用带来了挑战。


为了解决上述问题,Li 等人在《卷积》一书中重新思考了卷积的特性:Inverting the Inherence of Convolution for VisualRecognition》一书中重新思考了卷积的特性。

作者提出了 "卷积内核"(involution kernel),它具有位置特定性和通道无关性。由于这种操作具有特定位置的性质,作者认为自我注意属于内卷的设计范例。

本示例介绍了内卷核,比较了两种图像分类模型(一种是卷积模型,另一种是内卷模型),并尝试将其与自我注意层相提并论。

设置

import os

os.environ["KERAS_BACKEND"] = "tensorflow"

import tensorflow as tf
import keras
import matplotlib.pyplot as plt

# Set seed for reproducibility.
tf.random.set_seed(42)

卷积

在计算机视觉中,卷积是一种重要的操作,用于图像处理和特征提取。卷积通过将一个滤波器或核与输入图像进行逐像素的计算,生成一个新的输出图像。

卷积操作与图像处理中常用的滤波操作类似,滤波器在图像上滑动并与图像的局部区域进行点乘,然后将乘积相加得到新的像素值。这个过程可以看作是将滤波器与图像进行卷积计算。

卷积操作的一个重要特性是它具有局部感知性。即卷积运算只计算滤波器与图像窗口内像素的乘积和,并将结果相加。这样的操作可以有效地提取图像的局部特征,例如边缘和纹理等。

卷积在计算机视觉中有广泛的应用。它可以用于图像增强、边缘检测、特征提取、目标检测和图像分类等任务。卷积神经网络(Convolutional Neural Network,CNN)是计算机视觉领域中最重要的算法之一,它借鉴了卷积操作的思想,并在深度学习中取得了很大的成功。

总之,卷积是计算机视觉中的一种重要操作,它能够提取图像的局部特征,并被广泛应用于图像处理和特征提取任务中。

卷积是计算机视觉深度神经网络的支柱。要理解卷积,就必须先谈谈卷积操作。

考虑一个维数为 H、W 和 C_in 的输入张量 X。我们取一组 C_out 卷积核,每个核的形状为 K、K、C_in。通过对输入张量和卷积核进行乘加运算,我们得到一个维数为 H、W、C_out 的输出张量 Y。

在上图中,C_out=3。这使得输出张量的形状为 H、W 和 3。我们可以注意到,卷积核并不依赖于输入张量的空间位置,因此它与位置无关。另一方面,输出张量中的每个通道都基于特定的卷积滤波器,这使得它具有特定通道的特性。

演变


我们的想法是让操作既能针对特定位置,又能与通道特定性无关。要实现这些特定属性是一项挑战。如果使用固定数量的卷积核(针对每个空间位置),我们将无法处理可变分辨率的输入张量。

为了解决这个问题,咱们考虑根据特定的空间位置生成每个内核。通过这种方法,我们应该可以轻松处理变分辨率输入张量。下图提供了这种内核生成方法的直观图。

class Involution(keras.layers.Layer):
    def __init__(
        self, channel, group_number, kernel_size, stride, reduction_ratio, name
    ):
        super().__init__(name=name)

        # Initialize the parameters.
        self.channel = channel
        self.group_number = group_number
        self.kernel_size = kernel_size
        self.stride = stride
        self.reduction_ratio = reduction_ratio

    def build(self, input_shape):
        # Get the shape of the input.
        (_, height, width, num_channels) = input_shape

        # Scale the height and width with respect to the strides.
        height = height // self.stride
        width = width // self.stride

        # Define a layer that average pools the input tensor
        # if stride is more than 1.
        self.stride_layer = (
            keras.layers.AveragePooling2D(
                pool_size=self.stride, strides=self.stride, padding="same"
            )
            if self.stride > 1
            else tf.identity
        )
        # Define the kernel generation layer.
        self.kernel_gen = keras.Sequential(
            [
                keras.layers.Conv2D(
                    filters=self.channel // self.reduction_ratio, kernel_size=1
                ),
                keras.layers.BatchNormalization(),
                keras.layers.ReLU(),
                keras.layers.Conv2D(
                    filters=self.kernel_size * self.kernel_size * self.group_number,
                    kernel_size=1,
                ),
            ]
        )
        # Define reshape layers
        self.kernel_reshape = keras.layers.Reshape(
            target_shape=(
                height,
                width,
                self.kernel_size * self.kernel_size,
                1,
                self.group_number,
            )
        )
        self.input_patches_reshape = keras.layers.Reshape(
            target_shape=(
                height,
                width,
                self.kernel_size * self.kernel_size,
                num_channels // self.group_number,
                self.group_number,
            )
        )
        self.output_reshape = keras.layers.Reshape(
            target_shape=(height, width, num_channels)
        )

    def call(self, x):
        # Generate the kernel with respect to the input tensor.
        # B, H, W, K*K*G
        kernel_input = self.stride_layer(x)
        kernel = self.kernel_gen(kernel_input)

        # reshape the kerenl
        # B, H, W, K*K, 1, G
        kernel = self.kernel_reshape(kernel)

        # Extract input patches.
        # B, H, W, K*K*C
        input_patches = tf.image.extract_patches(
            images=x,
            sizes=[1, self.kernel_size, self.kernel_size, 1],
            strides=[1, self.stride, self.stride, 1],
            rates=[1, 1, 1, 1],
            padding="SAME",
        )

        # Reshape the input patches to align with later operations.
        # B, H, W, K*K, C//G, G
        input_patches = self.input_patches_reshape(input_patches)

        # Compute the multiply-add operation of kernels and patches.
        # B, H, W, K*K, C//G, G
        output = tf.multiply(kernel, input_patches)
        # B, H, W, C//G, G
        output = tf.reduce_sum(output, axis=3)

        # Reshape the output kernel.
        # B, H, W, C
        output = self.output_reshape(output)

        # Return the output tensor and the kernel.
        return output, kernel

测试逆卷积层

# Define the input tensor.
input_tensor = tf.random.normal((32, 256, 256, 3))

# Compute involution with stride 1.
output_tensor, _ = Involution(
    channel=3, group_number=1, kernel_size=5, stride=1, reduction_ratio=1, name="inv_1"
)(input_tensor)
print(f"with stride 1 ouput shape: {output_tensor.shape}")

# Compute involution with stride 2.
output_tensor, _ = Involution(
    channel=3, group_number=1, kernel_size=5, stride=2, reduction_ratio=1, name="inv_2"
)(input_tensor)
print(f"with stride 2 ouput shape: {output_tensor.shape}")

# Compute involution with stride 1, channel 16 and reduction ratio 2.
output_tensor, _ = Involution(
    channel=16, group_number=1, kernel_size=5, stride=1, reduction_ratio=2, name="inv_3"
)(input_tensor)
print(
    "with channel 16 and reduction ratio 2 ouput shape: {}".format(output_tensor.shape)
)

演绎展示:

with stride 1 ouput shape: (32, 256, 256, 3)
with stride 2 ouput shape: (32, 128, 128, 3)
with channel 16 and reduction ratio 2 ouput shape: (32, 256, 256, 3)

图像分类


在本文中,我们将建立一个图像分类器模型。将有两个模型,一个是卷积模型,另一个是渐开线模型。

图像分类模型的灵感主要来自谷歌的卷积神经网络(CNN)教程。

获取 CIFAR10 数据集

# Load the CIFAR10 dataset.
print("loading the CIFAR10 dataset...")
(
    (train_images, train_labels),
    (
        test_images,
        test_labels,
    ),
) = keras.datasets.cifar10.load_data()

# Normalize pixel values to be between 0 and 1.
(train_images, test_images) = (train_images / 255.0, test_images / 255.0)

# Shuffle and batch the dataset.
train_ds = (
    tf.data.Dataset.from_tensor_slices((train_images, train_labels))
    .shuffle(256)
    .batch(256)
)
test_ds = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(256)
加载 CIFAR10 数据集...

数据可视化

class_names = [
    "airplane",
    "automobile",
    "bird",
    "cat",
    "deer",
    "dog",
    "frog",
    "horse",
    "ship",
    "truck",
]

plt.figure(figsize=(10, 10))
for i in range(25):
    plt.subplot(5, 5, i + 1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i])
    plt.xlabel(class_names[train_labels[i][0]])
plt.show()

演绎展示: 

卷积神经网络

# Build the conv model.
print("building the convolution model...")
conv_model = keras.Sequential(
    [
        keras.layers.Conv2D(32, (3, 3), input_shape=(32, 32, 3), padding="same"),
        keras.layers.ReLU(name="relu1"),
        keras.layers.MaxPooling2D((2, 2)),
        keras.layers.Conv2D(64, (3, 3), padding="same"),
        keras.layers.ReLU(name="relu2"),
        keras.layers.MaxPooling2D((2, 2)),
        keras.layers.Conv2D(64, (3, 3), padding="same"),
        keras.layers.ReLU(name="relu3"),
        keras.layers.Flatten(),
        keras.layers.Dense(64, activation="relu"),
        keras.layers.Dense(10),
    ]
)

# Compile the mode with the necessary loss function and optimizer.
print("compiling the convolution model...")
conv_model.compile(
    optimizer="adam",
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=["accuracy"],
)

# Train the model.
print("conv model training...")
conv_hist = conv_model.fit(train_ds, epochs=20, validation_data=test_ds)

演绎展示:

building the convolution model...
compiling the convolution model...
conv model training...
Epoch 1/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 6s 15ms/step - accuracy: 0.3068 - loss: 1.9000 - val_accuracy: 0.4861 - val_loss: 1.4593
Epoch 2/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - accuracy: 0.5153 - loss: 1.3603 - val_accuracy: 0.5741 - val_loss: 1.1913
Epoch 3/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.5949 - loss: 1.1517 - val_accuracy: 0.6095 - val_loss: 1.0965
Epoch 4/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.6414 - loss: 1.0330 - val_accuracy: 0.6260 - val_loss: 1.0635
Epoch 5/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.6690 - loss: 0.9485 - val_accuracy: 0.6622 - val_loss: 0.9833
Epoch 6/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.6951 - loss: 0.8764 - val_accuracy: 0.6783 - val_loss: 0.9413
Epoch 7/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.7122 - loss: 0.8167 - val_accuracy: 0.6856 - val_loss: 0.9134
Epoch 8/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - accuracy: 0.7299 - loss: 0.7709 - val_accuracy: 0.7001 - val_loss: 0.8792
Epoch 9/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - accuracy: 0.7467 - loss: 0.7288 - val_accuracy: 0.6992 - val_loss: 0.8821
Epoch 10/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - accuracy: 0.7591 - loss: 0.6982 - val_accuracy: 0.7235 - val_loss: 0.8237
Epoch 11/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - accuracy: 0.7725 - loss: 0.6550 - val_accuracy: 0.7115 - val_loss: 0.8521
Epoch 12/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.7808 - loss: 0.6302 - val_accuracy: 0.7051 - val_loss: 0.8823
Epoch 13/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.7860 - loss: 0.6101 - val_accuracy: 0.7122 - val_loss: 0.8635
Epoch 14/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.7998 - loss: 0.5786 - val_accuracy: 0.7214 - val_loss: 0.8348
Epoch 15/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.8117 - loss: 0.5473 - val_accuracy: 0.7139 - val_loss: 0.8835
Epoch 16/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.8168 - loss: 0.5267 - val_accuracy: 0.7155 - val_loss: 0.8840
Epoch 17/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.8266 - loss: 0.5022 - val_accuracy: 0.7239 - val_loss: 0.8576
Epoch 18/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.8374 - loss: 0.4750 - val_accuracy: 0.7262 - val_loss: 0.8756
Epoch 19/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.8452 - loss: 0.4505 - val_accuracy: 0.7235 - val_loss: 0.9049
Epoch 20/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - accuracy: 0.8531 - loss: 0.4283 - val_accuracy: 0.7304 - val_loss: 0.8962

逆向传播神经网络

# Build the involution model.
print("building the involution model...")

inputs = keras.Input(shape=(32, 32, 3))
x, _ = Involution(
    channel=3, group_number=1, kernel_size=3, stride=1, reduction_ratio=2, name="inv_1"
)(inputs)
x = keras.layers.ReLU()(x)
x = keras.layers.MaxPooling2D((2, 2))(x)
x, _ = Involution(
    channel=3, group_number=1, kernel_size=3, stride=1, reduction_ratio=2, name="inv_2"
)(x)
x = keras.layers.ReLU()(x)
x = keras.layers.MaxPooling2D((2, 2))(x)
x, _ = Involution(
    channel=3, group_number=1, kernel_size=3, stride=1, reduction_ratio=2, name="inv_3"
)(x)
x = keras.layers.ReLU()(x)
x = keras.layers.Flatten()(x)
x = keras.layers.Dense(64, activation="relu")(x)
outputs = keras.layers.Dense(10)(x)

inv_model = keras.Model(inputs=[inputs], outputs=[outputs], name="inv_model")

# Compile the mode with the necessary loss function and optimizer.
print("compiling the involution model...")
inv_model.compile(
    optimizer="adam",
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=["accuracy"],
)

# train the model
print("inv model training...")
inv_hist = inv_model.fit(train_ds, epochs=20, validation_data=test_ds)
building the involution model...
compiling the involution model...
inv model training...
Epoch 1/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 9s 25ms/step - accuracy: 0.1369 - loss: 2.2728 - val_accuracy: 0.2716 - val_loss: 2.1041
Epoch 2/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.2922 - loss: 1.9489 - val_accuracy: 0.3478 - val_loss: 1.8275
Epoch 3/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.3477 - loss: 1.8098 - val_accuracy: 0.3782 - val_loss: 1.7435
Epoch 4/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.3741 - loss: 1.7420 - val_accuracy: 0.3901 - val_loss: 1.6943
Epoch 5/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.3931 - loss: 1.6942 - val_accuracy: 0.4007 - val_loss: 1.6639
Epoch 6/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.4057 - loss: 1.6622 - val_accuracy: 0.4108 - val_loss: 1.6494
Epoch 7/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4134 - loss: 1.6374 - val_accuracy: 0.4202 - val_loss: 1.6363
Epoch 8/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4200 - loss: 1.6166 - val_accuracy: 0.4312 - val_loss: 1.6062
Epoch 9/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.4286 - loss: 1.5949 - val_accuracy: 0.4316 - val_loss: 1.6018
Epoch 10/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.4346 - loss: 1.5794 - val_accuracy: 0.4346 - val_loss: 1.5963
Epoch 11/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4395 - loss: 1.5641 - val_accuracy: 0.4388 - val_loss: 1.5831
Epoch 12/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - accuracy: 0.4445 - loss: 1.5502 - val_accuracy: 0.4443 - val_loss: 1.5826
Epoch 13/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4493 - loss: 1.5391 - val_accuracy: 0.4497 - val_loss: 1.5574
Epoch 14/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4528 - loss: 1.5255 - val_accuracy: 0.4547 - val_loss: 1.5433
Epoch 15/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step - accuracy: 0.4575 - loss: 1.5148 - val_accuracy: 0.4548 - val_loss: 1.5438
Epoch 16/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4599 - loss: 1.5072 - val_accuracy: 0.4581 - val_loss: 1.5323
Epoch 17/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4664 - loss: 1.4957 - val_accuracy: 0.4598 - val_loss: 1.5321
Epoch 18/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4701 - loss: 1.4863 - val_accuracy: 0.4575 - val_loss: 1.5302
Epoch 19/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4737 - loss: 1.4790 - val_accuracy: 0.4676 - val_loss: 1.5233
Epoch 20/20
 196/196 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.4771 - loss: 1.4740 - val_accuracy: 0.4719 - val_loss: 1.5096

比较

在本文中,我们将研究这两种模式,并比较一些要点。

参数


我们可以看到,在类似的架构下,CNN 的参数要比 INN(卷积神经网络)的参数大得多。

conv_model.summary()

inv_model.summary()

损失图和准确率图


这里的损失图和准确率图表明,INNs 是一种学习速度较慢的学习器(参数较低)。

plt.figure(figsize=(20, 5))

plt.subplot(1, 2, 1)
plt.title("Convolution Loss")
plt.plot(conv_hist.history["loss"], label="loss")
plt.plot(conv_hist.history["val_loss"], label="val_loss")
plt.legend()

plt.subplot(1, 2, 2)
plt.title("Involution Loss")
plt.plot(inv_hist.history["loss"], label="loss")
plt.plot(inv_hist.history["val_loss"], label="val_loss")
plt.legend()

plt.show()

plt.figure(figsize=(20, 5))

plt.subplot(1, 2, 1)
plt.title("Convolution Accuracy")
plt.plot(conv_hist.history["accuracy"], label="accuracy")
plt.plot(conv_hist.history["val_accuracy"], label="val_accuracy")
plt.legend()

plt.subplot(1, 2, 2)
plt.title("Involution Accuracy")
plt.plot(inv_hist.history["accuracy"], label="accuracy")
plt.plot(inv_hist.history["val_accuracy"], label="val_accuracy")
plt.legend()

plt.show()

演绎展示:

可视化卷积核

为了使内核可视化,我们取每个内卷内核的 K×K 值之和。不同空间位置上的所有代表都构成了相应的热图。

有人说,"我们提出的内卷让人联想到自我注意,本质上可以成为自我注意的通用版本"。

通过核的可视化,我们确实可以获得图像的注意力图谱。

学习到的内卷化内核为输入张量的各个空间位置提供了注意力。

这种针对特定位置的特性使得内卷成为自我注意模型的通用空间。

layer_names = ["inv_1", "inv_2", "inv_3"]
outputs = [inv_model.get_layer(name).output[1] for name in layer_names]
vis_model = keras.Model(inv_model.input, outputs)

fig, axes = plt.subplots(nrows=10, ncols=4, figsize=(10, 30))

for ax, test_image in zip(axes, test_images[:10]):
    (inv1_kernel, inv2_kernel, inv3_kernel) = vis_model.predict(test_image[None, ...])
    inv1_kernel = tf.reduce_sum(inv1_kernel, axis=[-1, -2, -3])
    inv2_kernel = tf.reduce_sum(inv2_kernel, axis=[-1, -2, -3])
    inv3_kernel = tf.reduce_sum(inv3_kernel, axis=[-1, -2, -3])

    ax[0].imshow(keras.utils.array_to_img(test_image))
    ax[0].set_title("Input Image")

    ax[1].imshow(keras.utils.array_to_img(inv1_kernel[0, ..., None]))
    ax[1].set_title("Involution Kernel 1")

    ax[2].imshow(keras.utils.array_to_img(inv2_kernel[0, ..., None]))
    ax[2].set_title("Involution Kernel 2")

    ax[3].imshow(keras.utils.array_to_img(inv3_kernel[0, ..., None]))
    ax[3].set_title("Involution Kernel 3")
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 503ms/step
 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step
 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step
 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step
 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step
 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step
 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step
 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step
 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step
 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step

演绎展示:

结论


在本示例中,主要重点是构建一个可以轻松重复使用的卷积层。虽然我们的比较是基于一项特定的任务,但您也可以在不同的任务中使用该层,并报告您的结果。

我认为,内卷化的主要启示在于它与自我关注的关系。在很多任务中,特定位置和特定通道处理背后的直觉都是有道理的。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/536275.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[2024最新]MySQL-mysql 8.0.11安装教程

网上的教程有很多,基本上大同小异。但是安装软件有时就可能因为一个细节安装失败。我也是综合了很多个教程才安装好的,所以本教程可能也不是普遍适合的。 安装环境:win 10 1、下载zip安装包: MySQL8.0 For Windows zip包下载地…

redis复习笔记08(小滴课堂)

案例实战需求之大数据下的用户画像标签去重 我们就简单的做到了去重了。 案例实战社交应用里面之关注、粉丝、共同好友案例 这就是我们set的一个应用。 案例实战之SortedSet用户积分实时榜单最佳实践 准备积分类对象: 我们加上构造方法和判断相等的equals和hascod…

【网安小白成长之路】6.pikachu、sql-labs、upload-labs靶场搭建

🐮博主syst1m 带你 acquire knowledge! ✨博客首页——syst1m的博客💘 🔞 《网安小白成长之路(我要变成大佬😎!!)》真实小白学习历程,手把手带你一起从入门到入狱🚭 &…

关于SpringCloud,你了解多少?

Why SpringCloud? Spring cloud 是一系列框架的有序集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 spring boot 的开发风格做到一…

快速列表quicklist

目录 为什么使用快速列表quicklist 对比双向链表 对比压缩列表ziplist quicklist结构 节点结构quicklistNode quicklist 管理ziplist信息的结构quicklistEntry 迭代器结构quicklistIter quicklist的API 1.创建快速列表 2.创建快速列表节点 3.头插quicklistPushHead …

加固系统安全,防范ssh暴力破解之Fail2Ban

你是否还在担心你的服务器被攻击?你是否还在担心你的博客的安全?你是否还在担心你的隐私?别急fail2ban它来了,它可以解决你的一切问题。 Fail2Ban 是什么? 现在让我们一起来认识一下今天的主角 – Fail2Ban。简单说来…

浅析hex和bin文件格式以及使用Keil编译生成hex和bin文件

目录 概述 1 hex文件和bin文件 1.1 认识.hex文件 1.1.1 hex文件内容 1.1.2 hex文件格式介绍 1.1.3 认识几个数据类型 1.2 .bin文件 2 Keil 开发工具生成.hex和.bin 2.1 生成.hex文件 2.2 生成.bin文件 概述 本位主要介绍.hex文件和.bin文件的相关内容,重点…

Python+Django+Html网页版人脸识别考勤打卡系统

程序示例精选 PythonDjangoHtml人脸识别考勤打卡系统 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对《PythonDjangoHtml网页版人脸识别考勤打卡系统》编写代码,代码整洁&#xf…

【Ubuntu】 Github Readme导入GIF

1.工具安装 我们使用 ffmpeg 软件来完成转换工作1.1 安装命令 sudo add-apt-repository ppa:jonathonf/ffmpeg-3sudo apt-get updatesudo apt-get install ffmpeg1.2 转换命令 (1)直接转换命令: ffmpeg -i out.mp4 out.gif(2) 带参数命令&…

怎么在外地控制自家的电视

怎么在外地控制自家的电视 随着科技的进步和智能家居的普及,远程控制家中的电器设备已经成为现实。电视作为家庭娱乐的中心,远程控制功能更是备受关注。那么,如何在外地控制自家的电视呢?本文将为你提供详细的步骤和有价值的信息…

中国网站数量竟然比2022年多了10000个

关注卢松松,会经常给你分享一些我的经验和观点。 CNNIC发布了最新中国互联网报告,报告显示: 2018年中国有523万个网站,2023年13月下降到388万个,5年时间网站数量下降30%,但相比于2022年12月,竟…

Java后端基础知识(String类型)

String类的创建方式 String的特点 1.引用数据类型 2.是final类,一旦创建内容不可修改 3.String类对象相等的判断用equals()方法完成,是判断地址数值 String的创建方式 1.直接创建 String str"hello";注意&#xff…

【ELFK】Filebeat+ELK 部署

FilebeatELK 部署 Node1节点(2C/4G):node1/192.168.67.11 Elasticsearch Kibana Node2节点(2C/4G):node2/192.168.67.12 Elasticsearch Apache节点:apache/192.168.67.10 …

二叉树的前序

1.递归 public boolean isSymmetric(TreeNode root) {if(root null){return true;}return deepCheck(root.left,root.right);}boolean deepCheck(TreeNode left, TreeNode right){//递归的终止条件是两个节点都为空//或者两个节点中有一个为空//或者两个节点的值不相等if(lef…

DePIN打猎之旅:AI算力作饵,道阻且长

出品|OKG Research 作者|Hedy Bi 香港Web3嘉年华已告一段落,然而Web3自由的脉搏还在跳动,并不断向其他行业渗透。和上一轮周期相比,本轮牛市开启的逻辑是由“原生创新叙事”转变成“主流认可,资金驱动”的…

ios包上架系列 四、虚拟机涉及网站

一、网站相关 苹果开发者平台 https://developer.apple.com/ 谷歌邮箱 https://mail.google.com/mail/u/0/#inbox 微云在线或者安装QQ https://www.weiyun.com/disk 下载下的为zip文件,需要复制里面的内容出来使用 二、环境配置 1、ios-upload 配置&#x…

水利自动化控制系统平台介绍

水利自动化控制系统平台介绍 在当今社会,水资源的管理和保护日益成为全球关注的重要议题。随着科技的进步和信息化的发展,水利监测系统作为一种集成了现代信息技术、自动化控制技术以及环境监测技术的综合性平台,正在逐步改变传统的水利管理模…

【Dijkstra单源最短路径解法】蓝桥杯2022年第十三届决赛真题-出差

我也来贡献一份题解:Dijkstra单源最短路径的简单变式【简单C代码】 这道题的前置知识的Dijkstra单源最短路径算法 如果还没学过,建议去看AcWing算法教程的**图论(2)**中最短路径问题的讲解,u1s1–y总讲的是真的通透! 思路 这道题和单源最短路…

IJKPLAYER源码分析-iOS端显示

1 简介 1.1 EAGL(Embedded Apple Graphics Library) 与Android系统使用EGL连接OpenGL ES与原生窗口进行surface输出类似,iOS则用EAGL将CAEAGLLayer作为OpenGL ES输出目标。 与 Android EGL 不同的是,iOS EAGL 不会让应用直接向 BackendFrameBuffer 和 F…

Socks5代理IP如何获取?如何使用?

当我们在互联网上浏览网页、下载文件或者进行在线活动时,隐私和安全问题常常被提及。在这样的环境下,一个有效的解决方案是使用Sock5IP。本教程将向您介绍Sock5IP的使用方法,帮助您保护个人隐私并提升网络安全。 一、什么是Sock5IP&#xff1…