1、特征提取流程简介
CNN 能从局部到整体逐步学习图像结构,前几层学到的特征通常是通用的(如边缘),后面是特定任务的(如人脸、动物),在迁移学习中,常使用 CNN 的前几层作为特征提取器,冻结它们权重,仅训练后面的分类器。
步骤 | 名称 | 作用说明 |
---|---|---|
1 | 输入图像 | 输入通常为 RGB 图像,形状为 (C, H, W) ,例如 (3, 224, 224) 。 |
2 | 卷积层 | 使用多个卷积核滑动窗口提取图像的局部特征(如边缘、纹理等)。 |
3 | 激活函数(ReLU) | 添加非线性能力,使模型可以学习复杂模式。 |
4 | 池化层 | 减少空间维度、压缩信息,保留关键特征(如最大池化 MaxPooling)。 |
5 | 重复卷积+池化 | 多层堆叠提取更高级的特征(从边缘到形状,再到语义特征)。 |
6 | 展平(Flatten) | 将多维特征图转为一维向量,用于后续分类或其他任务。 |
7 | 分类层(可选) | 如果用于分类,则连接全连接层 + softmax 输出预测类别。 |
2、特征提取器
特征提取器(Feature Extractor) 是指提取输入数据(通常是图像)的深层次特征的一段神经网络。它可以是自定义的 CNN 模块,也可以是使用预训练模型(如 ResNet、VGG)的一部分。
import torch
import torch.nn as nn
# 用于提取中间特征的模块
class Feature_extractor(nn.Module):
def __init__(self):
super(Feature_extractor, self).__init__()
self.feature = None
def forward(self, input):
self.feature = input.clone()
return input
# 模拟已有 CNN(可替换为 torchvision.models.resnet18 等)
cnn = nn.Sequential(
nn.Conv2d(3, 8, kernel_size=3, padding=1),
nn.ReLU(),
nn.Conv2d(8, 16, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(16, 32, kernel_size=3, padding=1),
nn.ReLU(),
)
# 创建新网络
new_net = nn.Sequential().cuda()
target_layers = ["conv_1", "conv_2", "conv_4"] # 要提取的层
extractors = {} # 用于保存 extractor 层引用
i = 1
for layer in list(cnn):
if isinstance(layer, nn.Conv2d):
name = f"conv_{i}"
new_net.add_module(name, layer)
if name in target_layers:
extractor = Feature_extractor()
new_net.add_module(f"extractor_{i}", extractor)
extractors[name] = extractor
i += 1
elif isinstance(layer, nn.ReLU):
new_net.add_module(f"relu_{i}", layer)
elif isinstance(layer, nn.MaxPool2d):
new_net.add_module(f"pool_{i}", layer)
# 模拟输入图像
your_image = torch.randn(1, 3, 32, 32).cuda()
output = new_net(your_image)
# 提取特征:例如 conv_4 的特征
print(extractors["conv_4"].feature.shape) # 输出特征图尺寸