简介这份资源面向计算机、人工智能、生物信息等方向的在校学生与教师以及需要完成毕业设计、课程设计或项目立项演示的开发者提供一套基于LSTM与注意力机制预测蛋白质-配体结合亲和力的完整Python实现方案。压缩包共10个文件约13.06MB包含4个py源码文件、2个csv特征数据集、1个h5训练权重、1个log运行日志以及txt、md说明文档覆盖特征生成、数据连接与pka处理、网络训练及注意力模块等核心环节代码均经过测试可正常运行。已有362人学习下载说明该方案在同类任务中具备一定参考价值。读者可据此理解序列特征建模、注意力加权与亲和力回归的完整流程并在此基础上修改网络结构或替换数据集用于毕设、课设或算法进阶练习。1. 从一份能跑通的毕设说起LSTM注意力机制预测蛋白质-配体结合亲和力蛋白质-配体结合亲和力预测是药物筛选和分子对接里绕不开的一环。传统做法靠分子动力学模拟或者打分函数算一次动辄几小时到几天批量筛选基本靠排队。这份资源给了一条完全不同的路子用 LSTM 加注意力机制把结合亲和力当成一个回归任务来学输入是蛋白质和配体的序列/特征输出是一个连续的亲和力数值。压缩包里带了 Onion1 的两份特征 CSV、训练好的 bestmodel_0220.h5、四个 Python 脚本和注释属于那种「下载完配好环境就能跑」的课程设计/毕业设计级别工程。它适合谁计算机、人工智能、生物信息方向的学生拿来做毕设或课设也适合想入门深度学习回归任务的工程师拿来当练手项目——数据现成、模型结构清晰、注释到位改起来不费劲。2. 拆开压缩包四个脚本和两份数据到底怎么串起来2.1 文件清单与各自职责先把包里的东西摊开看。README.txt 和 README.md 是说明数据集目录下是 Onion1_Feature_D2016.csv、Onion1_Feature_D2013.csv 和 logfile_new.log程序目录下是四个脚本加一个模型文件。这四个脚本不是并列关系而是一条流水线文件作用输入输出生成特征.py从原始数据构造特征矩阵原始序列/结构数据特征 CSV连接数据和pka.py把特征和 pKa 标签对齐合并特征 CSV 标签训练用数据集myattention.py定义注意力层无模块可调用的 Attention 类训练网络.py搭 LSTMAttention 模型并训练合并后的数据集bestmodel_0220.h5理解这条链路比直接跑脚本重要得多。很多人拿到包第一反应是python 训练网络.py结果报错说找不到文件——因为特征还没生成、数据还没合并。正确顺序是先跑生成特征再跑连接数据最后才是训练。myattention.py 是被训练脚本 import 的不单独执行。2.2 特征生成从原始数据到 Onion1_Feature生成特征.py 干的事是把蛋白质和配体的原始信息转成模型能吃的数值矩阵。蛋白质这边常见做法是用氨基酸的理化性质编码疏水性、电荷、体积等配体这边用分子指纹或原子类型编码。脚本里应该能看到类似这样的处理逻辑import numpy as np import pandas as pd def encode_protein(seq, max_len1000): # 氨基酸理化性质映射表20种标准氨基酸 aa_props { A: [1.8, 0.0, 88.6], R: [-4.5, 1.0, 173.4], N: [-3.5, 0.0, 114.1], D: [-3.5, -1.0, 111.1], # ... 其余氨基酸 } # 截断或补零到固定长度保证批量训练时维度一致 seq seq[:max_len] feat np.zeros((max_len, 3)) for i, aa in enumerate(seq): if aa in aa_props: feat[i] aa_props[aa] return feat def encode_ligand(smiles, max_atoms100): # 简化版按原子序数编码实际项目可能用 RDKit 生成指纹 atom_feats [] for atom in smiles[:max_atoms]: atom_feats.append([ord(atom) % 20, 1.0, 0.0]) while len(atom_feats) max_atoms: atom_feats.append([0, 0, 0]) return np.array(atom_feats)这段代码的关键参数是 max_len 和 max_atoms。max_len 控制蛋白质序列截断长度设太小会丢信息设太大显存吃不消1000 是个折中值。max_atoms 同理配体原子数一般不超过 100。补零操作是为了让不同长度的样本能堆成同一个 batch这是 LSTM 处理变长序列的标准做法。生成完的特征会存成 Onion1_Feature_D2016.csv 这种格式D2016 和 D2013 大概率对应不同年份或不同版本的数据集训练时选一份用就行。2.3 数据连接与 pKa 标签对齐连接数据和pka.py 解决的是「特征有了标签在哪」的问题。pKa 在这里代表结合亲和力的某种度量可能是 -logKd 或 -logKi是回归任务的目标值。这个脚本要做的是按样本 ID 把特征矩阵和标签一一对应起来去掉缺失值可能还要做归一化import pandas as pd from sklearn.preprocessing import StandardScaler # 读取特征和标签 features pd.read_csv(Onion1_Feature_D2016.csv) labels pd.read_csv(pka_labels.csv) # 假设标签文件 # 按 ID 合并inner join 保证只保留两边都有的样本 data pd.merge(features, labels, onsample_id, howinner) print(f合并后样本数: {len(data)}) # 特征归一化pKa 值单独拿出来做目标 feature_cols [c for c in data.columns if c not in [sample_id, pka]] scaler StandardScaler() data[feature_cols] scaler.fit_transform(data[feature_cols]) # 保存归一化参数预测新样本时要复用 import joblib joblib.dump(scaler, scaler.pkl) data.to_csv(train_ready.csv, indexFalse)这里有个容易翻车的点归一化必须用训练集的均值和方差不能对全体数据 fit 完再切分否则测试集信息泄漏模型评估结果虚高。我一般会先把数据切分成 train/test只用 train fit scaler然后 transform 两边。另外 pKa 标签如果有异常值比如超过合理范围的要在这一步过滤掉不然回归模型会被带偏。2.4 注意力层myattention.py 里到底写了什么myattention.py 是整个模型的核心创新点。LSTM 本身能捕捉序列的时序依赖但它对长序列的记忆能力有限注意力机制的作用是让模型在预测时能「聚焦」到关键位置。常见的实现是加性注意力Bahdanau或点积注意力import tensorflow as tf from tensorflow.keras import layers class AttentionLayer(layers.Layer): def __init__(self, units): super(AttentionLayer, self).__init__() # 用一个小 MLP 计算每个时间步的注意力分数 self.W layers.Dense(units, activationtanh) self.V layers.Dense(1) def call(self, lstm_output): # lstm_output 形状: (batch, timesteps, features) score self.V(self.W(lstm_output)) # (batch, timesteps, 1) weights tf.nn.softmax(score, axis1) # 归一化成概率 context tf.reduce_sum(weights * lstm_output, axis1) # 加权求和 return context, weights这段代码的逻辑是LSTM 输出每个时间步的隐状态注意力层给每个时间步算一个分数softmax 归一化后得到权重最后加权求和得到一个固定长度的上下文向量。这个向量再接到全连接层做回归。参数 units 控制注意力内部 MLP 的宽度一般设成 LSTM 隐藏单元数的一半到相等。返回 weights 是为了可视化——你可以看模型到底关注了序列的哪些位置这对解释预测结果很有用答辩时也是加分项。3. 训练网络.py 逐段拆解从搭模型到存 h53.1 模型结构LSTM 堆叠 注意力 回归头训练网络.py 把前面几个模块串起来。典型的模型结构是输入层 → LSTM 层可能堆两层→ 注意力层 → 全连接层 → 输出一个标量。用 Keras 函数式 API 写出来大概是这样from tensorflow.keras import Input, Model from tensorflow.keras.layers import LSTM, Dense, Dropout, Bidirectional from myattention import AttentionLayer def build_model(timesteps, n_features): inputs Input(shape(timesteps, n_features)) # 双向 LSTM正反两个方向都扫一遍序列 x Bidirectional(LSTM(128, return_sequencesTrue))(inputs) x Dropout(0.3)(x) # 防过拟合 # 注意力层返回上下文向量和权重 context, weights AttentionLayer(64)(x) x Dense(64, activationrelu)(context) x Dropout(0.2)(x) outputs Dense(1)(x) # 回归输出不加激活函数 model Model(inputsinputs, outputsoutputs) model.compile(optimizeradam, lossmse, metrics[mae]) return model几个关键选择用 Bidirectional 包 LSTM 是因为蛋白质序列正反方向的信息都重要return_sequencesTrue 必须开否则注意力层拿不到每个时间步的输出输出层用 Dense(1) 不加激活因为回归任务输出范围不限loss 用 MSE 是回归的标准选择metrics 加 MAE 方便看平均绝对误差。Dropout 比例 0.3 和 0.2 是经验值数据量小的时候可以调大数据量大可以调小。3.2 训练循环与回调早停和模型保存训练部分要处理两个问题什么时候停、怎么保存最好的模型。Keras 的 callbacks 能搞定from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau callbacks [ # 验证损失 20 轮不降就停恢复最优权重 EarlyStopping(monitorval_loss, patience20, restore_best_weightsTrue), # 只保存验证损失最低的模型 ModelCheckpoint(bestmodel_0220.h5, monitorval_loss, save_best_onlyTrue, verbose1), # 损失停滞时降低学习率帮助跳出局部最优 ReduceLROnPlateau(monitorval_loss, factor0.5, patience10, min_lr1e-6) ] history model.fit( X_train, y_train, validation_data(X_val, y_val), epochs200, batch_size32, callbackscallbacks )EarlyStopping 的 patience20 意味着给模型 20 轮机会如果验证损失一直不降就停restore_best_weights 保证最后拿到的是最优轮次的权重而不是最后一轮的。ModelCheckpoint 的 save_best_only 避免保存一堆中间模型。ReduceLROnPlateau 是玄学调参的好帮手——学习率太大导致震荡时自动砍半。batch_size32 是显存和梯度稳定性的折中显存够可以调到 64 或 128。3.3 评估与预测别只看 loss训练完不能只看 loss 曲线就完事。回归任务要看预测值和真实值的散点图、Pearson 相关系数、RMSEfrom scipy.stats import pearsonr from sklearn.metrics import mean_squared_error import numpy as np y_pred model.predict(X_test).flatten() rmse np.sqrt(mean_squared_error(y_test, y_pred)) r, p_value pearsonr(y_test, y_pred) print(fRMSE: {rmse:.3f}) print(fPearson r: {r:.3f} (p{p_value:.2e})) # 画散点图看预测偏差分布 import matplotlib.pyplot as plt plt.scatter(y_test, y_pred, alpha0.5) plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], r--) plt.xlabel(True pKa) plt.ylabel(Predicted pKa) plt.savefig(pred_vs_true.png, dpi150)Pearson r 是衡量预测趋势是否正确的指标RMSE 衡量绝对误差大小。如果 r 高但 RMSE 大说明趋势对但数值偏如果 r 低说明模型根本没学到东西。散点图能直观看出模型在哪个区间预测不准——常见的是高亲和力区间被低估因为样本少。4. 避坑指南跑这份代码最容易翻车的五个地方4.1 现象ImportError: No module named tensorflow原因环境里没装 TensorFlow或者装的是 CPU 版但代码用了 GPU 相关配置。这份代码用的是 Keras 高层 APITensorFlow 2.x 自带 Keras不需要单独装 keras 包。解决先确认 Python 版本建议 3.7-3.9然后pip install tensorflow2.6.0或更新版本。如果要用 GPU装tensorflow-gpu并确认 CUDA 和 cuDNN 版本匹配。装完python -c import tensorflow as tf; print(tf.__version__)验证。4.2 现象训练时 loss 变成 nan原因学习率太大、数据没归一化、或者序列里有异常值。LSTM 对输入尺度敏感特征值范围差几个数量级时梯度容易爆炸。解决先检查数据归一化是否做了StandardScaler 或 MinMaxScaler 都行。然后把学习率从默认的 1e-3 降到 1e-4 试试。还可以加梯度裁剪optimizer tf.keras.optimizers.Adam(clipnorm1.0)。如果还不行检查标签里有没有 inf 或超大值。4.3 现象验证集 loss 比训练集低很多原因数据泄漏。最常见的是归一化时用了全体数据或者 train/test 切分前就做了特征选择。另一个可能是 Dropout 在验证时没关Keras 会自动处理但自定义层要注意。解决严格按「先切分再归一化」的顺序来。用train_test_split切完再对 X_train fit scaler。如果用了自定义层确认training参数传递正确。4.4 现象模型预测值全是一个常数原因注意力层输出被 softmax 压平了或者 LSTM 根本没学到东西。也可能是学习率太小模型还没开始学就停了。解决先检查注意力权重的分布如果所有权重都差不多说明注意力没起作用。可以试着去掉注意力层只用 LSTM 跑一遍看 loss 能不能降。如果能降说明问题在注意力实现如果不能说明数据或 LSTM 配置有问题。另外确认 EarlyStopping 的 patience 别设太小模型可能只是需要更多轮次。4.5 现象h5 模型加载时报「Unknown layer: AttentionLayer」原因自定义层在保存时没注册加载时 Keras 不认识。解决加载时用custom_objects参数from myattention import AttentionLayer model tf.keras.models.load_model(bestmodel_0220.h5, custom_objects{AttentionLayer: AttentionLayer})或者在定义 AttentionLayer 时加tf.keras.utils.register_keras_serializable()装饰器这样保存和加载都能自动识别。5. 进阶玩法把这份代码改成你自己的毕设5.1 换数据集从 Onion1 到其他亲和力数据这份代码的数据接口是 CSV换数据集的核心是改「生成特征.py」和「连接数据和pka.py」。常见做法是去 PDBbind 下载亲和力数据用 RDKit 生成配体指纹用 BioPython 提取蛋白质序列。特征维度变了之后训练脚本里的n_features参数要同步改。如果新数据集的标签分布和 Onion1 差很多建议重新做归一化别复用旧的 scaler。5.2 换模型把 LSTM 换成 Transformer注意力机制现在更流行的玩法是 Transformer完全靠自注意力不用 RNN。如果你想升级可以把 LSTM 层换成MultiHeadAttentionfrom tensorflow.keras.layers import MultiHeadAttention, LayerNormalization # 替换 Bidirectional(LSTM(...)) attn_output MultiHeadAttention(num_heads8, key_dim64)(inputs, inputs) x LayerNormalization()(inputs attn_output) # 残差连接 x Dense(128, activationrelu)(x)这样改完模型更现代但训练数据量要求也更高。Onion1 这种规模的数据集LSTMAttention 可能比 Transformer 更稳。5.3 验证方法交叉验证代替单次切分单次 train/test 切分的结果波动大答辩时容易被质疑。改成 5 折交叉验证from sklearn.model_selection import KFold kf KFold(n_splits5, shuffleTrue, random_state42) scores [] for fold, (train_idx, val_idx) in enumerate(kf.split(X)): X_train, X_val X[train_idx], X[val_idx] y_train, y_val y[train_idx], y[val_idx] model build_model(timesteps, n_features) model.fit(X_train, y_train, validation_data(X_val, y_val), epochs100, batch_size32, verbose0) y_pred model.predict(X_val).flatten() r, _ pearsonr(y_val, y_pred) scores.append(r) print(fFold {fold1}: Pearson r {r:.3f}) print(f平均 Pearson r: {np.mean(scores):.3f} ± {np.std(scores):.3f})交叉验证能给出更可靠的性能估计标准差还能反映模型稳定性。如果某折特别差说明数据分布有问题要回去检查。5.4 一个具体技巧注意力权重可视化答辩时老师最爱问「注意力机制到底学到了什么」。把 myattention.py 返回的 weights 画出来# 取一个测试样本 sample X_test[0:1] _, attn_weights model.predict(sample) # 需要模型输出 weights attn_weights attn_weights[0, :, 0] # (timesteps,) plt.bar(range(len(attn_weights)), attn_weights) plt.xlabel(Sequence Position) plt.ylabel(Attention Weight) plt.title(Attention Distribution) plt.savefig(attention_vis.png, dpi150)如果模型学到了东西你会看到权重集中在某些位置而不是均匀分布。这些位置可能对应结合口袋的关键残基。把这个图和生物学知识对上就是一篇完整的毕设故事。从那以后我每次拿到这种带注意力机制的模型都会强制走一遍「训练→评估→注意力可视化」的流程因为 loss 曲线好看不代表模型真的学到了有意义的模式。希望这份拆解能帮你少走点弯路把这份资源真正用起来。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
近红外脑功能成像技术全解析:从原理到实验设计与应用 做脑功能成像这一行,身边不少朋友一听我提“近红外脑功能成像技术”,第一反应都是:“是不是就是拿红外光拍脑袋?”说实话,这个说法虽然糙了点,但也算抓住了重点。近红外脑功能成像技术,英文叫fN… · 2026/9/23 5:39:07
新国标移动电源方案:英集芯锂保+SOC全集成的落地实操与避坑指南 移动电源这个品类,这两年最大的变量就是新国标。以前做一版方案,主控加锂保加协议芯片,三颗料堆上去,板子大、成本高、调试还容易互相打架。GB47372 落地之后,温升、过充保护、放电截止这些硬指标卡得更死,… · 2026/9/23 5:39:01
零基础自学Altium Designer:从新建工程到PCB布线的第一天踩坑实录 1. 一个纯小白打开Altium Designer的真实心路1.1 为什么是Altium Designer,而不是别的说实话,决定自学PCB的那一刻,我连“PCB”三个字母的全称都拼不利索。Printed Circuit Board,印刷电路板,就这么个东西,… · 2026/9/23 5:39:01
vc 教程源码解析:搞定环境配置,C++入门到精通 vc 教程源码解析:搞定环境配置,C++入门到精通 配置环境就卡半天?Visual Studio 安装包巨大,组件勾选眼花缭乱,编译报错满屏飘。很多转行做 C++ 开发的同行,还没写第一行代码,就在搭建 VC… · 2026/9/23 6:34:05
qq64位下载入门到精通:解决版本升级API全变痛点 qq64位下载入门到精通:解决版本升级API全变痛点 版本升级后 API 全变了,很多老手都在这一步卡壳。 想从 qq64位下载 的入门到精通,光看文档根本不够。 必须搞懂底层协议,才能应对腾讯频繁的接口变动。 项目目标… · 2026/9/23 6:34:05
800V车载PFC电感选型:磁芯材料、一体封装与动态饱和深度解析 1. 这不是选电感,是给800V车载PFC电路“挑心脏”PFC电感、升压电感、车载PFC、800V平台——这几个词最近在电源工程师的微信群里刷屏频率,比咖啡因还高。我上个月帮一家新势力车企做OBC(车载充电机)二轮评审,光是电感选… · 2026/9/23 6:34:05
三相并网逆变器控制策略与Simulink仿真实践 1. 项目背景与核心挑战三相并网逆变器作为新能源发电系统的关键接口设备,其性能直接影响电能质量与系统稳定性。在实际电网环境中,三相电压不平衡是常见工况(根据IEEE 1547标准,允许的最大电压不平衡度为3%)。这种不平… · 2026/9/23 6:34:05
从Function Calling到技能包:构建可复用的智能体技能系统 这几年做大模型应用,我有一个特别深的感触:真正难的不是把模型接进来,而是让模型稳定地干杂活。你写一个 agent,要它查资料、算数据、调接口、整理报告,如果每个能力都临时写死在 prompt 里,一两个功能还行… · 2026/9/23 6:33:53
3步吃透A调源码:别再只背八股,这次真能写项目 3步吃透A调源码:别再只背八股,这次真能写项目 看了一堆教程还是不会写项目?别怪自己笨,是你缺了“源码解析”这一环。 很多新手卡在“听懂了但手不动”,根源在于只看了表层API,没看懂底层数据流。 今天不讲虚的,直接拆解一个真实场景中的… · 2026/9/23 6:33:53
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29