【深度学习-pytorch篇】5. 卷积神经网络与LLaMA分类模型
卷积神经网络与LLaMA分类模型
一、卷积操作基础
卷积是深度学习中用于提取局部特征的核心操作,特别适用于图像识别任务。
自定义二维卷积函数示例
以下函数实现了一个简化版的二维卷积:
def convolve2D(image, kernel, padding=0, strides=1):kernel = np.flipud(np.fliplr(kernel)) # 进行卷积(交叉相关)Wk, Hk = kernel.shapeW, H = image.shapeW_out = int(((W - Wk + 2 * padding) / strides) + 1)H_out = int(((H - Hk + 2 * padding) / strides) + 1)output = np.zeros((W_out, H_out))if padding != 0:padded = np.zeros((W + 2*padding, H + 2*padding))padded[padding:-padding, padding:-padding] = imageelse:padded = imagefor y in range(0, H_out):for x in range(0, W_out):region = padded[x*strides:x*strides+Wk, y*strides:y*strides+Hk]output[x, y] = np.sum(region * kernel)return output
常见滤波器(以灰度图为例)
# 水平边缘检测
horizontal_filter = np.array([[1, 1, 1],[0, 0, 0],[-1, -1, -1]
])# 垂直边缘检测
vertical_filter = np.array([[-1, 0, 1],[-1, 0, 1],[-1, 0, 1]
])# 锐化滤波器
sharpen_filter = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, -1]
])
这些手工设计的卷积核虽然能提取部分边缘特征,但不够通用,且难以组合优化。解决方案是使用可学习的卷积核,这就是 CNN 的核心思想。
二、卷积层结构(多通道 & 多滤波器)
在 RGB 图像中,通常使用每通道分别卷积,再将其结果相加作为最终输出。
# 单个卷积核处理三通道图像
output = convolve2D(R, kernel) + convolve2D(G, kernel) + convolve2D(B, kernel)
若使用多个卷积核,可以将每组卷积结果堆叠成不同的特征图(feature maps)。
三、CNN 在 MNIST 手写数字识别上的应用
模型结构定义(基于 PyTorch)
import torch.nn as nn
import torch.nn.functional as Fclass MnistConvNet(nn.Module):def __init__(self):super().__init__()self.conv1 = nn.Conv2d(1, 32, kernel_size=7, padding=3)self.conv2 = nn.Conv2d(32, 64, kernel_size=5, padding=2)self.dropout1 = nn.Dropout2d(0.25)self.dropout2 = nn.Dropout(0.5)self.fc1 = nn.Linear(7*7*64, 128)self.fc2 = nn.Linear(128, 10)def forward(self, x):x = F.relu(self.conv1(x)) # 输出尺寸:28x28 -> 28x28x = F.max_pool2d(x, 2) # -> 14x14x = F.relu(self.conv2(x)) # -> 14x14x = F.max_pool2d(x, 2) # -> 7x7x = self.dropout1(x)x = x.view(-1, 7*7*64)x = F.relu(self.fc1(x))x = self.dropout2(x)return self.fc2(x)
四、LLaMA 模型用于序列分类(LlamaForSequenceClassification)
LLaMA 模型是基于 Transformer 的自回归语言模型。它也可以通过在顶部加上分类头来执行序列分类任务。
分类模型结构说明
from transformers import LlamaModel, LlamaPreTrainedModel
import torch.nn as nnclass LlamaForSequenceClassification(LlamaPreTrainedModel):def __init__(self, config):super().__init__(config)self.num_labels = config.num_labelsself.model = LlamaModel(config)self.score = nn.Linear(config.hidden_size, self.num_labels, bias=False)self.post_init()def forward(self, input_ids, attention_mask=None, labels=None):outputs = self.model(input_ids, attention_mask=attention_mask)hidden_states = outputs[0]last_hidden = hidden_states[:, -1, :] # 取最后一个 token 的表示logits = self.score(last_hidden)loss = Noneif labels is not None:if self.num_labels == 1:loss = nn.MSELoss()(logits.view(-1), labels.view(-1))else:loss = nn.CrossEntropyLoss()(logits.view(-1, self.num_labels), labels.view(-1))return {"loss": loss, "logits": logits}
与 LlamaForCausalLM 的区别:
功能 | LlamaForCausalLM | LlamaForSequenceClassification |
---|---|---|
输出维度 | token-level | sequence-level |
输出方式 | 每个 token 的概率分布 | 整个序列一个 logits |
应用任务 | 文本生成 | 分类、回归 |
五、总结
- 卷积操作本质是局部加权求和,可以检测边缘、角点等局部结构;
- CNN 利用可学习的卷积核自动提取多尺度多通道特征,效果远优于人工滤波器;
- LLaMA 可以通过添加一个线性头扩展为分类器,适用于文本情感分析、主题分类等任务;
- 分类版本的 LLaMA 使用的是最后一个 token 的隐状态作为语义表示。