Flexible Transmitter Network (南大Shao-Qun Zhang, Zhi-Hua Zhou)用FT0拟合sin信号python代码

Flexible Transmitter Network

原文附录A里,使用了FTNet模型对sin信号模拟。网上也没找到相关的代码,于是就自己尝试做一下,可能会有些错误,希望给位能够批评指正一下。下面是原文的图片。
sin

问题

我们要拟合的函数是周期为3的sin函数,x轴的范围为0到300的整数。首先给出产生数据的python代码。

# 生成数据
import numpy as np
a=np.array(range(300))
# x
y=np.sin(a*2/3*np.pi)
# y
import matplotlib.pyplot as plt
plt.plot(a[:60],y[:60]) # 画出这条线段 
plt.show()

数据图像如下:
在这里插入图片描述
根据论文,我们将论文中的模型带入,进行前向传播算法,得出预测数值。
以下为前向传播的公式,在这里可以把每一个字母当成标量。

st是输出信号,mt是t时刻的记忆强度,w和v是参数,xt是输入信号。
这边alpha和beta我都设置为1,原文中也没提到怎么设置这两个常数。
在这里插入图片描述
然后这个 σ \sigma σ 是激活函数,原文建议用 tanh 所以我们用tanh,然后原文介绍一个自然的想法就是将激活函数分别作用于复数的实部和虚部。

接着我们就写python代码,由于原文没有细说输入xt是什么,这里我们用 y t − 1 y_{t-1} yt1作为xt。mt是一个随时间更新的一个量。

x=y[:-1]
y=y[1:]
x.shape,y.shape

接着我们需要对这些数据矩阵化,然后初始化一些参数。

# 矩阵化
x=x.reshape(1,len(x))
y=y.reshape(1,len(y))
# 记录 x 和 y 的长度
lx,ly=x.shape[1],y.shape[1]
# 初始化所有参数
np.random.seed(1)
real=np.zeros(ly).reshape(1,ly)
image=np.zeros(ly).reshape(1,ly)
pre=np.zeros(ly).reshape(1,ly)
m=np.ones(ly).reshape(1,ly)*-0.24
w=np.array(np.random.randn(1)).reshape(1,1)
v=np.array(np.random.randn(1)).reshape(1,1)
real.shape,image.shape,pre.shape,m.shape,w,v

接着介绍前向传播和反向传播,同时计算损失函数。

# 前向传播
pre=np.tanh(np.matmul(w,x)-np.matmul(v,m))
real=np.matmul(w,x)-np.matmul(v,m)
image=np.matmul(w,x)+np.matmul(v,m)
# 计算损失
loss = np.sum(np.square(y-pre))/2
loss

下面进行反向传播

# 第一次迭代
dw=np.zeros(1).reshape(1,1)
dv=np.zeros(1).reshape(1,1)
dmw=np.zeros(ly).reshape(1,ly)
dmv=np.zeros(ly).reshape(1,ly)
for i in range(ly):
    dw+=(y[0,i]-pre[0,i])*(1-np.square(np.tanh(real[0,i])))*(x[0,i]-v*dmw[0,i])
    dmw[0,i]=(1-np.square(np.tanh(image[0,i])))*(x[0,i]+v*dmw[0,i])
    
for i in range(ly):                                         
    dv+=(y[0,i]-pre[0,i])*(1-np.square(np.tanh(real[0,i])))*-(m[0,i]+v*dmv[0,i])
    dmv[0,i]=(1-np.square(np.tanh(image[0,i])))*(m[0,i]+v*dmv[0,i])

# 更新参数,学习率0.01
w=w+0.01*dw
v=v+0.01*dv
m=np.tanh(np.matmul(w,x)+np.matmul(v,m))
# 第2次迭代前向传播
pre=np.tanh(np.matmul(w,x)-np.matmul(v,m))
real=np.matmul(w,x)-np.matmul(v,m)
image=np.matmul(w,x)+np.matmul(v,m)
# 计算损失
loss = np.sum(np.square(y-pre))/2
loss

设置最大迭代次数为1000,如果loss小于60则保存参数停止迭代

j=1
while j<1000:
    dw=np.zeros(1).reshape(1,1)
    dv=np.zeros(1).reshape(1,1)
    for i in range(ly):
        dw+=(y[0,i]-pre[0,i])*(1-np.square(np.tanh(real[0,i])))*(x[0,i]-v*dmw[0,i])
        dmw[0,i]=(1-np.square(np.tanh(image[0,i])))*(x[0,i]+v*dmw[0,i])

    for i in range(ly):                                         
        dv+=(y[0,i]-pre[0,i])*(1-np.square(np.tanh(real[0,i])))*-(m[0,i]+v*dmv[0,i])
        dmv[0,i]=(1-np.square(np.tanh(image[0,i])))*(m[0,i]+v*dmv[0,i])

    # 更新参数,学习率0.01
    w=w+0.01*dw
    v=v+0.01*dv
    m=np.tanh(np.matmul(w,x)+np.matmul(v,m))
    # 第六次迭代
    pre=np.tanh(np.matmul(w,x)-np.matmul(v,m))
    real=np.matmul(w,x)-np.matmul(v,m)
    image=np.matmul(w,x)+np.matmul(v,m)
    # 计算损失
    loss = np.sum(np.square(y-pre))/2
    j=j+1
    if loss<60 or j%50==0:
        print(w,v)
        print(m)
        print(loss)
        break

最后我们得出loss为57。下面我们绘制拟合效果图,以及记忆变量mt与信号yt的关系。

plt.plot(a[:60],y[0,:60])
plt.plot(a[:60],pre[0,:60]) 
plt.show()

在这里插入图片描述

plt.plot(a[:60],y[0,:60])
plt.plot(a[:60],m[0,:60]) 
plt.show()

在这里插入图片描述
两张图片看似一样,其实mt和pre的数值是不一样的,但是差距比较小。
接着我们使用传统的MP(多层感知器模型),同样采用tanh作为激活函数,隐藏层神经元设置为1,2,3,4,5。

from sklearn.neural_network import MLPRegressor
mlp = MLPRegressor(hidden_layer_sizes=(1),activation='tanh',max_iter=1000)
mlp.fit(x1,y1)
p2=mlp.predict(x1)
np.sum(np.square(p2-y1))
隐藏层神经元个数12345
loss1377157383

未解决的问题
1、原文的sin信号怎么生成的?
2、Mt如何更新?
文中的Mt是随时间变化的,那么对于时间序列问题来说预测一个值Mt就更新一次,但是在论文中反向传播时需要用到所有时间的数据,且Mt是在W和V更新之后,利用新的参数进行估计的,所以这边就比较困惑。

文章链接如下
[1]: https://arxiv.org/pdf/2004.03839.pdf

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值