卷积神经网络基础
添加 Conv2D 和 MaxPooling 层,用于图像分类任务
卷积神经网络基础 是 CoddyKit 上的免费 R Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。
为什么图像适合使用 CNN?
全连接网络会独立处理每个像素,从而丢失空间关系。卷积神经网络(CNN) 会将可学习的滤波器在输入上滑动,无论局部模式位于何处,都能检测边缘、纹理和形状等特征。这种平移不变性以及参数共享机制,使 CNN 成为处理图像数据的标准方法。
library(keras)
# Images are 3D tensors: (height, width, channels)
# MNIST: (28, 28, 1) — grayscale
# CIFAR-10: (32, 32, 3) — RGB
# Reshape flat vectors into image tensors
mnist <- dataset_mnist()
x_train <- array_reshape(mnist$train$x / 255, c(-1, 28, 28, 1))
y_train <- to_categorical(mnist$train$y, 10)
cat('Input shape:', dim(x_train))layer_conv_2d()——核心层
layer_conv_2d(filters, kernel_size, activation) 会对输入应用 filters 个大小为 kernel_size 的可学习二维卷积核。每个滤波器都会学习检测一种空间模式。输出的形状为 (height, width, filters)。
library(keras)
# First conv layer: 32 filters of 3x3
model <- keras_model_sequential(input_shape = c(28, 28, 1)) |>
layer_conv_2d(
filters = 32,
kernel_size = c(3, 3),
activation = 'relu',
padding = 'same' # keep spatial dimensions
)
summary(model) # output: (None, 28, 28, 32)layer_max_pooling_2d()
layer_max_pooling_2d(pool_size) 会在每个池化窗口中取最大值,从而缩小空间维度。这样做有两个作用:减少后续层中的参数数量,并引入一定程度的平移不变性(即使发生小幅位移,输出也不会发生明显变化)。
model <- keras_model_sequential(input_shape = c(28, 28, 1)) |>
layer_conv_2d(32, kernel_size = c(3, 3), activation = 'relu') |>
layer_max_pooling_2d(pool_size = c(2, 2))
summary(model)
# After pooling: (None, 13, 13, 32)
# Spatial dims halved, channel count preserved堆叠卷积层
更深的 CNN 会堆叠多个“卷积层+池化层”模块。较早的层检测低级特征(边缘、梯度);较深的层将这些特征组合成高级特征(形状、物体)。随着空间维度缩小,每个卷积层都会增加滤波器数量,以此进行补偿。
model <- keras_model_sequential(input_shape = c(32, 32, 3)) |>
layer_conv_2d(32, c(3, 3), activation = 'relu', padding = 'same') |>
layer_max_pooling_2d(c(2, 2)) |> # 16x16
layer_conv_2d(64, c(3, 3), activation = 'relu', padding = 'same') |>
layer_max_pooling_2d(c(2, 2)) |> # 8x8
layer_conv_2d(128, c(3, 3), activation = 'relu', padding = 'same') |>
layer_max_pooling_2d(c(2, 2)) # 4x4
summary(model)layer_flatten()
layer_flatten() 会将最后一个卷积模块的三维输出 (height, width, filters) 转换为一维向量。它连接了特征提取主干(卷积层)和分类头(全连接层)。
model <- keras_model_sequential(input_shape = c(28, 28, 1)) |>
layer_conv_2d(32, c(3, 3), activation = 'relu') |>
layer_max_pooling_2d(c(2, 2)) |>
layer_conv_2d(64, c(3, 3), activation = 'relu') |>
layer_max_pooling_2d(c(2, 2)) |>
layer_flatten() |> # 3D -> 1D vector
layer_dense(128, activation = 'relu') |>
layer_dense(10, activation = 'softmax')
summary(model)CNN 中的 layer_dropout()
在 CNN 中,dropout 通常应用于展平层和全连接层之后,而不是卷积模块内部(卷积模块中更适合使用空间 dropout layer_spatial_dropout_2d())。在第一个全连接层之后使用 0.25 到 0.5 的比率很常见。
model <- keras_model_sequential(input_shape = c(28, 28, 1)) |>
layer_conv_2d(32, c(3, 3), activation = 'relu') |>
layer_max_pooling_2d(c(2, 2)) |>
layer_conv_2d(64, c(3, 3), activation = 'relu') |>
layer_max_pooling_2d(c(2, 2)) |>
layer_flatten() |>
layer_dense(128, activation = 'relu') |>
layer_dropout(rate = 0.5) |> # regularise the classifier head
layer_dense(10, activation = 'softmax')
summary(model)编译和训练 CNN
编译和训练 CNN 的方式与全连接网络相同。对于使用独热标签的多分类问题,请使用 'categorical_crossentropy';对于整数标签,请使用 'sparse_categorical_crossentropy'。与全连接网络相比,CNN 通常适合使用稍低的学习率。
model |> compile(
optimizer = optimizer_adam(learning_rate = 0.0005),
loss = 'categorical_crossentropy',
metrics = c('accuracy')
)
history <- model |> fit(
x = x_train,
y = y_train,
epochs = 10,
batch_size = 64,
validation_split = 0.1,
verbose = 1
)
plot(history)数据增强
在小型数据集上训练 CNN 往往会导致过拟合。数据增强 会在训练时应用随机变换(翻转、旋转、缩放),以人为扩充训练集。在 keras3 中,请将 layer_random_flip()、layer_random_rotation() 作为模型内部的预处理层使用。
model <- keras_model_sequential(input_shape = c(32, 32, 3)) |>
# Data augmentation layers (only active during training)
layer_random_flip('horizontal') |>
layer_random_rotation(factor = 0.1) |>
layer_random_zoom(height_factor = 0.1) |>
# CNN backbone
layer_conv_2d(32, c(3, 3), activation = 'relu', padding = 'same') |>
layer_max_pooling_2d(c(2, 2)) |>
layer_flatten() |>
layer_dense(10, activation = 'softmax')
summary(model)评估 CNN
evaluate(model, x_test, y_test) 返回测试损失和准确率。若要进行更深入的分析,请使用 predict() 获取各类别的概率,然后构建混淆矩阵或计算各类别的 F1 分数,以了解模型在哪些方面表现不佳。
# Evaluate on test set
test_scores <- model |> evaluate(x_test, y_test, verbose = 0)
cat('Test accuracy:', test_scores['accuracy'])
# Get predicted classes
prob_matrix <- model |> predict(x_test)
pred_classes <- max.col(prob_matrix) - 1 # 0-indexed
true_classes <- mnist$test$y
# Confusion matrix
table(Predicted = pred_classes, True = true_classes)迁移学习概念
从头开始训练 CNN 需要大型数据集。迁移学习 会复用在 ImageNet 上预训练的特征提取层(例如 VGG、ResNet、MobileNet),只训练自定义分类头。在 keras 中,使用 application_mobilenet_v2() 加载预训练主干,并冻结其中的层。
# Load MobileNetV2 pretrained on ImageNet
base_model <- application_mobilenet_v2(
weights = 'imagenet',
include_top = FALSE, # remove original classifier head
input_shape = c(224, 224, 3)
)
# Freeze pretrained weights
base_model$trainable <- FALSE
# Add custom classifier head
model <- keras_model(
inputs = base_model$input,
outputs = base_model$output |>
layer_global_average_pooling_2d() |>
layer_dense(128, activation = 'relu') |>
layer_dense(5, activation = 'softmax')
)Conv2D 填充和步幅
layer_conv_2d 有两个重要参数:padding = 'same' 会在输入周围补零,使输出的空间大小与输入相同;padding = 'valid'(默认值)会使维度减少 kernel_size - 1。strides = c(2,2) 让滤波器以 2 为步长滑动,从而替代最大池化。
# 'same' padding: output = input size
conv_same <- layer_conv_2d(filters = 32, kernel_size = c(3, 3),
padding = 'same')
# Strided convolution instead of pooling
conv_strided <- layer_conv_2d(filters = 64, kernel_size = c(3, 3),
strides = c(2, 2), # halves spatial dims
padding = 'same')
# Model using strides instead of max pooling
model2 <- keras_model_sequential(input_shape = c(28, 28, 1)) |>
layer_conv_2d(32, c(3,3), strides = c(2,2), activation = 'relu',
padding = 'same') |>
layer_conv_2d(64, c(3,3), strides = c(2,2), activation = 'relu',
padding = 'same') |>
layer_flatten() |>
layer_dense(10, activation = 'softmax')
summary(model2)快速检查
在 CNN 中,layer_max_pooling_2d(pool_size = c(2, 2)) 的主要作用是什么?
CNN 回顾
卷积神经网络基础的要点:
- CNN 使用局部感受野和参数共享机制,高效处理图像。
layer_conv_2d(filters, kernel_size, activation)提取空间特征。layer_max_pooling_2d(pool_size)进行下采样,并提供平移不变性。layer_flatten()将卷积主干连接到全连接分类头。layer_dropout(rate)对分类头进行正则化。- 数据增强层(
layer_random_flip()等)可以减少过拟合。 - 对于小型数据集,使用预训练主干进行迁移学习是实用的方法。
# Standard CNN architecture for image classification
model <- keras_model_sequential(input_shape = c(32, 32, 3)) |>
layer_conv_2d(32, c(3,3), activation = 'relu', padding = 'same') |>
layer_max_pooling_2d(c(2,2)) |>
layer_conv_2d(64, c(3,3), activation = 'relu', padding = 'same') |>
layer_max_pooling_2d(c(2,2)) |>
layer_conv_2d(128, c(3,3), activation = 'relu', padding = 'same') |>
layer_flatten() |>
layer_dense(256, activation = 'relu') |>
layer_dropout(0.5) |>
layer_dense(num_classes, activation = 'softmax')
model |> compile('adam', 'categorical_crossentropy', 'accuracy')
summary(model)用 AI 导师学习 R — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 43
- 课程
- 159
常见问题解答
「卷积神经网络基础」课时是免费的吗?
是的 — 「卷积神经网络基础」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。
「卷积神经网络基础」这节课中我会学到什么?
添加 Conv2D 和 MaxPooling 层,用于图像分类任务 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 R Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「卷积神经网络基础」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 R Academy 课中编写并运行代码吗?
能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。