艺考网
全国站

你还不懂的傅里叶变换,神经网络只用了30多行代码就学会了

xunaa
2024-10-08 07:12:09
编辑说
通俗地说,离散傅里叶变换(DFT)就是将一系列复杂的波形划分为不同的频率分量。
比如说声音,如果用录音机来显示声音的话,其实生活中大部分的声音都是非常复杂甚至是杂乱的。
通过

通俗地说,离散傅里叶变换(DFT)就是将一系列复杂的波形划分为不同的频率分量。

比如说声音,如果用录音机来显示声音的话,其实生活中大部分的声音都是非常复杂甚至是杂乱的。

通过傅里叶变换,可以将这些杂乱的声波转换成正弦波,这就是我们通常在音乐声谱图中看到的。

但在实际计算中,这个过程其实是非常复杂的。

如果将声波视为连续函数,则它可以唯一地表示为叠加的三角函数的堆栈。但在叠加过程中,各个三角函数的权重系数是不同的。有的应该提高,有的应该降低,有的甚至不应该增加。

傅里叶变换找到这些三角函数及其各自的权重。

难道不是巧合吗?这个搜索过程非常类似于神经网络。

神经网络的本质其实就是逼近一个函数。

是不是可以用训练神经网络的方法来获得傅里叶变换呢?

这确实可行,最近有人在网上发布了他的训练过程和结果。

DFT=神经网络

如何训练神经网络?这位网友给出的思路是这样的:

首先,离散傅里叶变换(DFT)应该被视为一种人工神经网络。这是一个单层网络,没有偏置,没有激活函数,权重有特定值。其输出节点数等于傅里叶变换计算后的频率数。

具体方法如下:

这是一个DFT:

k表示每N个样本的循环数; N表示信号的长度;表示样本n 处的信号值。信号可以表示为所有正弦信号的总和。

你还不懂的傅里叶变换,神经网络只用了30多行代码就学会了

yk 是一个复数值,给出信号x 中频率为k 的正弦信号的信息;根据yk 我们可以计算出正弦波的幅度和相位。

改成矩阵形式,就变成了这样:

这里给出了特定值k 的傅立叶值。

但通常情况下,我们要计算全谱,即从[0,1,N-1]中得到k的值,可以用矩阵来表示(k按列增加,n按行增加) :

化简后我们得到:

你应该熟悉这一点,因为它是一个没有偏置和激活函数的神经网络层。

指数矩阵包含权重,可以称为复傅立叶权重。通常我们不知道神经网络的权重,但我们可以在这里。

不要使用复数。通常我们在神经网络中不使用复数。为了适应这种情况,我们需要将矩阵的大小加倍,使得左侧部分包含实数,右侧部分包含虚数。

将要

引入DFT,可得:

然后用实部(cos形式)表示矩阵的左半部分,用虚部(sin形式)表示矩阵的右半部分:

化简后我们可以得到:

将要

称为傅立叶权重;

需要注意的是,y^和y实际上包含相同的信息,但是y^

没有使用复数,因此它的长度是y 的两倍。

你还不懂的傅里叶变换,神经网络只用了30多行代码就学会了

换句话说,我们可以使用

或者

代表幅度和相位,但我们通常使用

现在,可以将傅立叶层添加到网络中。

用傅里叶权重计算傅里叶变换

现在可以使用神经网络来实现

,并使用快速傅立叶变换(FFT) 检查它是否正确。

将matplotlib.pyplot 导入为plty_real=y[:signal_length]y_imag=y[: signal_length:]tvals=np.arange(signal_length).reshape([-1, 1])freqs=np.arange(signal_length).reshape( [1, -1])arg_vals=2 * np.pi * tvals * freqs/signal_lengthsinusoids=(y_real * np.cos(arg_vals) - y_imag * np.sin(arg_vals))/signal_lengthreconstructed_signal=np.sum(sinusoids, axis=1)print('rmse:', np.sqrt(np.mean((x - 重建信号)**2)))plt.subplot(2, 1, 1)plt.plot(x[0,])plt .title('原始信号')plt.subplot(2, 1, 2)plt.plot(reconstructed_signal)plt.title('DFT后从正弦曲线重建的信号')plt.tight_layout()plt.show()rmse: 2.3243522568191728e这个-15这个小误差值可以证明计算出来的结果就是我们想要的。

