目录
学习新东西的过程,应该是自顶向下,先给一个整体思路,再补充具体细节。更好的是给一个简单的例子,再迁移出特定场景下的困难的例子,最终再丰富这个困难例子的功能。
每一个故事的开始总是很美好,理想的情况下,我希望按照上面的思路完成代码讲解。但现实总是很骨感,因为学习者希望尽快的缩短听我嘚嘚的时间,因此直接就从困难的丰富的直接可用的例子开始,再辅以每一步为什么需要这样做的动机,应该也是很不错的。
希望这个2小时速成的例子,可以让大家的代码入门不再困难。
最后再送两句话给大家:
只有觉到悟到,才是自己的!2小时速成只是起点,需要大量的实践和试错,才能真正成为自己的知识!
要学会用调试手段观察中间过程!(闵老师教我的)每一个科研coder都是孤单的,因为没有人和你写一模一样的代码,你甚至无法判断它是对是错,那只有看每一步的结果是否符合自己的预期,才能给出相对客观的评价!
代码讲解的思路将从这样的方式展开:
1、数据加载
数据加载设计类型转换和处理操作。
1)类型转换。数据加载的最终目标是将躺在硬盘中的数据(numpy类型),放到GPU上(tensor类型),因此涉及到类型转换。
2)数据预处理。是否做归一化、翻转等操作。采取哪种处理方式,选择依据是什么?
3)关注数据维度的变换。往往数据维度不合适是出错的原因。
2、FWI网络模型
1)FWI网络的形状是什么?编解码器?Unet? 对抗网络?
2)网络中每一个组件是如何选择的?是否需要批归一化?激活函数ReLU/LeakyReLU?跳跃连接?残差级联?解码时上采样/转置卷积?是否加注意力模块?
3)搭建网络时,如何查看网络中通道数、宽、高变化?
注意:搭建网络是最难、种类最多的部分,大家的创新基本上都在这里。建议多看多借鉴地震数据处理、全波形反演论文中别人的模型,往往这些都是成功的经验,可能适合地震数据和全波形反演的组件/结构就那么几个。
3、训练网络模型
理论上,为什么训练网络模型后,它的性能就越来约好了呢?因为有损失函数,每一次的训练都希望损失函数越来越小 ,通过反向传播,模型(参数)被更新的越来越好。
1)一般,全波形反演常用的损失函数是,L1 和 L2损失函数。
2)在损失函数极小化的过程中,也可能会陷入局部最优解。这时候我们还要看是不是数据的问题,或者需要改进损失函数,或者训练策略。总之,要让损失函数下坡的过程尽可能顺利且结果正确。
3)训练时需要保存中间结果,如模型参数(方便中断后继续训练)、损失函数(观察训练过程)、一个好用的可视化工具是TensorBoard。
4、测试网络模型
测试这部分,涉及两个工作,计算评价指标和显示图像结果。
1)计算评价指标。常常使用(numpy类型)进行计算并保存,而在模型上炮的数据(tensor类型),这里又需要做数据类型转换。常见评价指标,SSIM、MSE、MAE。
2)显示图像,没啥好说的,直接抄代码就是。
5、参数定义
参数定义涉及参数形式和参数内容。
1)参数定义形式也是困扰我很久的一个部分,有的作者喜欢写pathConfig.py、paramConfig.py;
也有的作者通过导入对象argparse,将参数设置写到了训练测试过程。实际证明,在大规模程序开发中,后者更加方面,免去了写一大堆if else的苦恼。
2)参数内容涉及:路径(数据路径、模型路径、损失函数日志路径、测试评价指标结果路径)、模型(模型名称、是否归一化、插值类型、时间空间采样率)、训练(batchsize、epoch、学习率、加载数据线程数、是否可视化、打印频率、是否reuse模型训练)、测试(batchsize、加载数据线程数、是否可视化、缺失道、噪声)
6、工程文件结构
代码地址:GitHub - lanl/OpenFWI: A collection of codes with OpenFWI project
文章参考:Deng C, Feng S, Wang H, et al. OpenFWI: Large-scale Multi-structural Benchmark Datasets for Full Waveform Inversion[J]. Advances in Neural Information Processing Systems, 2022, 35: 6007-6020.
本次代码的讲解基于以上工程,原因:就是人家的代码规范很不错,有公开数据集、配套论文。
包含了三个网络;FCNVMB、InversionNet、VelocityGAN。
现在,学习之旅正式开始。