概述
最近一直在研究与自编码相关的深度学习知识,关于自编码相关的数学知识请移步相关的解释网站,这里不再赘述。一直想利用tensorflow实现一个自编码的小例子,网上列出的例子大部分都是和官方例子相似的图像处理的实例代码。这些例子对于没有图像处理的人来说有些晦涩,所以想自己设计一个自编码网络的例子来说明一下深度学习在自编码网络中的作用,突然想到大名鼎鼎的傅里叶变换其实也可以利用自编码网络来实现。
傅里叶分解在工程学上常用于时间信号处理,即将所有信号看称为基函数为一系列频率不同的三角函数的线性组合。因此我们可以选用两个基函数线性组成的时间序列为训练对向,通过自编码网络训练来获取基函数。
设定 y = a * sin(x) + b * sin(2*x) 在x属于[0, PI/2]的区间内均匀采样30的点来表示信号。 这样就可以利用随机生成a和b来生成大量的训练数据。
FIG1 训练信号集
FIG2 典型自编码网络的结构
网络结构:
第一层作为输入层,因此神经元的维数为信号的长度, 因为本例信号采样长度为30,故第一层的维数为30;
第二层为隐藏层,信号由两个基函数的线性组合,我们期望隐藏层的节点值正好是信号系数,故隐藏层的维数为2;
第三层为输出层,相当于还原信号,维数为30;
激活函数:
隐藏层选用sigmoid函数,输出层不用激活函数。不使用激活函数的目的是为了实现解码即:
y = ahidden1 * w1 + ahidden2 * w2
w1, w2 为输出层系数矩阵的两行值,最后期待w1, w2 接近两个基函数在选定区间的波形,就能实现利用自编码网络实现类似傅里叶变换的信号分解。
目标函数:
目标函数为min(y-x)^2
FIG3 训练结果
从训练结果可以看出,分解信号的效果是达到了,但精度还有待进一步提高。其中青色和红色为精确基函数,蓝色和绿色为训练结果。
关于如何提高精度,期待高手指教。
代码附上:
#!/usr/bin/Python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
from matplotlib import pyplot as plt
if __name__ == "__main__":
PI = 3.1415926
totalSize = 300
factor_data = np.float32(np.random.uniform(0,1, size= (totalSize,2)))
x = np.linspace(0.0, PI, num=30)
template = np.array([np.sin(x), np.sin(2 * x)])
singles = np.float32(np.dot(factor_data, template))
trainSingles = []
for i in range(totalSize):
onesingle = []
for j in range(30):
onesingle.append(singles[i][j])
trainSingles.append(onesingle)
n_input = 30
n_hidden = 2
n_output = 30
batch_size = 1
learning_rate = 0.05
totalSteps = 1
X = tf.placeholder(tf.float32, [None,n_input])
yTrue = X
wEncoder = tf.Variable(tf.random_normal([n_input, n_hidden]))
wDecoder = tf.Variable(tf.random_normal([n_hidden, n_output]))
bEncode = tf.Variable(tf.random_normal([n_hidden]))
bDecoder = tf.Variable(tf.random_normal([n_output]))
hiddenlayer = tf.nn.sigmoid(tf.add(tf.matmul(X, wEncoder), bEncode))
Y = tf.add(tf.matmul(hiddenlayer,wDecoder), bDecoder)
cost = tf.reduce_mean(tf.pow(Y - yTrue, 2))
opt = tf.train.RMSPropOptimizer(learning_rate).minimize(cost)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for step in range(totalSteps):
for i in range(int(totalSize / batch_size)):
_,c = sess.run([opt,cost],feed_dict={ X:[trainSingles[i]]})
if step%20 == 0:
print("step"+str(step)+":"+ str(c))
sess.run(wDecoder)
w = wDecoder.eval()
plt.figure()
plt.plot(x,w[0])
plt.plot(x,w[1])
plt.plot(x,np.sin(x))
plt.plot(x,np.sin(2*x))
plt.show()
最后
以上就是不安钢铁侠为你收集整理的自编码网络与时间信号分解的全部内容,希望文章能够帮你解决自编码网络与时间信号分解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复