EQTransformer实战:AI地震事件检测与P/S波拾取指南
2026/9/7 6:46:10 网站建设 项目流程

简介:EQTransformer 是一个基于注意力机制与深度神经网络的地震信号检测与 P/S 相位拾取 Python 软件包,面向地震学研究人员、数据科学家及地球物理开发者。它采用专门为地震信号设计的分层结构,模型已在全球地震数据上完成训练,可同时输出事件检测概率与 P、S 波到达时间,并附带模型不确定性估计,适合连续波形处理、余震监测与台阵资料分析等场景。压缩包共含 92 个文件,约 31.34MB;其中 Python 脚本覆盖数据下载、预处理、检测与相位拾取、模型训练与测试、简单相位关联等完整流程,Jupyter Notebook 提供训练、检测、可视化、下载和关联的交互示例,RST 文档与配置文件帮助理解环境和依赖,并附有预训练权重和百段样本数据用于快速验证。资源从源码实现、示例数据到说明文档一应俱全,既可直接用预训练模型处理真实地震数据,也能基于多任务学习与注意力机制改造和训练新模型。目前已有 1171 人学习下载,适合希望将深度学习方法落地到地震信号处理任务中的研究者和工程师。 做地震数据处理的同行应该都有同感:每天从台网拉回来的连续波形数据越来越大,可真正能盯着屏幕做人工分析的老师傅却越来越少。传统上,地震事件的识别和P波、S波到时拾取主要靠STA/LTA这类基于振幅特征的算法,再配合人工复核。但当地震密集、信噪比低的时候,误检率和漏检率都会明显上升。EQTransformer这个基于AI的Python软件包,正是冲着这个痛点来的:输入三分量波形,它直接输出事件检测概率和P波、S波到达概率,把“检测”和“拾取”合并成一步。

这篇文章我会从模型怎么设计、环境怎么搭,一直讲到真实台站数据怎么跑通、怎么处理阈值和滑窗这些工程问题,最后再聊聊我实测下来踩过的坑。内容适合两类人:一类是正在搭建自动化地震处理流程的科研人员和工程师,另一类是对AI在地球物理中的应用感兴趣、想找一个具体案例上手的同学。

1. 台网处理流程的瓶颈:为什么检测和拾取要一起解决

1.1 传统路线:STA/LTA检测与相位拾取是两套分离的流程

传统方案里,地震事件检测通常使用短时平均与长时平均的能量比值算法。它计算滑动窗口内的短时能量和长时能量的比值,当比值超过某个阈值时认为有事件到达。这套方法已经运行了好几十年,优点是计算量小、实现简单,缺点在低信噪比时表现很不稳定:强噪声背景、人为干扰、雷暴等都会造成大量误触发,而真正的小震级事件反而可能被淹没在背景里。

拾取环节同样不轻松。常用的拾取算法包括AIC(赤池信息准则)、偏振分析等,它们依赖波形特征突变点。当地震信号和背景噪声频带重叠、或者震相波形不明显时,拾取结果往往需要人工大量校正。这还不是最麻烦的,最麻烦的是这两套流程通常是互相独立的。检测模块给一个“大概有事件”的结论,拾取模块要在连续波形里重新找震相,一旦两个模块的参数不一致,实际处理链路里会出现大量需要人工兜底的边缘情况。

我当时尝试把这两套流程串成自动化时的体感是:每个模块单独看都能工作,连起来就互相“打架”。检测阈值调低了误报多,调高了又漏报,拾取结果夹在中间会更乱。如果只是处理单台站、少量事件,人工介入还能忍,但想扩展到区域台网、长时间连续数据,这套分离流程的维护成本会直线上升。

1.2 EQTransformer的设计思路:多任务学习把两步合并

EQTransformer的设计目标很直接:不再拆成检测和拾取两个独立模块,而是用同一个模型,同时输出事件检测概率、P波到达概率和S波到达概率。模型名字里带Transformer,但它不是纯粹的Transformer,而是一个卷积神经网络做底层特征提取、Transformer注意力模块做全局上下文建模的混合结构。

这个设计有一个很实用的意义:事件检测和相位拾取共享底层特征。波形里有没有地震事件,P波和S波具体到在哪个采样点,本质上是同一份信号在不同抽象层级上的属性。多任务共享特征的方式,让检测结果和拾取结果天然联动,省掉了模块间参数不一致的问题。这一点在生产环境里的价值,比模型精度数字提升几个点更重要。

具体到输入输出,模型接收三分量(E、N、Z)波形片段,默认输入长度是6000个采样点。按100Hz采样率计算,6000个采样点就是60秒。它一次推理同时输出三路逐采样点序列:第一路是事件检测概率,第二路是P波到达概率,第三路是S波到达概率。你在输出序列中看到脉冲式的高概率区间,就对应一个被识别到的震相。

