2024年2月5日-2月11日周报

1. 本周计划

阅读论文《Data-Driven Seismic Waveform Inversion: A Study on the Robustness and Generalization》并实现论文代码,学习代码套路

2. 完成情况

2.1 论文摘要

Full-waveform inversion is an important and widely used method to reconstruct subsurface velocity images. Waveform inversion is a typical nonlinear and ill-posed inverse problem. Existing physics-driven computational methods for solving waveform inversion suffer from the cycle-skipping and local-minima issues, and do not mention that solving waveform inversion is computationally expensive. In recent years, data-driven methods become a promising way to solve the waveform-inversion problem. However, most deep-learning frameworks suffer from the generalization and overfitting issue. In this article, we developed a real-time data-driven technique and we call it VelocityGAN, to reconstruct accurately the subsurface velocities. Our VelocityGAN is built on a generative adversarial network (GAN) and trained end to end to learn a mapping function from the raw seismic waveform data to the velocity image. Different from other encoder–decoder-based data-driven seismic waveform-inversion approaches, our VelocityGAN learns regularization from data and further imposes the regularization to the generator so that inversion accuracy is improved. We further develop a transfer-learning strategy based on VelocityGAN to alleviate the generalization issue. A series of experiments is conducted on the synthetic seismic reflection data to evaluate the effectiveness, efficiency, and generalization of VelocityGAN. We not only compare it with the existing physics-driven approaches and datadriven frameworks but also conduct several transfer-learning experiments. The experimental results show that VelocityGAN achieves the state-of-the-art performance among the baselines and can improve the generalization results to some extent.

在摘要部分,论文作者提出了解决FWI的物理驱动计算方法主要面临的问题

  • 周期跳跃问题
  • 局部最小值问题
  • 计算成本很高

论文中提出了一种实时的数据驱动技术VelocityGAN,利用生成对抗网络(GAN)从原始地震波形数据到速度图像的映射函数,论文主要的创新点:

  • 实时数据驱动技术
  • 从数据中学习正则化,并将正则化施加给生成器,
  • 基于VelocityGAN的迁移学习策略来缓解泛化问题

2.2 网络结构

VelocityGan 由两部分组成:生成器和判别器;其中生成器是一种编码器-解码器结构,将原始地震数据映射到速度图像;鉴别器是一个卷积神经网络(CNN),对真实或假的速度图像进行分类.如下是网络结构图:
在这里插入图片描述

  • 生成器Generator
    在论文中生成器的结构如下表TABLE I所示,这个结构其实和InversionNet的网络结构很相似
    在这里插入图片描述
    在这里插入图片描述
    但是在最新的代码中,输入的图像为 5 ∗ 1000 ∗ 70 5*1000*70 5100070,输出为 1 ∗ 70 ∗ 70 1*70*70 17070 为啥要改变尺寸大小? 为啥要改变尺寸大小? 为啥要改变尺寸大小?

  • 判别器Generator

Discriminator: Similar to Radford et al. [35], we adapt our discriminator from a CNN architecture. In particular, it consists of five convolution blocks, a global average pooling layer, and fully connected layers. Each convolutional block involves a combination of Convolutional, BatchNormalization, LeakyReLU, and MaxPooling layers. We apply the “PatchGAN” classifier [18] in the discriminator to capture local style statistics. We set the patch size as 4 and calculate the mean loss value of all patches in an image

在论文中,判别器主要由五个卷积块、一个全局平均池化层和全连接层组成,还应用了PatchGAN分类器,而在现在的代码中发现已经取消了PathGan.也没由全连接层和平均池化层了。 这貌似就和论文中的出入较大。(patchGan: 主要用在判别器上,比如的GAN网络输入为一张图像输出一个单一的判别结果true or false, 而patchGan使用了局部感受野,转为对图像局部区域进行判别,若输入一张图像,输出就是一个N*N的矩阵。)
在这里插入图片描述

2.3 损失函数

  • 生成器损失函数
    def criterion_g(pred, gt, model_d=None): # 预测值和真实值?
        loss_g1v = l1loss(pred, gt)
        loss_g2v = l2loss(pred, gt)
        loss = args.lambda_g1v * loss_g1v + args.lambda_g2v * loss_g2v
        if model_d is not None:
            loss_adv = -torch.mean(model_d(pred)) 
            loss += args.lambda_adv * loss_adv
        return loss, loss_g1v, loss_g2v

