深度学习基础:前馈、卷积、循环、图网络

做迁移学习,绕不开深度学习的基础模型。说白了,这些网络就是我们的“传家宝”。你从源域学到的特征,最后都要落到这些架构里才能迁移到目标域。

我个人习惯把四个网络按“数据形态”分个类:前馈网络处理固定向量,卷积网络处理网格结构(如图像),循环网络处理序列,图网络处理非欧几里得的数据,比如分子、蛋白质结构。相互作用预测里,这四种网络都有用武之地。

1. 前馈网络(FNN)—— 最基础的拼图

前馈网络是全连接层的堆叠。你给它一个输入向量,它通过一系列线性变换加非线性激活,输出一个结果。

我在早期做结合亲和力预测时,就只用了三层全连接。效果嘛,能看,但总觉得欠点火候。后来才发现——简单模型适合做微调,不太适合做预训练。

import torch.nn as nn

class SimpleFNN(nn.Module):
    def __init__(self, input_dim=128, hidden_dim=64, output_dim=1):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim//2),
            nn.ReLU(),
            nn.Linear(hidden_dim//2, output_dim)
        )
    def forward(self, x):
        return self.net(x)

避坑指南:我曾经把前馈网络训练到过拟合,当时用Dropout补救。但迁移学习中,预训练的权重往往包含了丰富的结构信息,Dropout加太大会把特征“洗掉”。我建议在Fine-tune阶段用较低的Dropout率(0.1~0.2)。

2. 卷积网络(CNN)—— 抓局部模式的利器

卷积网络擅长捕捉空间局部关联。在图像上,它识别边缘、纹理;在相互作用预测里,它处理一维序列特征——比如把蛋白质的氨基酸编码成向量,用1D卷积扫过去,就能捕获短程的相互作用模式。

我记得有个项目要做化合物-蛋白质亲和力预测。我把蛋白质序列切成固定长度窗口,用1D-CNN提取局部特征。效果比全连接好15%。为什么?因为卷积核在局部区域共享权重,参数少,泛化强。

维度卷积类型应用场景
1DConv1d蛋白质序列、时间序列
2DConv2d分子指纹网格、结合口袋图像

关键知识点:CNN通过局部连接和权值共享降低参数量。在迁移学习中,预训练的CNN骨干(如ResNet)可以直接拿来提取高维特征,再接入任务头。

3. 循环网络(RNN)—— 序列依赖的建模者

RNN用于处理变长序列。但大家都知道,标准RNN有梯度消失的问题。所以实际中我们常用LSTM或GRU。

在相互作用预测里,RNN常被用来处理蛋白质或分子的顺序信息。比如从一个长序列里预测结合位点,就需要用到双向LSTM来捕捉前后上下文。

我自己用过Bi-LSTM做蛋白质‑药物相互作用。训练时loss掉得很慢,一度以为代码写错了。后来发现是序列长度差异大——短的十几,长的上千。我建议用动态RNN(pack_padded_sequence),避免填充带来的无效计算。

import torch.nn.utils.rnn as rnn_utils

# 假设 data 是已排序的长短序列 batch
packed = rnn_utils.pack_padded_sequence(emb, lengths, batch_first=True)
lstm_out, (h_n, c_n) = lstm(packed)
unpacked, _ = rnn_utils.pad_packed_sequence(lstm_out, batch_first=True)

注意:RNN在迁移学习中很容易发生灾难性遗忘。预训练语言模型的权重如果直接微调整个网络,长序列特征会迅速漂移。我建议先冻结RNN层,只训练线性分类头,稳定后再解冻。

4. 图网络(GNN)—— 结构化数据的王牌

图网络是近几年最火的方向。分子本身就是图——原子是节点,化学键是边。GNN通过消息传递机制,让每个节点聚合邻居信息来更新自己的表示。

相互作用预测里,你可以用GNN分别编码配体分子图和靶点蛋白质图,再把两个图的全局特征拼接,做分类或回归。这比人工特征(如分子指纹)效果好得多。

我做过一个GNN的迁移学习项目——小分子预训练(用自监督损失),然后在下游靶点亲和力任务上微调。效果比从头训练好10%以上。但要注意,GNN的层数不能太深,否则会过度平滑(所有节点表示趋于一致)。我建议最多3层。

class BasicGNNLayer(nn.Module):
    def __init__(self, in_dim, out_dim):
        super().__init__()
        self.linear = nn.Linear(in_dim, out_dim)
    def forward(self, x, edge_index):
        # 简单消息传递: 聚合邻居
        row, col = edge_index
        agg = scatter_mean(x[row], col, dim=0)
        return F.relu(self.linear(agg))
深度学习基础模型体系(相互作用预测场景) 输入数据(序列/图/向量) 前馈网络(FNN) 卷积网络(CNN) 循环网络(RNN/LSTM) 图网络(GNN) 固定长度向量 局部空间关联 时序依赖 拓扑结构 迁移学习(特征/模型/参数)

这张图画出了四种网络与迁移学习的关系:输入数据经过不同网络提取特征,最终都可以作为迁移学习的基础。你不需要每个网络都精通,但至少要知道各自适合的数据形态。

什么时候选哪个?

  • 输入是向量(如分子指纹、结构描述符) → 前馈网络
  • 输入是序列(如蛋白质氨基酸、DNA碱基) → CNN或RNN(混合使用效果更佳)
  • 输入是图(如分子结构、蛋白质接触图) → GNN
  • 希望做预训练再微调 → 优先选CNN(ResNet)或GNN(如GIN、MPNN),因为它们更鲁棒

个人建议:在做相互作用预测的迁移学习时,不要把时间浪费在调网络结构上。直接拿开源预训练模型(比如GIN、ChemBERTa)做特征提取,再加一个分类头,往往比从头搭网络快10倍。