另一种方法是重建信号: import matplotlib.pyplot as plty_real=y[:signal_length]y_imag=y[: signal_length:]tvals=np.arange(signal_length).reshape([-1, 1])freqs=np .arange(signal_length).reshape([1, -1])arg_vals=2 * np.pi * tvals * freqs/signal_lengthsinusoids=(y_real * np.cos(arg_vals) - y_imag * np.sin(arg_vals))/signal_lengthreconstructed_signal=np.sum(正弦曲线, axis=1)print('rmse:', np.sqrt(np.mean((x - 重建信号)**2)))plt.subplot(2, 1, 1)plt.plot ( x[0,])plt.title('原始信号')plt.subplot(2, 1, 2)plt.plot(reconstructed_signal)plt.title('DFT后从正弦曲线重建的信号')plt.tight_layout( ) plt.show()rmse: 2.3243522568191728e-15

最后可以看出,DFT后的正弦信号重构的信号与原始信号能够很好地重叠。

通过梯度下降学习傅里叶变换

现在是神经网络实际学习的部分。这一步不需要像之前那样预先计算权重值。

首先,使用FFT训练神经网络来学习离散傅里叶变换:

import tensorflow as tfsignal_length=32# 将权重向量初始化为train:W_learned=tf.Variable(np.random.random([signal_length, 2 * signal_length]) - 0.5)# 预期权重,用于比较:W_expected=create_fourier_weights(signal_length)losses=[]rmses=[]for i in range(1000): # 每次迭代生成一个随机信号: x=np.random.random([1, signal_length]) - 0.5 # 使用FFT: 计算预期结果fft=np.fft.fft( x) y_true=np.hstack([fft.real, fft.imag]) 与tf.GradientTape() 作为Tape: y_pred=tf.matmul(x, W_learned) 损失=tf.reduce_sum(tf.square(y_pred - y_true) ) # 通过梯度下降训练权重: W_gradient=Tape.gradient(loss, W_learned) W_learned=tf.Variable(W_learned - 0.1 * W_gradient)loss.append(loss) rmses.append(np.sqrt(np.mean((W_learned) - W_expected)**2)))最终损失值1.6738563548424711e-09最终权重rmse 值3.1525832404710523e-06

结果如上,证实了神经网络确实可以学习离散傅里叶变换。

训练网络学习DFT

你还不懂的傅里叶变换,神经网络只用了30多行代码就学会了

除了使用快速傅里叶变换方法外,还可以通过网络学习DFT来重构输入信号。 (类似于自动编码器)。

自动编码器(AE)是一种用于半监督学习和无监督学习的人工神经网络(ANN)。其功能是以输入信息为学习目标,对输入信息进行表征学习。 (表征学习)。

W_learned=tf.Variable(np.random.random([signal_length, 2 * signal_length]) - 0.5)tvals=np.arange(signal_length).reshape([-1, 1])freqs=np.arange(signal_length)。 reshape([1, -1])arg_vals=2 * np.pi * tvals * freqs/signal_lengthcos_vals=tf.cos(arg_vals)/signal_lengthsin_vals=tf.sin(arg_vals)/signal_lengthlosses=[]rmses=[]for i in范围(10000): x=np.random.random([1, signal_length]) - 0.5 tf.GradientTape() 作为tape: y_pred=tf.matmul(x, W_learned) y_real=y_pred[: 0:signal_length] y_imag=y_pred [:signal_length:] 正弦曲线=y_real * cos_vals - y_imag * sin_vals 重构信号=tf.reduce_sum(sinusoids, axis=1) 损失=tf.reduce_sum(tf.square(x - 重构信号)) W_gradient=Tape.gradient(loss, W_learned ) W_learned=tf.Variable(W_learned - 0.5 * W_gradient) Loss.append(loss) rmses.append(np.sqrt(np.mean((W_learned - W_expected)**2)))最终损失值4.161919455121241e-22最终权重'均方根值0.20243339269590094