生成器损失函数公式:
在这里插入图片描述

  • L1loss函数是MAE(MAE loss performs better on revealing the geological interfaces); L2loss函数是MSE(MSE loss is good at capturing the geological faults)

  • loss 总损失值是根据权重系数计算得到。(平衡损失项的重要性)

  • loss_adv:在生成器损失函数中,若提供了判别器,则需要计算对抗损失项loss_adv,首先需要将预测值输入到判别器模型中得到判别结果。再将判别结果取负均值。 这样的目的是最大化生成器生成图像被判别器判别为真的概率。即负均值越接近0,则说明生成的图像被判别为真实图像的概率越高,从而生成器的性能越好。并最后将这个损失函数加入到总损失函数 中。
    最后返回生成器相关的损失函数

  • 判别器损失函数

class Wasserstein_GP(nn.Module):
    def __init__(self, device, lambda_gp):
        super(Wasserstein_GP, self).__init__()
        self.device = device
        self.lambda_gp = lambda_gp

    def forward(self, real, fake, model):
        gradient_penalty = self.compute_gradient_penalty(model, real, fake)
        loss_real = torch.mean(model(real))
        loss_fake = torch.mean(model(fake))
        loss = -loss_real + loss_fake + gradient_penalty * self.lambda_gp
        return loss, loss_real-loss_fake, gradient_penalty

    def compute_gradient_penalty(self, model, real_samples, fake_samples):
        alpha = torch.rand(real_samples.size(0), 1, 1, 1, device=self.device) # 生成一个张量值,值是在 [0, 1) 范围内随机
        interpolates = (alpha * real_samples + ((1 - alpha) * fake_samples)).requires_grad_(True) # 线性插值生成样本并跟踪这个张量的梯度
        d_interpolates = model(interpolates) #获取插值样本在生成器上的,以便计算梯度惩罚
        gradients = autograd.grad(
            outputs=d_interpolates,
            inputs=interpolates,
            grad_outputs=torch.ones(real_samples.size(0), d_interpolates.size(1)).to(self.device),
            create_graph=True,
            retain_graph=True,
            only_inputs=True,
        )[0]
        gradients = gradients.view(gradients.size(0), -1)
        gradient_penalty = ((gradients.norm(2, dim=1) - 1) ** 2).mean()
        return gradient_penalty

判别器的损失函数在论文中描述到

