使用简单rnn预测指数加权平均值

时间:2019-08-04 16:00:31

标签: tensorflow keras deep-learning recurrent-neural-network

为了进一步探索keras-tf RNN功能和不同参数,我决定解决上述玩具问题-

  1. 构建由一系列随机数组成的源数据集
  2. 构建一个由源数据集上执行的EWMA formula组成的“标签”数据集。

其背后的想法是EWMA对如何使用序列的“历史”有一个非常清晰和简单的定义-

EWMA t =(1-alpha)*平均值 t-1 + alpha * x t < / p>

我的假设是,当看一个简单的RNN单元时,当前输入有单个神经元,而先前状态只有一个神经元,方程的(1-alpha)部分可以直接是先前隐藏状态的权重,而 alpha 部分可以是网络经过充分训练后的当前输入权重。

例如,对于alpha = 0.2,我希望经过训练的网络权重为:

Waa = [0.8](先前状态的权重参数)

Wxa = [0.2](当前输入的权重参数)

我使用numpy非常简单地模拟了数据集和标签。

目前,我已经使用反向传播实现了自己的简单rnn。 我用MSE来衡量损失和SGD,它很快收敛到上述参数。一次只能在一个输入上工作。

我尝试使用keras和tensorflow尝试不同的网络配置,但似乎没有一个能碰到头。我想知道什么是最好的建议方式来复制玩具RNN的行为。

这是我的玩具神经网络-

import numpy as np
np.random.seed(1337)  # for reproducibility


def run_avg(signal, alpha=0.2):
    avg_signal = []
    avg = np.mean(signal)
    for i, sample in enumerate(signal):
        if np.isnan(sample) or sample == 0:
            sample = avg
        avg = (1 - alpha) * avg + alpha * sample
        avg_signal.append(avg)
    return np.array(avg_signal)

X = np.random.rand(10000)


Y = run_avg(X)


def train(X,Y):
    W_a = np.random.rand()
    W_x = np.random.rand()
    b = np.random.rand()
    a = np.random.rand()
    lr = 0.001
    for i in range(100):
        for x,y in zip(X,Y):
            y_hat = W_x * x + W_a * a + b
            L = (y-y_hat)**2
            dL_dW_a = (y - y_hat) * a
            dL_dW_x = (y - y_hat) * x
            dL_db = (y - y_hat) * 1
            W_a = W_a + dL_dW_a*lr
            W_x = W_x + dL_dW_x*lr
            b = b + dL_db*lr
            a = y_hat
        print("epoch " ,str(i), " LOSS = ", L, " W_a = ", W_a, " W_x = ", W_x , " b = " ,b)


train(X,Y)

与keras-tf simpleRNN相比,有关实现的几点说明-

  1. 该网络的“时间步长”为1,“批量大小”也为1。
  2. 该网络可能类似于张量流使用“有状态”参数建议的内容。由于在当前步骤中使用了最后一个状态预测(在循环中为“ a = y_hat”)。
  3. 就每个标签使用的输入而言,我认为可以肯定地说这是“一对一”的培训。

考虑到EWMA算法不仅可以保存序列的整个历史记录,而且还可以保存整个序列的历史信息,因此可以在EWMA算法的本质上添加很多内容,您将如何使用简单的RNN或任何神经网络来预测EWMA?

我如何在喀拉拉邦复制玩具神经网络的行为?

更新: 似乎阻止我解决此问题的主要问题似乎是由于使用“本机” keras(导入keras)而不是tensorflow实现(来自tensorflow导入keras)。 对此问题here发表了一个更具体的问题。

1 个答案:

答案 0 :(得分:0)

在keras中复制玩具神经网络行为的代码如下所示:

from tensorflow import keras
import numpy as np
from tensorflow.keras.models import Sequential as Sequential

np.random.seed(1337)  # for reproducibility

def run_avg(signal, alpha=0.2):
    avg_signal = []
    avg = np.mean(signal)
    for i, sample in enumerate(signal):
        if np.isnan(sample) or sample == 0:
            sample = avg
        avg = (1 - alpha) * avg + alpha * sample
        avg_signal.append(avg)
    return np.array(avg_signal)

def train():
    x = np.random.rand(3000)
    y = run_avg(x)
    x = np.reshape(x, (-1, 1, 1))
    y = np.reshape(y, (-1, 1))

    # SimpleRNN model
    model = Sequential()
    model.add(Dense(32, batch_input_shape=(1,1,1), dtype='float32'))
    model.add(keras.layers.SimpleRNN(1, stateful=True, activation=None, name='rnn_layer_1'))
    model.compile(optimizer=keras.optimizers.SGD(lr=0.1), loss='mse')
    model.summary()

    print(model.get_layer('rnn_layer_1').get_weights())
    model.fit(x=x, y=y, batch_size=1, epochs=10, shuffle=False)
    print(model.get_layer('rnn_layer_1').get_weights())

train()