2. 模型原理拆解:CNN+Transformer混合架构在看什么

2.1 输入表示:三分量波形怎么编码

EQTransformer的输入是三分量波形片段,这个“三分量”本身很有讲究。地震波在地表传播时,质点振动同时包含水平分量和垂直分量。P波到达时垂直分量通常更明显,S波到达时水平分量能量增强。模型同时看E、N、Z三个分量,相当于在一个“立体”视角里去识别震相,而不是只盯着单道波形。

窗口长度6000个采样点也不是随便定的。它要能容纳P波和S波之间的时间差。区域地震的S-P到时差通常在几秒到几十秒之间,60秒窗口能覆盖大多数区域地震场景,同时还不会因为窗口过长导致计算负担过大。如果台网以远震为主,S-P到时差可能超过60秒,这时就要考虑增加输入长度,但那就涉及改模型结构了,一般不建议在预训练权重上直接改。

波形不会以原始数值直接喂进模型,会先经过标准化处理。输入数据会被归一化到零均值和单位标准差,基于整个窗口计算。这一步非常关键:同一个台站记录的近震和远震,振幅可以差几个数量级,如果不做归一化,模型很难在不同量级的数据上泛化。实际使用中,我还会对原始数据先做一次带通滤波(比如1~45Hz),这不是模型的硬性要求,但能明显提升低信噪比时的拾取效果。

2.2 CNN与注意力:先局部卷积,再全局建模

模型结构可以大致拆成两段。第一段是卷积模块,使用一维卷积核对三分量波形做局部特征提取。一维卷积可以理解为一个可学习的滤波器在时间轴上滑动,提取短时间内的波形形态特征,比如波峰、波谷、突变段、频率突变点等。这些局部特征对应到地震学里,就是各种震相在波形上的直观表现。

第二段是Transformer模块。Transformer的核心是注意力机制,它让模型在处理某个时间点的特征时,主动关注窗口内其他时间点的特征。比如判断某个时刻是否真的是P波到达,模型可以同时参考后面几十秒内是否存在S波到达的候选——这种长程信息关联,正是传统卷积网络不擅长的地方。卷积的感受野要靠堆层数来扩大,但堆到一定深度后训练困难和信息损耗都很明显,Transformer直接做全局注意力就能绕开这个限制。

论文里使用的是多头注意力结构,同时有自注意力和交叉注意力。自注意力让模型理解波形内部的总体结构,交叉注意力让不同任务分支之间互相交换信息。这也是它能做到检测和拾取两个任务同时输出、且效果不弱的重要原因。从地震学直觉来看,这种结构确实合理:一个可靠的事件检测判断,需要兼顾P波和S波的整体证据;而准确的震相拾取,也依赖于对事件整体特征的认知。

2.3 三个输出分支与训练数据

模型输出的三个分支,每个都逐点输出0到1之间的概率值。事件检测分支给出该时间点处于一个地震事件有效区间的概率;P波分支给出该时间点为P波到达时刻的概率;S波分支同理。训练时使用的损失函数是聚焦损失和掩码损失的组合。聚焦损失在处理正负样本极度不平衡时有明显优势——一个60秒窗口中,真正的震相可能只占零点几秒,绝大多数时间都是噪声或非震相信号,普通交叉熵很快会被大量负样本主导。

训练数据主要来自STEAD数据集,这是目前公开的比较大规模地震波形数据集之一。它汇集了全球多个台网的记录,包含大量标注好的P波、S波到时和事件标签,样本量在百万量级。这是EQTransformer泛化能力相对较好的重要原因。但也要注意,任何全局数据集都有区域偏差,性能评估还是要落到自己的数据上,这一点后面专门说。

3. 从安装到推理:完整跑通EQTransformer

3.1 环境准备与依赖安装

先确认Python版本。EQTransformer依赖TensorFlow 2.x,我目前推荐在Python 3.8~3.10环境下运行。安装有两条常用途径,我分开说。

第一条,直接通过PyPI安装早期版本:

pip install eqtransformer

这个版本对应论文发布时的0.1.0老代码,结构简洁、方便阅读源码。如果你想研究实现细节,这个版本的源码很值得看。

第二条更推荐:使用SeisBench加载。SeisBench是开源的地震学深度学习基准工具包,把多种拾取模型统一封装成类似接口,省去很多重复工作。

pip install seisbench

安装完成后一行命令就能加载EQTransformer预训练模型。SeisBench会自动处理模型下载和缓存,比手动处理模型文件省心很多。如果你平时用VSCode写Python,直接在Jupyter Notebook里跑SeisBench也挺顺手,波形可视化用ObsPy的plot方法就够了。

