文章目录
一、前言
放假前一周主要完成了DDNet论文阅读,并尝试思考新的点子修改网络架构。
这段时间主要学习了数学表达式的简单书写(包括常用符号、集合的表示与运算、向量与矩阵、二元关系等,但是还有一大部分数学表达式没有学习完成,并且对一些概念掌握较差,如范数等)、深度学习地震数据去噪、DDNet架构学习。
二、DDNet架构学习
DDNet工程文件基于模块化的设计思路,主要包含data、func、models、net四个文件夹,以及model_test.py、model_test.py等文件,如图1所示。
- data文件夹:存放实验数据;
- func文件夹:包括datasets_reader.py(读取数据集)与utils.py(存放一些方法,如绘图方法、canny边缘检测算法、添加高斯噪声等);
- models文件夹:存放训练好的网络模型(pkl文件);
- net文件夹:存放网络结构;
2.1 数据预处理
数据预处理的操作主要在func文件夹中完成,该文件夹下包括datasets_reader.py(读取数据集)与utils.py(存放一些数据预处理方法),很大一部分方法在之前的OpenFWI与FCNVMB的介绍中提及过了,下面介绍一下canny边缘检测算法;
# 使用Canny边缘检测算法从输入的图像(通常是一个速度模型)中提取轮廓特征
def extract_contours(para_image):
'''
Use Canny to extract contour features
:param image: Velocity model (numpy) 速度模型图像(numpy数组)
:return: Binary contour structure of the velocity model (numpy)
'''
image = para_image
# OpenCV的normalize函数对输入的图像进行归一化,将图像的像素值范围调整为[0, 1]。
# NORM_MINMAX表示使用图像的最小和最大值进行归一化。
# dtype=cv2.CV_32F指定了输出图像的数据类型为32位浮点数。
norm_image = cv2.normalize(image, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
# 将归一化后的在[0, 1]之间的图像像素值范围转换为0 - 255的范围(这是Canny边缘检测算法通常需要的)。
# 将每个像素值乘以255,并将数据类型转换为8位无符号整数(np.uint8)。
norm_image_to_255 = norm_image * 255
norm_image_to_255 = norm_image_to_255.astype(np.uint8)
# 使用OpenCV的Canny函数对归一化并转换后的图像进行边缘检测。
# Canny函数接受三个参数:输入图像、低阈值和高阈值。这里,低阈值设置为10,高阈值设置为15。
canny = cv2.Canny(norm_image_to_255, 10, 15)
# 将Canny输出转换为布尔值
# 使用clip函数将Canny输出的像素值限制在[0, 1]范围内,并返回一个布尔值数组。在这个数组中,值为1的像素表示边缘,值为0的像素表示非边缘。
bool_canny = np.clip(canny, 0, 1)
# 函数返回处理后的布尔值数组,代表输入图像的速度模型的轮廓特征。
return bool_canny
2.2 网络模型构建
DDNet的架构如下图所示,其基本思想来自Unet,具有明显的左右高度对称的编解码器结构,整体结构呈Y形,如图2所示。
不同的解码器将U-Net变成一个多任务学习环境,子任务解码器还可以为主任务或后续任务提供参数上下文。
- 左侧的编码器组件负责地震数据的压缩过程,将29炮的地震观测记录压缩成1024维的抽象结构化信息。
- 右边的两个解码器使用不同的想法来解释高维抽象信息。第一解码器的目标是常规的速度模型,是预测的主要解码器,关注速度值的准确拟合。然后,Canny轮廓提取后的二进制速度模型进一步用作第二解码器的拟合目标。该解码器将用作训练轮廓信息的辅助解码器。轮廓解码器以确保分割预测的平滑性。
DD-Net 70在网络前面扩展了一个预网络降维器。因为输入图像的时间维度(图像的高)相比于宽度是很高的,所以需要使用一些比较窄的卷积将时间域压缩来与宽度差不多的程度,先经历宽度不变,高度被压缩的过程。引入非方形卷积来压缩时间维度(图像高度),确保地震数据被约束到与速度模型相同的大小。降维器将使用多个卷积来协调,以防止由一个卷积压缩引起的信息丢失。
之前提到可以使用Tensorboard查看网络的架构,下面介绍另一种方法查看网络模型的详细信息:
- torchsummary 是一个用于 PyTorch 的库,可以为给定的神经网络模型生成一个简洁的摘要,展示模型的每一层的详细信息,包括层类型、输出形状、参数数量等。summary 函数会打印出模型的每一层及其详细信息。
from torchsummary import summary # 从 torchsummary 库中导入了 summary 函数
# model:想要获取摘要的 PyTorch 神经网络模型
# input_size:模型预期接收的数据大小
summary(model, input_size=[(7, 1000, 70)])
网络的详细介绍如下:
- 深蓝色箭头:高度为3、宽度为1的卷积核、高度为2、宽度为1的步长、高度为1、宽度为1的填充;
- 棕色箭头:调整张量(特征图)的尺寸;
- 红色箭头:3x3的卷积核、BN批量归一化、ReLU激活函数;
- 紫色箭头:2x2的最大池化操作;
- 黄色箭头:2x2的反卷积操作;
- 浅蓝色箭头:1x1的卷积操作;
三、基于深度学习地震数据去噪处理
本节知识主要包含以下几个板块:深度学习在地震数据去噪中的研究方向、深度学习地震数据去噪流程、基于DnCNN的地震数据去噪实验,参考如下:
- 学习参考(B站夜剑听雨博主):https://www.bilibili.com/video/BV1734y1a77W/?spm_id_from=333.788&vd_source=af74aafa4645f30fd97c16896b278128
- 数据和代码(阿里云):https://www.aliyundrive.com/s/ApwRi7zJtBy
3.1 深度学习在地震数据去噪中的研究方向
卷积神经网络(CNN)具有自动学习高度复杂的非线性特征的能力,将其应用与叠前地震数据随机噪声处理的压制中,通过对叠前地震数据中随机噪声特征的自动学习,实现自动且高效的随机噪声分离。(李海山等,2020)
面波作为很强的干扰波出现在地震勘探中,大大降低了地震记录的分辨率和信噪比。深度学习作为一种数据驱动类方法,能够从大量数据样本中学习得到有效信号与噪声的区别,自适应建立深度神经网络来压制噪声。
注意:信号与噪声是一个相对的概念。使用反射波的时候面波是噪声,在一些使用面波的成像技术中面波是需要保留的信号。
大多数传统三维地震数据重建方法对噪声较为敏感,且不能应对规则缺失的数据。相比于传统的方法,基于深度学习的方法可以克服传统方法对数据先验信息的要求,使得在对地震数据的去噪和重建过程中只需要考虑数据的分布,大大降低了重建过程中的复杂度(王峰, 2020)。
3.2 深度学习地震数据去噪流程
深度学习技术存在较多的不可解释性,更强调工程实用性。因此需要大量实践经验,数据科学家更像是工程师,每个环节的处理经验对训练效果具有显著影响。
- 准备数据:在深度学习中,数据集通常被划分为训练集、验证集和测试集三个部分;
1.训练集: 用于训练模型的数据集,即模型通过学习训练集中的数据来更新其参数,从而获得更好的性能。训练集相当于教材或例题,通过训练集,模型可以学习到数据中的规律和特征;
2.验证集: 用于在模型训练过程中验证模型性能的数据集。验证集相当于模拟考试,用于调整模型的参数和超参数,以及选择最佳的模型。验证集的作用是帮助我们在多个可能的模型中选出表现最好的那个;
3.测试集: 用于评估模型最终性能的数据集,通常是在模型训练完成后,使用测试集来评估模型的性能。测试集相当于高考,其特点是数据不参与训练,用于检验模型的泛化能力,即在未知数据集下反映出的性能。测试集的特点是数据不参与训练,用于检验模型在未见过的数据上的表现能力; - 搭建网络:例如DnCNN(用于去噪的卷积神经网络)、Unet、GAN等;
- 训练网络:获得在训练集、测试集中表现最好,也就是误差最小的模型;
- 最优模型:某次实验的最佳模型保存本地,必要的时候可以继续训练不断优化;
超参数:学习率 η \eta η、正则化参数 λ \lambda λ、神经网络的层数 L L L、每一个隐藏层中神经元的个数 j j j、学习的回合数 e p o c h epoch epoch、小批量数据 m i n i b a t c h minibatch minibatch 的大小、输出神经元的编码方式、代价函数的选择、权重初始化方法、神经元激活函数的种类(目前来说影响并不是这么大)、参与训练模型数据的规模等。
3.2.1 数据集准备
正演地震记录:通过正演软件得到炮集记录以及结合部分实际的地震记录。一些公开炮集记录数据包含地震道道头信息,因此首先需要剥离道头信息,剥离之后再对其进行不同辅助噪声的增加,增加噪声的多样性。
地震数据切片:对无噪声数据和含噪声数据采用相同的方式,在炮集记录的高、宽方向滑动一定的步长, 该种方式切片可以是数据具有一定的相似度,从而得到同一个位置的特征和标签,增加了数据的丰富度。
- 类似的数据集可点击链接:https://wiki.seg.org/wiki/Open_data;
3.2.2 模型构建
假设无噪声数据为
x
x
x,每个像素都有一个噪声偏量
v
v
v,得到的含噪数据(观测数据)为
y
y
y,即:
y
=
x
+
v
(1)
y =x + v \tag{1}
y=x+v(1)
去噪任务的目的,就是根据噪声图像
y
=
x
+
v
y =x + v
y=x+v会付出干净图像的过程。
DnCNN在VGG的基础上进行修改,网络结构是(卷积、BN、 ReLU) 级联的结构,模型内部并不像ResNet一样存在跳跃连接,而是在网络的输出使用残差学习。残差学习策略是指在网络中输入含有噪声的观测图片,通过网络的隐藏层隐式地移除干净图片,以噪声数据作为输出(于四伟等, 2021)。于四伟老师提出的网络结构如图8所示。
该模型的输入为一个40x40大小的信号,第1层卷积层(Convolution)的卷积核大小设置为 3×3,卷积的步长(Strides)设置为 1,卷积核的数量为 64,激活函数采用ReLu。第2~16层在每次卷积方式同第一层一样,增加了批归一化(Batchnormalization),对数据中心做偏移处理,用于加快网络的收敛速度使特征图的大小和输入相等,避免因为卷积而损失特征,然后再用激活函数ReLu。最后一层卷积层的卷积核大小也设置为 3*3,卷积核的数量为 1(合并通道数),此时的结果是信号,最后用输入数据减去此时结果,就得到了噪声(残差学习) 。
根据噪声图像
y
=
x
+
v
y=x+v
y=x+v,残差训练可表示三维根据噪声图像
R
(
y
)
=
v
′
≈
v
R(y) = v^{'} \approx v
R(y)=v′≈v
- 损失函数:
L ( θ ) = 1 2 M ∑ i = 1 M ∥ R ( y i ; θ ) − ( y i − x i ) ∥ F 2 (2) L(\theta) = \frac{1}{2M} \sum_{i=1}^{M} \Vert R\left(y_{i};\theta\right) - \left(y_{i}-x_{i} \right) \Vert_{F}^{2} \tag{2} L(θ)=2M1i=1∑M∥R(yi;θ)−(yi−xi)∥F2(2)
源码为:L(\theta) = \frac{1}{2M} \sum_{i=1}^{M} \Vert R\left(y_{i};\theta\right) - \left(y_{i}-x_{i} \right) \Vert_{F}^{2} \tag{2};
其中, θ \theta θ 是可训练的参数。
3.2.3 训练网络
- 搭建网络:利用Pytorch或TensorFlow搭建深度学习框架;
- 训练网络:训练过程中查看训练集、验证集损失函数的最小值,以及测试集在评估指标上的最大值;
S N R = 10 log 10 ( ∑ i = 1 N ∑ j = 1 M ( X ( i , j ) − x ˉ ) 2 ∑ i = 1 N ∑ j = 1 M ( Y ( i , j ) − X ( i , j ) ) 2 ) (3) SNR = 10 \log_{10} \left( \frac{\sum_{i=1}^{N} \sum_{j=1}^{M} \left( X \left( i,j \right) - \bar{x} \right)^{2}}{\sum_{i=1}^{N} \sum_{j=1}^{M} \left( Y \left( i,j \right) - X \left( i,j \right) \right)^{2}} \right) \tag{3} SNR=10log10(∑i=1N∑j=1M(Y(i,j)−X(i,j))2∑i=1N∑j=1M(X(i,j)−xˉ)2)(3)
3.3 基于DnCNN的地震数据去噪实验
基于模块化的设计思路,将深度学习研究变成易操作的流水线作业。代码模块化的意义在于:可以让后面的研究可以专注于修改神经网络模型(调结构或换网络),不用花费大量时间在其他的基础工作上,方便后期的研究和代码的维护。
本工程一共有data、model、utils三个文件夹:
- data文件夹:实验数据;sgy_data中synthetic.sgy是一个30炮干净的地震记录,运行utils/sgy-nyp.py这个代码,可以将这个sgy文件分割成单炮的地震记录,并且去除道头,只保留了地震道信息,同时对30炮地震记录加入随机噪声;无噪声数据存储在clean文件夹中,含噪声数据存储在noise文件夹中。然后运行utils/GetPatches.py代码,将含噪声和干净的炮集记录,切分为一些列64*64大小的patches,并且使用了数据增强;含噪声数据patches作为特征放在feature文件中,干净数据patches作为标签放在label文件中,这样就完成了数据集的制作。
- model文件夹:网络模型、网络预测、网络信念以及最佳网络模型(pth文件);dncnn是网络架构文件,这里的DNCNN输出的是残差,运model/train.py文件,通过utils/dataset.py自定义加载数据集,并且按照8:1:1划分数据集,每训练一次就会验证并测试一次。训练和验证用的loss会保存到loss_sets.txt文件中,测试用的评估指标是信噪比,结果将保存到snr_sets.txt文件中,训练时间.txt记录的是训练用的时间;
- utils文件夹:数据集切片程序、数据集加载、数据绘图、信号处理工具包;utils/SignalProcess中有信噪比,傅里叶分析,f-k分析,各种滤波方法,用于验证网络结果好坏;
四、小结
4.1 存在的问题及解决
在这段时间中,遗忘了之前的一些概念,有点模模糊糊。
1.叠前地震数据 如何理解?
叠前地震数据是指在地震数据处理中,对常规水平叠加之前的地震数据进行偏移处理所得到的数据。这些数据包含了丰富的地震信息,且具有较高的精度,因此在解决地层倾角大或者构造复杂地区的问题时非常实用。然而,叠前数据处理过程相对复杂,所需时间也较长。
叠前地震信号是指多个一维地震信号按照入射角或者方位角排列形成的高维数据集合,也称为叠前道集。与之相对,叠后地震数据是通过将叠前地震信号以一定方法叠加起来形成的,这种方式增加了地震信号的信噪比,但可能会降低分辨率,并丢失叠前信号中的道间变化特征。
2. 数据先验信息怎么理解?
地震数据的先验信息是指在获得地震样本或模型之前,已经存在的经验、可参考的历史资料或其他相关信息。这些信息可以提供关于地下介质结构、性质和地震波传播规律的初步了解。
在地震数据处理和解释中,先验信息具有重要的作用。首先,它可以帮助建立合理的地下模型,从而更准确地预测地震波的传播路径和反射特征。
其次,先验信息还可以用来约束地震数据的处理过程,减少多解性和不确定性。例如,在地震反演中,可以利用先验信息来设置合理的搜索范围或约束条件,从而避免得到不合理的反演结果。
此外,先验信息还可以用来评估地震数据的可靠性和质量。通过与历史资料或其他可靠数据的对比,可以判断当前地震数据的准确性和可信度,从而为后续的数据处理和解释提供更为可靠的依据。
3. in-line和cross-line怎么理解?
三维资料处理后,可以得到一个完整的、能反映地质体时空变化的三维数据体。由该数据体可以验出全P的水平切片和垂直剖面图供人员解释。使用三维切片图可分为:垂直剖面和水平切片。
- 拉剖面是沿垂直方向的剖面,一般垂直于构造的剖面为主测线(EFGH剖面)通常用Inline或Subline表示,为便于手工解释,显示的测线间隔一般为50m;
- 与主测线垂直的为联络测线(MNOP剖面)通常用Crossline表示,显示的测线间隔可根据需要选择。一般为20、50或100m,为确定地质层位,实现地震与地质直接对比而连接部分钻井的测张.称可并井测线通常用select profile表示。
- 主线一般情况下垂直于构造的走向,联络线沿着构造的走向。主测线上看构造的形态是最清楚的。
4.数据增强包括哪些操作?为什么要进行数据增强?
数据增强(Data Augmentation)是一种在机器学习和深度学习中常用的技术,主要目的是在不实质性增加数据的情况下,让有限的数据产生等价于更多数据的价值。通常通过在已有数据的基础上,应用一系列随机变换来生成新的、但又保持标签不变的样本,从而增加数据集的多样性和规模,提高模型的泛化能力。
数据增强的主要方式包括旋转、平移、缩放、裁剪、翻转、颜色变换等,这些变换可以单独或组合使用。例如,对于图像数据,可以通过随机裁剪、旋转、调整亮度等操作来生成新的样本;对于文本数据,可以通过同义词替换、随机插入、随机删除等方式来增加数据的多样性。
数据增强是一种低成本和有效的方法,可以显著提高机器学习模型的性能和准确性,特别是在训练数据有限的情况下。然而,需要注意的是,对于一些复杂的任务和数据分布,单纯的数据增强可能无法取得理想的效果。因此,在使用数据增强时,需要根据具体任务和数据特点来选择合适的变换方式和参数设置。
5.如何提高深度学习代码能力?
- 实现了巨多的深度学习模型:https://github.com/lucidrains
- 一行行进行代码模型解读:https://nn.labml.ai/
4.2 下周安排
1.完善开题报告书,准备开题答辩
2.思考:先进行数据增强,再反演会不会效果好一些呢?
3.找到了一些即插即用的模块,但是在训练过程中,5000个数据如何判断他们效果的好坏呢?会不会数据量增大之后,效果反而降低?