卷积层 #
卷积操作原理 #
卷积层通过卷积核在输入上滑动,提取局部特征。
text
┌─────────────────────────────────────────────────────────────┐
│ 卷积操作示意 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 输入 (5×5) 卷积核 (3×3) 输出 (3×3) │
│ ┌─┬─┬─┬─┬─┐ ┌─┬─┬─┐ ┌─┬─┬─┐ │
│ │1│1│1│0│0│ │1│0│1│ │4│3│4│ │
│ ├─┼─┼─┼─┼─┤ ├─┼─┼─┤ ├─┼─┼─┤ │
│ │0│1│1│1│0│ * │0│1│0│ = │2│4│3│ │
│ ├─┼─┼─┼─┼─┤ ├─┼─┼─┤ ├─┼─┼─┤ │
│ │0│0│1│1│1│ │1│0│1│ │2│3│4│ │
│ ├─┼─┼─┼─┼─┤ └─┴─┴─┘ └─┴─┴─┘ │
│ │0│0│1│1│0│ │
│ ├─┼─┼─┼─┼─┤ 计算过程: │
│ │0│1│1│0│0│ 1×1+1×0+1×1+ │
│ └─┴─┴─┴─┴─┘ 0×0+1×1+1×0+ │
│ 0×1+0×0+1×1 = 4 │
│ │
└─────────────────────────────────────────────────────────────┘
Conv2D 层 #
基本用法 #
python
import keras
model = keras.Sequential([
keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
keras.layers.MaxPooling2D(),
keras.layers.Flatten(),
keras.layers.Dense(10, activation='softmax')
])
参数详解 #
python
keras.layers.Conv2D(
filters=32,
kernel_size=3,
strides=(1, 1),
padding='valid',
activation='relu',
use_bias=True,
kernel_initializer='glorot_uniform',
bias_initializer='zeros',
kernel_regularizer=None,
bias_regularizer=None
)
text
┌─────────────────────────────────────────────────────────────┐
│ Conv2D 参数说明 │
├─────────────────────────────────────────────────────────────┤
│ │
│ filters: 卷积核数量(输出通道数) │
│ ├── 决定输出特征图的深度 │
│ └── 常见值: 32, 64, 128, 256 │
│ │
│ kernel_size: 卷积核大小 │
│ ├── 整数: 正方形卷积核 │
│ ├── 元组: (height, width) │
│ └── 常见值: 3, 5, 7 │
│ │
│ strides: 步幅 │
│ ├── 控制卷积核移动步长 │
│ └── 增大步幅会减小输出尺寸 │
│ │
│ padding: 填充方式 │
│ ├── 'valid': 无填充,输出尺寸减小 │
│ └── 'same': 填充使输出尺寸等于输入 │
│ │
└─────────────────────────────────────────────────────────────┘
输出尺寸计算 #
text
┌─────────────────────────────────────────────────────────────┐
│ 输出尺寸公式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 输出尺寸 = floor((W - K + 2P) / S) + 1 │
│ │
│ W: 输入尺寸 │
│ K: 卷积核大小 │
│ P: 填充大小 │
│ S: 步幅 │
│ │
│ 示例: │
│ 输入: 224×224, 卷积核: 3×3, 填充: 1, 步幅: 1 │
│ 输出: (224 - 3 + 2×1) / 1 + 1 = 224 │
│ │
│ 输入: 224×224, 卷积核: 3×3, 填充: 0, 步幅: 2 │
│ 输出: (224 - 3 + 0) / 2 + 1 = 112 │
│ │
└─────────────────────────────────────────────────────────────┘
不同配置示例 #
python
import keras
x = keras.Input(shape=(224, 224, 3))
conv1 = keras.layers.Conv2D(64, 3, padding='same')(x)
print(f"Same padding: {conv1.shape}")
conv2 = keras.layers.Conv2D(64, 3, padding='valid')(x)
print(f"Valid padding: {conv2.shape}")
conv3 = keras.layers.Conv2D(64, 3, strides=2, padding='same')(x)
print(f"Stride=2: {conv3.shape}")
conv4 = keras.layers.Conv2D(64, 7, strides=2, padding='same')(x)
print(f"Kernel=7, Stride=2: {conv4.shape}")
池化层 #
池化层用于降低特征图的空间维度。
text
┌─────────────────────────────────────────────────────────────┐
│ 池化类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 最大池化 (MaxPooling) │
│ ┌───┬───┬───┬───┐ ┌───┬───┐ │
│ │ 1 │ 3 │ 2 │ 0 │ │ 3 │ 2 │ │
│ ├───┼───┼───┼───┤ ├───┼───┤ │
│ │ 2 │ 0 │ 1 │ 5 │ ───► │ 4 │ 5 │ │
│ ├───┼───┼───┼───┤ └───┴───┘ │
│ │ 0 │ 4 │ 3 │ 1 │ 取每个区域的最大值 │
│ ├───┼───┼───┼───┤ │
│ │ 2 │ 1 │ 0 │ 3 │ │
│ └───┴───┴───┴───┘ │
│ │
│ 平均池化 (AveragePooling) │
│ 取每个区域的平均值 │
│ │
│ 全局池化 (GlobalPooling) │
│ 将整个特征图池化为一个值 │
│ │
└─────────────────────────────────────────────────────────────┘
MaxPooling2D #
python
import keras
model = keras.Sequential([
keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
keras.layers.MaxPooling2D(pool_size=2),
keras.layers.Conv2D(64, 3, activation='relu'),
keras.layers.MaxPooling2D(pool_size=2),
keras.layers.Flatten(),
keras.layers.Dense(10, activation='softmax')
])
AveragePooling2D #
python
import keras
model = keras.Sequential([
keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
keras.layers.AveragePooling2D(pool_size=2),
keras.layers.Flatten(),
keras.layers.Dense(10, activation='softmax')
])
GlobalAveragePooling2D #
python
import keras
model = keras.Sequential([
keras.layers.Conv2D(64, 3, activation='relu', input_shape=(224, 224, 3)),
keras.layers.Conv2D(128, 3, activation='relu'),
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(10, activation='softmax')
])
Conv1D 层 #
Conv1D 用于处理序列数据。
python
import keras
model = keras.Sequential([
keras.layers.Embedding(10000, 128, input_length=100),
keras.layers.Conv1D(64, 3, activation='relu'),
keras.layers.GlobalMaxPooling1D(),
keras.layers.Dense(10, activation='softmax')
])
Conv3D 层 #
Conv3D 用于处理视频或 3D 数据。
python
import keras
model = keras.Sequential([
keras.layers.Conv3D(32, 3, activation='relu', input_shape=(16, 112, 112, 3)),
keras.layers.MaxPooling3D(pool_size=2),
keras.layers.Conv3D(64, 3, activation='relu'),
keras.layers.GlobalAveragePooling3D(),
keras.layers.Dense(10, activation='softmax')
])
SeparableConv2D 层 #
深度可分离卷积,参数更少。
python
import keras
model = keras.Sequential([
keras.layers.SeparableConv2D(32, 3, activation='relu', input_shape=(224, 224, 3)),
keras.layers.SeparableConv2D(64, 3, activation='relu'),
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(10, activation='softmax')
])
DepthwiseConv2D 层 #
深度卷积,每个输入通道单独卷积。
python
import keras
model = keras.Sequential([
keras.layers.DepthwiseConv2D(3, padding='same', input_shape=(224, 224, 3)),
keras.layers.BatchNormalization(),
keras.layers.Activation('relu'),
keras.layers.Conv2D(64, 1),
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(10, activation='softmax')
])
Conv2DTranspose 层 #
转置卷积(反卷积),用于上采样。
python
import keras
model = keras.Sequential([
keras.layers.Dense(7 * 7 * 128, input_shape=(100,)),
keras.layers.Reshape((7, 7, 128)),
keras.layers.BatchNormalization(),
keras.layers.Conv2DTranspose(64, 3, strides=2, padding='same', activation='relu'),
keras.layers.BatchNormalization(),
keras.layers.Conv2DTranspose(32, 3, strides=2, padding='same', activation='relu'),
keras.layers.Conv2D(1, 3, padding='same', activation='sigmoid')
])
UpSampling2D 层 #
简单的上采样层。
python
import keras
model = keras.Sequential([
keras.layers.Conv2D(32, 3, padding='same', input_shape=(14, 14, 3)),
keras.layers.UpSampling2D(size=2),
keras.layers.Conv2D(64, 3, padding='same'),
keras.layers.Conv2D(3, 3, padding='same')
])
Cropping2D 层 #
裁剪层,用于去除边缘。
python
import keras
model = keras.Sequential([
keras.layers.Conv2D(32, 3, padding='same', input_shape=(32, 32, 3)),
keras.layers.Cropping2D(cropping=4),
])
ZeroPadding2D 层 #
零填充层。
python
import keras
model = keras.Sequential([
keras.layers.ZeroPadding2D(padding=1, input_shape=(28, 28, 1)),
keras.layers.Conv2D(32, 3),
])
完整 CNN 示例 #
python
import keras
model = keras.Sequential([
keras.layers.Input(shape=(32, 32, 3)),
keras.layers.Conv2D(32, 3, padding='same'),
keras.layers.BatchNormalization(),
keras.layers.Activation('relu'),
keras.layers.Conv2D(32, 3, padding='same'),
keras.layers.BatchNormalization(),
keras.layers.Activation('relu'),
keras.layers.MaxPooling2D(),
keras.layers.Dropout(0.25),
keras.layers.Conv2D(64, 3, padding='same'),
keras.layers.BatchNormalization(),
keras.layers.Activation('relu'),
keras.layers.Conv2D(64, 3, padding='same'),
keras.layers.BatchNormalization(),
keras.layers.Activation('relu'),
keras.layers.MaxPooling2D(),
keras.layers.Dropout(0.25),
keras.layers.Flatten(),
keras.layers.Dense(512),
keras.layers.BatchNormalization(),
keras.layers.Activation('relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(10, activation='softmax')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
model.summary()
下一步 #
现在你已经掌握了卷积层,接下来学习 循环层,处理序列数据!
最后更新:2026-04-04