A Wasserstein GAN (WGAN) with gradient penalty [14] has been proven to be robust of a wide variety of generator architectures. Considering the modified structure in our generator, we use Wasserstein loss with a gradient penalty to distinguish the real and generated velocity maps

  • WGAN(Wasserstein GAN
    wasserstein距离:度量两个概率分布之间差异的距离度量。参考文章
  • 判别器损失函数
    在这里插入图片描述
    注:在GAN训练中,若把判别器训练得太好反而在实验中生成器会完全学不动。

P g P_g Pg生成器速度模型预测, P r P_r Pr真实速度模型预测, P x ^ P_{\hat{x}} Px^ P g P_g Pg P r P_r Pr之间的随机样本, E D ( ⋅ ) ED(·) ED()代表判别器输出的期望值

  • loss_real 真实样本在判别器上的损失的平均值
  • loss_fake 生成样本在判别器上的损失的平均值
  • gradient_penalty 梯度惩罚项
    最后计判别器的损失函数

2.4 优化器

  • Adam优化器
    Adam算法是自适应学习率的优化算法,尤其在Transforms架构出现后,调整学习率是很困难的,使用SGD类似算法可能效果没有那么有用,采用Adam算法,结合了一阶矩阵动量和二阶矩阵动量来调整学习率。
    input : γ  (lr) , β 1 , β 2  (betas) , θ 0  (params) , f ( θ )  (objective) λ  (weight decay) ,   amsgrad ,   maximize initialize : m 0 ← 0  ( first moment) , v 0 ← 0  (second moment) ,   v 0 ^ m a x ← 0 for   t = 1   to   …   do if   maximize : g t ← − ∇ θ f t ( θ t − 1 ) else g t ← ∇ θ f t ( θ t − 1 ) if   λ ≠ 0 g t ← g t + λ θ t − 1 m t ← β 1 m t − 1 + ( 1 − β 1 ) g t v t ← β 2 v t − 1 + ( 1 − β 2 ) g t 2 m t ^ ← m t / ( 1 − β 1 t ) v t ^ ← v t / ( 1 − β 2 t ) if   a m s g r a d v t ^ m a x ← m a x ( v t ^ m a x , v t ^ ) θ t ← θ t − 1 − γ m t ^ / ( v t ^ m a x + ϵ ) else θ t ← θ t − 1 − γ m t ^ / ( v t ^ + ϵ ) r e t u r n   θ t \begin{aligned} &\rule{110mm}{0.4pt} \\ &\textbf{input} : \gamma \text{ (lr)}, \beta_1, \beta_2 \text{ (betas)},\theta_0 \text{ (params)},f(\theta) \text{ (objective)} \\ &\hspace{13mm} \lambda \text{ (weight decay)}, \: \textit{amsgrad}, \:\textit{maximize} \\ &\textbf{initialize} : m_0 \leftarrow 0 \text{ ( first moment)}, v_0\leftarrow 0 \text{ (second moment)},\: \widehat{v_0}^{max}\leftarrow 0\\[-1.ex] &\rule{110mm}{0.4pt} \\ &\textbf{for} \: t=1 \: \textbf{to} \: \ldots \: \textbf{do} \\ &\hspace{5mm}\textbf{if} \: \textit{maximize}: \\ &\hspace{10mm}g_t \leftarrow -\nabla_{\theta} f_t (\theta_{t-1}) \\ &\hspace{5mm}\textbf{else} \\ &\hspace{10mm}g_t \leftarrow \nabla_{\theta} f_t (\theta_{t-1}) \\ &\hspace{5mm}\textbf{if} \: \lambda \neq 0 \\ &\hspace{10mm} g_t \leftarrow g_t + \lambda \theta_{t-1} \\ &\hspace{5mm}m_t \leftarrow \beta_1 m_{t-1} + (1 - \beta_1) g_t \\ &\hspace{5mm}v_t \leftarrow \beta_2 v_{t-1} + (1-\beta_2) g^2_t \\ &\hspace{5mm}\widehat{m_t} \leftarrow m_t/\big(1-\beta_1^t \big) \\ &\hspace{5mm}\widehat{v_t} \leftarrow v_t/\big(1-\beta_2^t \big) \\ &\hspace{5mm}\textbf{if} \: amsgrad \\ &\hspace{10mm}\widehat{v_t}^{max} \leftarrow \mathrm{max}(\widehat{v_t}^{max}, \widehat{v_t}) \\ &\hspace{10mm}\theta_t \leftarrow \theta_{t-1} - \gamma \widehat{m_t}/ \big(\sqrt{\widehat{v_t}^{max}} + \epsilon \big) \\ &\hspace{5mm}\textbf{else} \\ &\hspace{10mm}\theta_t \leftarrow \theta_{t-1} - \gamma \widehat{m_t}/ \big(\sqrt{\widehat{v_t}} + \epsilon \big) \\ &\rule{110mm}{0.4pt} \\[-1.ex] &\bf{return} \: \theta_t \\[-1.ex] &\rule{110mm}{0.4pt} \\[-1.ex] \end{aligned} input:γ (lr),β1,β2 (betas),θ0 (params),f(θ) (objective)λ (weight decay),amsgrad,maximizeinitialize:m00 ( first moment),v00 (second moment),v0 max0fort=1todoifmaximize:gtθft(θt1)elsegtθft(θt1)ifλ=0gtgt+λθt1mtβ1mt1+(1β1)gtvtβ2vt1+(1β2)gt2mt mt/(1β1t)vt vt/(1β2t)ifamsgradvt maxmax(vt max,vt )θtθt1γmt /(vt max +ϵ)elseθtθt1γmt /(vt +ϵ)returnθt
    γ \gamma γ:学习率; β 1 , β 2 \beta_1, \beta_2 β1,β2 第一个,第二个动量的指数衰减率; θ 0 \theta_0 θ0:模型参数的初始值; λ \lambda λ 权重衰减参数(控制参数更新的正则化项); maximize \textit{maximize} maximize:是否为最大化问题
    初始化一阶动量 m 0 m_0 m0和二阶动量 v 0 v_0 v0为0, 在每次迭代中,计算梯度 g t g_t gt,若 λ \lambda λ 不为0将其添加到梯度中,更新一阶动量 m t m_t mt和二阶动量 v t v_t vt,再对一阶动量 m t m_t mt和二阶动量 v t v_t vt进行偏差矫正。(为什么要进行偏差矫正? 因为在初始化时一阶动量 m 0 m_0 m0和二阶动量 v 0 v_0 v0为0,会导致一阶动量和二阶动量的估计存在较大的偏差,影响到优化算法的收敛速度和稳定性,故加入了偏差矫正项 1 − β 1 t 1-\beta_{1}^{t} 1β1t 1 − β 2 t 1-\beta_{2}^{t} 1β2t, 随着迭代次数增加,偏差矫正项逐渐减小)
  • AdamW优化器
    AdamW算法相比于Adam算法,引入更加稳定的权重衰减方式,AdamW 在计算梯度时会将权重衰减项直接加到梯度上,而不是像 Adam 算法那样在参数更新时再单独处理。在VelocityGan中,优化器采用了AdamW优化器进行参数优化
    input : γ (lr) ,   β 1 , β 2 (betas) ,   θ 0 (params) ,   f ( θ ) (objective) ,   ϵ  (epsilon) λ (weight decay) ,   amsgrad ,   maximize initialize : m 0 ← 0  (first moment) , v 0 ← 0  ( second moment) ,   v 0 ^ m a x ← 0 for   t = 1   to   …   do if   maximize : g t ← − ∇ θ f t ( θ t − 1 ) else g t ← ∇ θ f t ( θ t − 1 ) θ t ← θ t − 1 − γ λ θ t − 1 m t ← β 1 m t − 1 + ( 1 − β 1 ) g t v t ← β 2 v t − 1 + ( 1 − β 2 ) g t 2 m t ^ ← m t / ( 1 − β 1 t ) v t ^ ← v t / ( 1 − β 2 t ) if   a m s g r a d v t ^ m a x ← m a x ( v t ^ m a x , v t ^ ) θ t ← θ t − γ m t ^ / ( v t ^ m a x + ϵ ) else θ t ← θ t − γ m t ^ / ( v t ^ + ϵ ) r e t u r n   θ t \begin{aligned} &\rule{110mm}{0.4pt} \\ &\textbf{input} : \gamma \text{(lr)}, \: \beta_1, \beta_2 \text{(betas)}, \: \theta_0 \text{(params)}, \: f(\theta) \text{(objective)}, \: \epsilon \text{ (epsilon)} \\ &\hspace{13mm} \lambda \text{(weight decay)}, \: \textit{amsgrad}, \: \textit{maximize} \\ &\textbf{initialize} : m_0 \leftarrow 0 \text{ (first moment)}, v_0 \leftarrow 0 \text{ ( second moment)}, \: \widehat{v_0}^{max}\leftarrow 0 \\[-1.ex] &\rule{110mm}{0.4pt} \\ &\textbf{for} \: t=1 \: \textbf{to} \: \ldots \: \textbf{do} \\ &\hspace{5mm}\textbf{if} \: \textit{maximize}: \\ &\hspace{10mm}g_t \leftarrow -\nabla_{\theta} f_t (\theta_{t-1}) \\ &\hspace{5mm}\textbf{else} \\ &\hspace{10mm}g_t \leftarrow \nabla_{\theta} f_t (\theta_{t-1}) \\ &\hspace{5mm} \theta_t \leftarrow \theta_{t-1} - \gamma \lambda \theta_{t-1} \\ &\hspace{5mm}m_t \leftarrow \beta_1 m_{t-1} + (1 - \beta_1) g_t \\ &\hspace{5mm}v_t \leftarrow \beta_2 v_{t-1} + (1-\beta_2) g^2_t \\ &\hspace{5mm}\widehat{m_t} \leftarrow m_t/\big(1-\beta_1^t \big) \\ &\hspace{5mm}\widehat{v_t} \leftarrow v_t/\big(1-\beta_2^t \big) \\ &\hspace{5mm}\textbf{if} \: amsgrad \\ &\hspace{10mm}\widehat{v_t}^{max} \leftarrow \mathrm{max}(\widehat{v_t}^{max}, \widehat{v_t}) \\ &\hspace{10mm}\theta_t \leftarrow \theta_t - \gamma \widehat{m_t}/ \big(\sqrt{\widehat{v_t}^{max}} + \epsilon \big) \\ &\hspace{5mm}\textbf{else} \\ &\hspace{10mm}\theta_t \leftarrow \theta_t - \gamma \widehat{m_t}/ \big(\sqrt{\widehat{v_t}} + \epsilon \big) \\ &\rule{110mm}{0.4pt} \\[-1.ex] &\bf{return} \: \theta_t \\[-1.ex] &\rule{110mm}{0.4pt} \\[-1.ex] \end{aligned} input:γ(lr),β1,β2(betas),θ0(params),f(θ)(objective),ϵ (epsilon)λ(weight decay),amsgrad,maximizeinitialize:m00 (first moment),v00 ( second moment),v0 max0fort=1todoifmaximize:gtθft(θt1)elsegtθft(θt1)θtθt1γλθt1mtβ1mt1+(1β1)gtvtβ2vt1+(1β2)gt2mt mt/(1β1t)vt vt/(1β2t)ifamsgradvt maxmax(vt max,vt )θtθtγmt /(vt max +ϵ)elseθtθtγmt /(vt +ϵ)returnθt
    ϵ \epsilon ϵ 用于数值稳定性的小常数,通常取一个很小的值(主要是避免避免分母为零的情况)
    对于Adam算法,权重衰减项是在计算梯度后与梯度相加的;对于AdamW算法,权重衰减项是在更新模型参数之前与当前模型参数相乘。

2.5 代码

2.5.1 代码结果

因为是自己电脑上跑的,准备的训练数据集比较少,所以这个结果肯定不是很准确的。
在这里插入图片描述

2.5.2 代码大致流程

训练网络结构(后续代码的一个大致流程):以gan_train.py为例

  • 准备数据集:自定义的数据集FWIDataset,通过读取txt文件中的npy文件路径去下载数据集
  • 建立数据加载器(数据加载器:为网络提供不同的加载形式)
  • 搭建神经网络模型:在本论文的代码中,有两种网络模型,一种是生成器Generate(和InversionNet差不多,代码调用都一样),一种是判别器discriminater(是一种CNN神经网络结构)
  • 创建损失函数 (生成器和判别器损失函数)
  • 创建优化器 (采用的AdamW优化算法)
  • 训练模型
  • 测试模型
  • 模型保存

4. 总结及收获

  1. 更为熟悉网络结构的一个完整流程。而我认为后续自己论文的主要出发点会在网络结构,损失函数和优化器上做创新。
  2. VelocityGan 是基于Gan网络进行的,在读完论文后,首先,VelocityGan的生成器和InversionNet的网络结构很相似。从最开始了解CNN一个传统的神经网络架构,主要就是卷积层,池化层到全连接层。到后续看到的一个FCN网络,将全连接层转换为卷积层,这样就可以保留空间的特征信息,添加反卷积层进行上采样,到后来了解到U-Net网络架构,一个对称的网络结构,也是一个端到端网络,U-Net的提出是在图像领域方面的,而后续看到我们研究内容相关的一些论文也是在这U-Net网络结构上进行创新,受到了很多启发(所以我们的确是可以去探索图像领域方面的优秀架构),如FCNVMB,他则是基于U-Net架构基础上创新。而我们看的这篇论文,他则可以说是在InversionNet网络架构的创新。 其次就是VelocityGan中的损失函数的设计,针对生成器和判别器,损失函数的设计不同,对于生成器,损失函数主要由对抗性损失和内容损失组成,对抗损失主要和判别器的判别结果有关,内容损失是和地质信息有关(主要是MSE和MSE); 对于判别器的损失函数主要是采用带有梯度惩罚的WGAN。最后优化器的选择,我想我更会倾向于ADAM和ADAMW中进行选择。
  3. 对于论文实验中提到各种模型的对比,以及在之前看论文中,都会有对比实验,而对比选择的模型是如何选择的?我不是很清楚。

4. 下周计划

  1. 主要任务是看这篇论文《Deep-Learning Full-Waveform Inversion Using Seismic Migration Images》
  2. 去看看图像相关论文的网络架构,学习一下。

相关推荐

  1. 202426

    2024-02-13 08:08:02       27 阅读
  2. 【Git】切换分支【2024219

    2024-02-13 08:08:02       28 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-13 08:08:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-13 08:08:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-13 08:08:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-13 08:08:02       18 阅读

热门阅读

  1. Atcoder ABC338 C - Leftover Recipes

    2024-02-13 08:08:02       35 阅读
  2. 如何查看电脑连接的wifi的密码

    2024-02-13 08:08:02       27 阅读
  3. C#系列-C#EF框架实现分库分表(21)

    2024-02-13 08:08:02       29 阅读
  4. C++11:智能指针

    2024-02-13 08:08:02       22 阅读
  5. ES实战--wildcard正则匹配&exists过滤字段是否存在

    2024-02-13 08:08:02       33 阅读
  6. C语言——oj刷题——模拟实现库函数strlen

    2024-02-13 08:08:02       33 阅读
  7. docker从入门到入土

    2024-02-13 08:08:02       37 阅读
  8. 2.12学习总结

    2024-02-13 08:08:02       40 阅读