3.2 加载预训练模型

SeisBench加载EQTransformer的代码非常简单:

from seisbench.models import EQTransformer model = EQTransformer.from_pretrained("original")

from_pretrained会从SeisBench的模型仓库下载权重,首次执行需要联网,权重文件会缓存到本地,后续运行不再重复下载。如果默认源下载不畅,可以手动下载权重文件后通过本地路径加载,这类问题我在第5章集中说。

模型本身不算大,权重文件大概几十MB级别。在CPU上处理一个60秒窗口大约需要一两秒,在GPU上会快一个数量级以上。如果只是离线处理几百个事件波形,CPU完全够用;如果要在线处理连续波流或者整个台网的数据,建议用GPU,并把批大小调大,吞吐量提升很明显。

3.3 处理一段连续波形数据

加载模型后,处理一段mseed格式连续波形的完整流程可以分三步:预处理、推理、后处理。先用ObsPy读取:

import obspy st = obspy.read("station.mseed") st.resample(100) # 统一到100Hz st.detrend("demean") st.taper(max_percentage=0.005)

统一到100Hz很重要。预训练模型默认输入就是100Hz数据,如果台站采样率是50Hz或200Hz,统一重采样可以避免输入分布偏差。detrend和taper主要解决直流漂移和边缘截断效应,属于标准预处理。这里有个隐藏细节:如果原始采样率已经是100Hz,resample不会发生;但如果是50Hz插值到100Hz,则要留意插值伪影对模型的影响,后面踩坑部分会详细讲。

推理部分,SeisBench封装了annotate方法,可以直接对Stream对象进行预测:

annotations = model.annotate(st)

annotate内部完成了切窗、标准化、滑窗预测、概率合并这一串处理,返回一个包含三个通道概率的Stream对象。实际项目中,如果数据量不大、台站数不多,用annotate完全够了;但如果要处理整月、整年的连续数据,建议自己写滑窗与并行逻辑,这个我在第4章展开。

4. 工程化细节:阈值、滑窗和后处理

4.1 输出概率的含义与阈值选择

模型输出的三个0到1概率序列,不能简单地把每个点大于0.5就认定为拾取。要先理解概率序列的形态规律。

事件检测分支通常会持续一段高概率区间,覆盖从P波到S波以及之后的振动区段,它表达的是“这个事件存在”的概率,不是“此刻有震相到达”的概率。P波和S波分支则不同,它们是在到达时刻附近出现的尖峰状高值,宽度一般只有几个到十几个采样点。两类分支的特性完全不一样,所以阈值策略也应该分开。

阈值设定的建议如下表:

分支推荐阈值说明
事件检测0.5~0.6低于0.4会引入大量噪声误报
P波拾取0.3~0.5弱震相到达时刻容易被高阈值漏掉
S波拾取0.3~0.5S波信噪比通常低于P波,阈值不宜过高

在阈值之上,还需要配合一个最小持续采样点数来滤除孤立尖峰。比如要求高概率至少连续持续15个采样点(在100Hz下就是0.15秒),才认定为有效拾取。这个简单规则能滤掉大量单点随机噪声,成本几乎为零。我见过很多人只调阈值不设最小持续时间,误检率一直压不下去,其实就是差了这一步。

4.2 长序列滑窗处理

连续波形通常远远超过60秒,一天24小时的台站数据肯定不能直接塞进模型。要做滑窗切分,窗口长度6000采样点,滑窗步长一般设为窗口长度的一半或更小,保证事件完整落在至少一个窗口内。

步长越大计算越快,但事件跨窗口被截断的风险越大。我常用的配置是窗口60秒、步长30秒,这样任何一个持续时间不超过30秒的事件都能完整落入一个窗口。预测完后,把重叠窗口的概率取最大值或平均值,再拼回完整的概率曲线。取最大值更保守,不容易漏检;取平均值更平滑,不容易误检。对地震事件检测来说,我更推荐取最大值。

简单的滑窗预测核心代码可以这样写:

# 滑窗参数 window_len = 6000 # 60秒 @ 100Hz step_len = 3000 # 30秒步长 for start in range(0, total_len - window_len + 1, step_len): window = data[start:start + window_len] # 标准化后进入模型 e_prob, p_prob, s_prob = model.predict(window) # 重叠区域概率按最大值合并

这个逻辑写清楚后,再考虑并行:不同窗口之间没有依赖关系,可以用Python的多进程池把窗口分发到多个CPU核,或者用GPU批量推理。批量推理时注意把维度对齐,三维数组形状一般是(batch, 6000, 3)。批量大小设成8或16对多数GPU都很稳,超过32容易显存溢出。

