1 自编码器
4.1 测试用例
4.2 降噪结果
4.3 降噪指标
自编码器(Auto-Encoder, AE)是神经网络的一种,严格意义上,自编码器是一种自监督算法,不属于无监督的机器学习方法,训练过程中,不需要对训练样本进行打标,其标签产生自输入数据[1]。经过训练后能够尝试将输入复 制到输出,其基本结构如图1所示。
图1 自编码器基本结构
自编码器由编码器和解码器组成,自编码器算法的基本过程如下[2]:
(1)编码:原始数据输入编码器,得到输入数据的隐含特征,这个过程即为编码(encoding);
(2)解码:特征信号输入解码器,得到重构的输入信号,这个过程即为解码(decoding);
(3)迭代:反复进行编码和解码过程,得到能够使输出信号与输入信号尽可能相似的加权(W,B)。
由于在编码和解码过程中输入数据会被压缩,特征会被降维,因此自编码器是一种有损方法,训练过程中,设定损失函数衡量由于压缩而损失的信息,训练的目的为最小化损失函数。
为了规避AE的过拟合问题,降噪自编码器(Denoising Auto-Encoder,DAE)被提出,其基本原理是对输入数据加入噪声,进而改善编码器的鲁棒性。
降噪自编码器的网络结构与自编码器类似,均由编码器和解码器两部分组成,它们的学习过程也相似,最终目的均是保证输出信号尽可能接近输入信号,图2所示为降噪自适应编码器的示意图。
图2 降噪自编码器[3]
降噪自编码器过程类似于dropout,降噪自编码器以一定概率将输入节点的值偏置为0,从而得到含有噪音的模型(破损数据)进行输入。使用破损数据进行训练的优点如下:
(1)当使用破损数据(即加入噪声的数据)训练DAE时,模型被迫学习从噪声中恢复出原始信号。这个过程使得模型的权重对噪声不那么敏感,因为模型已经学会了忽略这些噪声成分;
(2)破损数据训练出的模型在面对实际应用中的噪声时,由于已经在训练过程中接触过类似的噪声情况,因此具有更好的泛化能力。
堆叠降噪自编码器(Stacked Denoising Auto-Encoder,SDAE)由多个DAE组成,其结构如图3所示[4]。
图3 堆叠降噪自编码器
记由N组数据构成的样本集X的第i组数据样本
式中,W为输入层和隐藏层之间的权重矩阵,B为输入层与隐藏层之间的偏置矩阵,
解码运算是编码运算的逆过程,以隐藏层的特征向量作为输入向量重构原始输入,记Y为输出数据,则H与Y的解码关系为:
式中,W’为输入层和隐藏层之间的权重矩阵,B’为输入层与隐藏层之间的偏置矩阵,
训练过程中,各层DAE通过最小化输入数据与输出数据之间的重构误差来实现特征学习,利用梯度下降算法不断调整网络权重和偏置,降低重构误差,重构误差可表示为:
由于降噪训练的引入,SDAE在特征学习过程中具有一定的正则化效果,有助于减少过拟合的风险。此外,在数据集较大、特征复杂的情况下,SDAE通过逐层学习数据的层次结构,能够获得更好的泛化能力。
import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, models
import matplotlib.pyplot as plt
import matplotlib
# 生成示例数据
n = 500 # 生成1000个点的信号
t = np.linspace(0, 30*np.pi, 500, endpoint=False)
s = np.cos(0.1*np.pi*t) + np.sin(0.3*np.pi*t) + np.cos(0.5*np.pi*t) + np.sin(0.7*np.pi*t) # 原始信号
s = np.tile(s, (n, 1)) # 复 制为多个样本
r = 0.5 * np.random.normal(0, 1, s.shape)
y = s + r # 加噪声
# 建立堆叠自编码器模型
input_signal = layers.Input(shape=(500,))
encoded = layers.Dense(256, activation='relu')(input_signal)
encoded = layers.Dense(128, activation='relu')(encoded)
decoded = layers.Dense(256, activation='relu')(encoded)
decoded = layers.Dense(500, activation='linear')(decoded)
autoencoder = models.Model(input_signal, decoded)
autoencoder.compile(optimizer='adam', loss='mse')
# 训练模型,不使用验证集
h = autoencoder.fit(y, s, epochs=50, batch_size=32, validation_split=0.2)
# 使用模型进行降噪
denoised_signals = autoencoder.predict(y)
# 降噪评估
value = denoise_evaluate(s[0], r[0], denoised_signals[0])
print(value)
# 可视化结果
fig = plt.figure(figsize=(16, 9))
plt.subplots_adjust(hspace=0.5)
plt.subplots_adjust(left=0.05, right=0.98, top=0.95, bottom=0.05)
font = {'family': 'Times New Roman', 'size': 16, 'weight': 'normal',}
matplotlib.rc('font', **font)
plt.subplot(3, 1, 1)
plt.plot(t, s[0], linewidth=1.5, color='b')
plt.title('pure signal', fontname='Times New Roman', fontsize=20)
plt.subplot(3, 1, 2)
plt.plot(t, y[0], linewidth=1.5, color='r')
plt.title('noised signal', fontname='Times New Roman', fontsize=20)
plt.subplot(3, 1, 3)
plt.plot(t, denoised_signals[0], linewidth=1.5, color='g')
plt.title('SDAE', fontname='Times New Roman', fontsize=20)
# 绘制损失曲线
plt.figure(figsize=(10, 6))
plt.plot(h.history['loss'], label='训练损失', color='b')
plt.title('训练损失曲线', fontname='Simsun', fontsize=20)
plt.xlabel('Epoch', fontname='Times New Roman', fontsize=20)
plt.ylabel('Loss', fontname='Times New Roman', fontsize=20)
plt.show()
损失曲线如图5所示。
[4] 王亚伦,周涛,陈中,等. 基于堆叠式降噪自动编码器和深度神经网络的风电调频逐步惯性智能控制[J]. 上海交通大学学报,2023,57(11):1477-1491. DOI:10.16183/j.cnki.jsjtu.2022.157.