美文网首页
深度学习去噪新思路——教你用自编码实现非监督地震降噪

深度学习去噪新思路——教你用自编码实现非监督地震降噪

作者: 科技州与数据州 | 来源:发表于2020-06-27 19:57 被阅读0次

    深度学习是人工智能的基石,正飞速的改变着我们的生活,也是现在最热的研究方向之一。深度学习的传统方法是监督学习,需要提供训练的样本标签。但像很多训练很难提供准确的样本标签,比如地震信号的去除噪声标签。这时研究非监督学习就很重要了。

    与有监督学习有明确的目标输出不同,无监督学习没有给定目标输出,而是去提取数据本身的静态结构特征。其中一个无监督算法就是自编码。

    01 什么是自编码

    自编码是区别于人工编码的过程,人工编码是通过人的经验将数据进行编码。而自编码过程是不需要人工的。那么,自编码一定需要有办法知道自己的编码方法是否合理。这个方法就是解码器,用解码器来看解码之后的复原情况。如果我能通过解码器将你编码器压缩的数据恢复得差不多,那么你的编码就是合理的。如下图:

    同样的原理,如果自编码从噪声数据中学习到了有效信号的特征,那么通过编码和解码,就可以从噪声中还原有用的信号。如下图:

    02 一个地震信号通过非监督学习去除噪声的全过程

    1.训练地震资料

    这里使用一个仿真近地表的地震资料,如下图:

    这是一个不含有随机噪声的地震资料(终止时间3000毫秒),尺寸为661到*661采样点。

    2.对地震资料获取训练样本集

    (1)读取地震信号

    使用segyio读取地震信号

    with segyio.open(file_list[i],'r',ignore_geometry=True) as f

    (2)从地震信号中获取小块训练样本

    获取1000个,128*128的地震小块样本,在获取过程中还设计了90、180、270等不同角度的翻转,使得训练样本形态更丰富。

    另外,为了处理和可视化展示高效,数据都归一化到了(-1,1)区间。主要代码:

    data_test = data_test/data_test.max()#归一化到-1,1之间

    (3)将训练样本保存为二级制文件

    为了方便后续调用训练数据集方便,将训练集保存为二进制文件。

    np.save('seismic_patches.npy', train_data)

    3.对训练样本集使用全连接网络进行训练

    (1)读取二进制的训练集

    train_data='seismic_patches.npy'

    data = np.load(train_data)#(1000,128,128,1)

    data = data.astype(np.float64)

    (2)构建全连接神经网络模型

    这是一个隐藏层为32层的全连接神经网络。主要代码如下:

    # 构建模型

    hidden_units = 32

    image_size =data.shape[1]#128

    # 输入层

    inputs_ = tf.placeholder(tf.float32, [None, image_size,image_size,1], name='inputs_')

    targets_ = tf.placeholder(tf.float32, [None, image_size,image_size,1], name='targets_')

    ## 隐层

    hidden_layer = tf.layers.dense(inputs_, hidden_units, activation=tf.nn.relu)

    ## 输出层

    #logits_ = tf.layers.dense(hidden_layer,image_size, activation=None)

    logits_ = tf.layers.dense(hidden_layer,1, activation=None)

    outputs_ = tf.sigmoid(logits_, name='outputs_')

    # 损失函数

    loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=targets_, logits=logits_)

    cost = tf.reduce_mean(loss)

    # 优化函数

    optimizer = tf.train.AdamOptimizer(0.001).minimize(loss)

    (3)训练样本

    采用20个周期训练,每个批次为50,在每个批次训练过程中加噪声。这里训练的样本和标签都是噪声数据。主要代码如下:

    sess = tf.Session()

    epochs = 20#改为20

    noise_factor = 25

    batch_size = 50

    sess.run(tf.global_variables_initializer())

    indices = list(range(data.shape[0]))#1000,一个序列(0,1,2...999)

    np.random.shuffle(indices) # shuffle简单随机排列,打乱顺序(624,2942,2149,...)

    for e in range(epochs):

    for i in range(0, len(indices), batch_size):#len(indices)=1000

    batch = data[indices[i:i+batch_size]]

    noise = np.random.normal(0, noise_factor/255.0, batch.shape)

    batch_noise = batch + noise

    batch_noise = np.clip(batch_noise, 0.0, 1.0)

    batch_cost, _ = sess.run([cost, optimizer],

    feed_dict={inputs_:batch_noise, targets_: batch_noise})

    print("Epoch: {}/{}...".format(e+1, epochs),"Training loss: {:.4f}".format(batch_cost))

    4.测试训练效果

    (1)选取测试数据

    还是从训练地震信号中选取一块256*256的数据块,并进行归一化处理。

    (2)将地震数据增加噪声。

    (3)将地震噪声信号拆分为小的地震块并带入程序进行预测

    noisy_imgs = myimtocol(inputs, patch_rows, patch_rows, n2, n1*n3, tslide,xslide,1);#拆分为(81,128,128)的地震块

    reconstructed = sess.run(outputs_, feed_dict={inputs_: noisy_imgs})#(81,128,128,1)预测清晰信号

    (4)重新组合小地震块并显示最终的效果

    reconstructed = myimtocol(reconstructed, patch_rows, patch_rows, n2, n1*n3, tslide,xslide,0);#将地震块组合为完整地震数据(256,256)

    im_Denoise = axs[0].imshow(reconstructed, cmap=plt.cm.seismic, vmin=vmin, vmax=vmax)#显示最终去噪效果

    这个效果确实不太让人满意,主要是全连接神经网络本来的性能有限。在参数设置方面,使用20个epoch,使用81张图块进行训练,这些训练量都太小了。

    在网上有个爱好者使用自编码对Minist图片训练集降噪,找了10000个小图块进行降噪训练,效果如下图,确实也不太理想。

    03 小结

    地震信号降噪的原理与图片类似,都是要让模型学习到有规律的特征——有效信号,而去除无效的噪声信号。

    但是全连接神经网络结构对于特征学习能力有限,而且训练样本还需要增加,这些都需要在下一次的研究中完善。

    喜欢请点赞,或关注公众号“科技爸遇到文艺妈”获取更多干货好文。

    相关文章

      网友评论

          本文标题:深度学习去噪新思路——教你用自编码实现非监督地震降噪

          本文链接:https://www.haomeiwen.com/subject/bmbvfktx.html