让我们尝试改变输入幅度和相位。

W_learned=tf.Variable(np.random.random([signal_length, 2 * signal_length]) - 0.5)losses=[]rmses=[]for i in range(10000): x=np.random.random([1, signal_length]) - .5 与tf.GradientTape() 作为Tape: y_pred=tf.matmul(x, W_learned) y_real=y_pred[: 0:signal_length] y_imag=y_pred[: signal_length:] 幅度=tf.sqrt(y_real**2 + y_imag**2)/signal_length 相位=tf.atan2(y_imag, y_real) 正弦曲线=振幅* tf.cos(arg_vals + 相位) 重建信号=tf.reduce_sum(sinusoids, axis=1) 损失=tf.reduce_sum(tf.平方(x - 重建信号))W_gradient=Tape.gradient(损失,W_learned)W_learned=tf.Variable(W_learned - 0.5 * W_gradient)loss.append(损失)rmses.append(np.sqrt(np.mean((W_learned - W_expected)**2)))最终损失值2.2379359316633115e-21最终权重rmse 值0.2080118219691059

可以看出,重建后的信号又是一致的;

然而,和以前一样,输入幅度和相位的所得权重并不完全等于傅立叶权重(但非常接近)。

可以得出结论,虽然最终的权重不是最准确的,但也能得到局部最优解。

这样,神经网络就学会了傅里叶变换!

值得一提的是,这种方法仍然存在质疑:首先,它没有解释计算权重与真实傅立叶权重之间的差异;

此外,没有解释将傅里叶层放入模型中的好处。

原文链接:https://sidsite.com/posts/fourier-nets/

- 超过-

用户评论

没过试用期的爱~

这也太牛了吧!机器学习的速度越来越快。

    有8位网友表示赞同!

浅巷°

感觉科技发展真是让人兴奋啊,这些复杂的数学概念都被程序员搞定了。

    有5位网友表示赞同!

﹎℡默默的爱

看来我得着手学点编程知识了,不然以后就跟不上时代了。

    有7位网友表示赞同!

一纸愁肠。

30行代码就能学会傅里叶变换?这神经网络也太厉害了吧!

    有18位网友表示赞同!

凉城°

我一直觉得傅里叶变换很难懂,没想到代码都能搞定!

    有20位网友表示赞同!

仰望幸福

看来未来技术将会发展得更加迅速和智能化。

    有8位网友表示赞同!

青衫负雪

30行代码能解决问题?我还以为要写个大文档才能算完呢!

    有11位网友表示赞同!

大王派我来巡山!

这证明数学和计算机科学的结合越来越紧密,真是太精彩了!

    有18位网友表示赞同!

来瓶年的冰泉

我一直想搞懂傅里叶变换,现在看来不用自己费苦脑筋了。

    有5位网友表示赞同!

单身i

神经网络真是一年比一年强啊!

    有9位网友表示赞同!

灵魂摆渡人

看来人工智能的发展确实让人感到期待。 我觉得将来会有更多复杂问题被解决

    有8位网友表示赞同!

眉黛如画

数学知识在深度学习中的应用,果然是未来科技发展的重要方向!

    有16位网友表示赞同!

烟雨离殇

这篇文章让我感觉神经网络真的是越来越强大啦!

    有9位网友表示赞同!

_心抽搐到严重畸形っ°

以后是不是连傅里叶变换这种专业的东西都能用代码实现?

    有15位网友表示赞同!

陌潇潇

我终于明白为什么很多人都在学习编程了,掌握这些技能太关键了。

    有17位网友表示赞同!

失心疯i

人工智能真的改变世界啊,以前不可能想象到的事情现在都能实现!

    有17位网友表示赞同!

冷风谷离殇

希望有更多人了解傅里叶变换的魅力,以及神经网络的强大功能!

    有11位网友表示赞同!