4.3 拾取结果去重和校验

滑窗预测会带来一个必然问题:同一个地震事件可能被相邻两个窗口都检测到,并且各自给出一个拾取时间,二者可能相差几十个采样点。这类重复必须做合并去重。

我处理重复拾取时用的规则是:两个拾取时间差小于2秒的合并为一次拾取,保留概率更大那次的到时。这个规则在处理密集地震序列时特别重要——如果不做合并,一个地震可能被输出成三四个假事件,后续定位会一团糟。

除此之外,还要利用地震学常识做合理性校验:

  • P波到达时间必须早于S波到达时间,若某个S波拾取早于P波,大概率是模型错误,建议丢弃。
  • 根据台站距震中的粗略距离,S-P时差有一个合理范围。如果S-P时差大得离谱,打上可疑标记,不直接作为正式结果。
  • 单个台站单独出现的事件拾取,可靠性低,最好结合多台站关联后再确认。

这些规则看起来很基础,但它们是自动化流程能稳定跑下去的关键。模型只是给出概率,能不能变成台网产品里可靠的一个个事件,全看后处理写得好不好。

5. 实测效果、常见坑位与微调建议

5.1 全局模型在区域台网的实测表现

EQTransformer的预训练权重来自STEAD全球数据,泛化能力确实不错,但在特定区域台网上的表现和论文报告的指标会有差距。我实测下来的感受是:在宽频带台站、信噪比较高的数据上,它几乎没有漏检;但在火山震动、冰震、采矿爆破这类非构造地震信号上,会出现一定误拾取,因为这些信号形态和构造地震的标注样本有分布差异。

如果要在某个特定区域长期使用,强烈建议做一遍区域数据评估:标注一小批本地事件,统计在几组不同阈值下的精确率和召回率,画出PR曲线,再选定生产阈值。这个过程不复杂,但对最终效果提升非常明显。反过来,如果直接拿默认阈值用,可能在你的数据上出现三天两头误报,然后得出结论“AI不行”——这其实是流程工程问题,不是模型问题。

5.2 几个容易被忽略的坑

先说采样率。这不只是重采样的问题,还要注意重采样引入的波形畸变。如果原始采样率是200Hz或400Hz,直接降采样到100Hz一般没问题;但如果是低于100Hz的短周期台记录,重采样实际是插值,插值产生的伪波形有可能被模型误判。遇到这种台站,我宁可把数据限制在有效频带内处理,或者用更保守的阈值。

然后是TensorFlow环境兼容性。EQTransformer依赖TensorFlow 2.x和Keras,TensorFlow大版本升级后,有可能会让旧权重加载失败,原因通常是Keras的层结构存储格式变了。遇到这类问题,我通常的做法是在conda里单独建一个环境,固定TensorFlow版本专门跑EQTransformer,不让它跟项目其他依赖一起升级。这个办法最省心,可以解决九成以上的环境冲突。

第三个容易踩的坑是在M系列Mac上跑TensorFlow。虽然TensorFlow已经支持Apple Silicon,但一些老代码在GPU后端起会有兼容性问题,简单处理方式是强制只用CPU:

import os os.environ["CUDA_VISIBLE_DEVICES"] = "-1"

对测试和教学场景,CPU已经足够,不用纠结这一点性能损失。

5.3 数据量允许时怎么做微调

如果你的台网数据有较完整的震相标注,可以对模型做微调,效果通常比直接用全局模型提升明显。微调不需要从头训练,只需要在预训练权重基础上用本地数据继续训练少量epoch,一般10~20个代次甚至更少就够了。

SeisBench对迁移学习支持得不错。你可以把预训练模型作为初始化权重,冻结前几层特征提取层,只微调后面的Transformer层和输出层。如果本地数据只有几千个样本,建议冻结更多层防止过拟合;如果数据量有数万个样本,可以放开更多层参与训练。

需要注意一个很容易犯的错误:划分训练集和验证集时按事件分,不要按台站分。一个地震事件会在多个台站同时记录到,如果把同一事件在部分台站的记录放在训练集、另一部分放在验证集,评估指标会虚高——模型其实已经见过这个事件的特征了。我见过不少人在这个细节上栽跟头,导致所谓“微调后精度极高”的结果上不了生产。

最后分享一个我个人的使用习惯:不要只把EQTransformer当成一个独立的拾取工具,它输出的概率序列本身就是很有价值的信息。比如在没有触发事件的时间段里,观察事件检测概率是否有规律抬升,有时候能提前发现一些被STA/LTA漏掉的微弱连续信号。把这些概率序列记录下来,作为台网数据流的额外监控通道,说不定能发现传统处理流程发现不了的东西。这算是用AI做地震监测时一个值得留意的附加价值。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询