哥帅但不是蟋蟀

真想知道这30行代码具体写的什么!

    有9位网友表示赞同!

免责声明
本站所有收录的学校、专业及发布的图片、内容,均收集整理自互联网,仅用于信息展示,不作为择校或选择专业的建议,若有侵权请联系删除!

大家都在看

你还不懂的傅里叶变换,神经网络只用了30多行代码就学会了

你还不懂的傅里叶变换,神经网络只用了30多行代码就学会了

通俗地说,离散傅里叶变换(DFT)就是将一系列复杂的波形划分为不同的频率分量。 比如说声音,如果用录音机来显示声音的话,其实生活中大部分的声音都是非常复杂甚至是杂乱的。 通过
2024-10-08
过去分词作为表语和状语的总结

过去分词作为表语和状语的总结

1.过去分词作为表语成分 过去分词作为表语成分并不意味着“完整”或“被动”。主要表达主体的感情或心理状态,主体通常是人。 示例:地中海四分之一的海岸受到污染。 他似乎很
2024-10-08
动词不定式、动名词、分词等非谓语形式的几种类型、含义和作用

动词不定式、动名词、分词等非谓语形式的几种类型、含义和作用

动词不定式、动名词、分词三种形式都是动词的非谓语形式;分词包括两种形式:现在分词和过去分词。它们不能单独作为句子中的谓词。 动词不定式 形式:动词不定式的基本形式由“不
2024-10-08
考研阅读提高成绩的几点

考研阅读提高成绩的几点

一、英语阅读理解的命题特点 (一)阅读理解的命题特征 一、阅读理解的定义及其答题启示 阅读理解的定义有很多种,但总的来说我们认为阅读理解本质上是认知能力、逻辑思维能力
2024-10-08
高中英语第二单元(必修四)关键短语讲解,值得评分!

高中英语第二单元(必修四)关键短语讲解,值得评分!

1. 与斗争相同。斗争 他正在与坏人作斗争 2. 奋斗。和奋斗 他正在为自己的权利而奋斗 3. 挣扎着站起来 他挣扎着站起来 4.感谢 谢谢你,我可以通过考试谢谢你,我可以通过考试 5
2024-10-08
#squirrelsplitword #struggle

#squirrelsplitword #struggle

拆除: str- 意思是“抓住,紧紧抓住”。我个人的理解是用手做某事,可以恰当地理解为“撕开” 丑陋,丑陋 猜: 双手被撕破是什么丑陋的现象? 答复: 斗争、反抗、斗争 用户评论 寒
2024-10-08
今天分享两个单词并利用词根词缀来记忆(37)

今天分享两个单词并利用词根词缀来记忆(37)

名词派遣、发送、紧急邮件、电信 v. 派遣,派出,发送 根: -patch:同ped-、pod-、=foot,表示脚。 词缀: dis-:意为“分开、分散”,引申为“离开、无、无、缺少、相反”等。 dis-+-patc
2024-10-08
适合发扎的简短而精致的鼓励句子:奋斗永远是一个开始。

适合发扎的简短而精致的鼓励句子:奋斗永远是一个开始。

1、奋斗没有终点,却永远有一个开始。 奋斗没有终点,却永远有起点。 2.我不顾一切地为了你而伤害自己。 我曾经为了你不顾一切,甚至伤害自己。 3.当泪水流下来时,留下的应该是坚
2024-10-08
学会这10个英语单词,你的英语永远不会过时!

学会这10个英语单词,你的英语永远不会过时!

学会这10个单词,你的英语就不会过时! Millennials: 千禧一代,涵盖美国20 世纪80 年代至2000 年代出生的人Millennium: Millennial Gen 大家都知道,成人就是成人的意思。 但这个
2024-10-08
下的用法

下的用法

你看过床底下吗? 你看过床底下吗? 她把梯子放在窗户下面。 她把梯子立在窗户下面。 狗从门缝里挤了进去,跑到了路上。 狗从门缝里钻出来,跑到路上。 他躲在床底下。 他躲在床底
2024-10-08