使用RNN和Keras进行信号对信号的训练

时间:2019-03-19 12:14:52

标签: keras recurrent-neural-network

我正在尝试复制出色的作品here并对其进行改编,以便它从文件中读取真实数据。 我首先生成随机信号(而不是上面链接中提供的生成方法)。 Unfortoutanyl,我无法生成模型可以接受的正确信号。

代码如下:

import numpy as np
import keras
from keras.utils import plot_model
input_sequence_length = 15 # Length of the sequence used by the encoder
target_sequence_length = 15 # Length of the sequence predicted by the decoder
import random

def getModel():# Define an input sequence.

    learning_rate = 0.01
    num_input_features = 1
    lambda_regulariser = 0.000001 # Will not be used if regulariser is None
    regulariser = None # Possible regulariser: keras.regularizers.l2(lambda_regulariser)
    layers = [35, 35]
    num_output_features=1
    decay = 0 # Learning rate decay
    loss = "mse" # Other loss functions are possible, see Keras documentation.



    optimiser = keras.optimizers.Adam(lr=learning_rate, decay=decay) # Other possible optimiser "sgd" (Stochastic Gradient Descent)


    encoder_inputs = keras.layers.Input(shape=(None, num_input_features))

    # Create a list of RNN Cells, these are then concatenated into a single layer
    # with the RNN layer.
    encoder_cells = []
    for hidden_neurons in layers:
        encoder_cells.append(keras.layers.GRUCell(hidden_neurons, kernel_regularizer=regulariser,recurrent_regularizer=regulariser,bias_regularizer=regulariser))

    encoder = keras.layers.RNN(encoder_cells, return_state=True)
    encoder_outputs_and_states = encoder(encoder_inputs)

    # Discard encoder outputs and only keep the states.
    # The outputs are of no interest to us, the encoder's
    # job is to create a state describing the input sequence.
    encoder_states = encoder_outputs_and_states[1:]

    # The decoder input will be set to zero (see random_sine function of the utils module).
    # Do not worry about the input size being 1, I will explain that in the next cell.
    decoder_inputs = keras.layers.Input(shape=(None, 1))

    decoder_cells = []
    for hidden_neurons in layers:
        decoder_cells.append(keras.layers.GRUCell(hidden_neurons,
                                                  kernel_regularizer=regulariser,
                                                  recurrent_regularizer=regulariser,
                                                  bias_regularizer=regulariser))

    decoder = keras.layers.RNN(decoder_cells, return_sequences=True, return_state=True)

    # Set the initial state of the decoder to be the ouput state of the encoder.
    # This is the fundamental part of the encoder-decoder.
    decoder_outputs_and_states = decoder(decoder_inputs, initial_state=encoder_states)

    # Only select the output of the decoder (not the states)
    decoder_outputs = decoder_outputs_and_states[0]

    # Apply a dense layer with linear activation to set output to correct dimension
    # and scale (tanh is default activation for GRU in Keras, our output sine function can be larger then 1)
    decoder_dense = keras.layers.Dense(num_output_features,
                                       activation='linear',
                                       kernel_regularizer=regulariser,
                                       bias_regularizer=regulariser)

    decoder_outputs = decoder_dense(decoder_outputs)

    # Create a model using the functional API provided by Keras.
    # The functional API is great, it gives an amazing amount of freedom in architecture of your NN.
    # A read worth your time: https://keras.io/getting-started/functional-api-guide/ 
    model = keras.models.Model(inputs=[encoder_inputs, decoder_inputs], outputs=decoder_outputs)
    model.compile(optimizer=optimiser, loss=loss)
    print(model.summary())
    return model

def getXY():

    X, y = list(), list()
    for _ in range(100):
        x = [random.random() for _ in range(input_sequence_length)]
        y = [random.random() for _ in range(target_sequence_length)]
        X.append([x,[0 for _ in range(input_sequence_length)]])
        y.append(y)
    return np.array(X), np.array(y)

X,y = getXY()
print(X,y)
model = getModel()
model.fit(X,y)

我收到的错误消息是:

  

ValueError:检查模型输入时出错:Numpy数组的列表   您传递给模型的信息不是模型期望的大小。   预期会看到2个数组,但得到以下1个列表   数组:

模型的输入数据的正确形状是什么?

1 个答案:

答案 0 :(得分:0)

如果仔细阅读inspiration的来源,您会发现他谈论的是“ decoder_input”数据。

他谈到了“教师强制”技术,该技术包括向解码器提供一些延迟的数据。但也说这在他的情况下并不能很好地发挥作用,因此他将解码器的初始状态设置为0,例如line shows

decoder_input = np.zeros((decoder_output.shape[0], decoder_output.shape[1], 1))

在他的自动编码器设计中,它们是两个具有不同输入的独立模型,然后他将它们与RNN统计信息相互关联。

我可以看到您尝试做同样的事情,但是您将np.array([x_encoder, x_decoder])附加在应该完成的地方[np.array(x_encoder), np.array(x_decoder)]。网络的每个输入都应该是输入列表中的一个numpy数组,而不是一个大的numpy数组。

我还在您的代码中发现了一些错字,您将y附加到其自身,而应在其中创建一个Y变量

def getXY():

    X_encoder, X_decoder, Y = list(), list(), list()
    for _ in range(100):
        x_encoder = [random.random() for _ in range(input_sequence_length)]
        # the decoder input is a sequence of 0's same length as target seq
        x_decoder = [0]*len(target_sequence_length)
        y = [random.random() for _ in range(target_sequence_length)]
        X_encoder.append(x_encoder)
        # Not really optimal but will work
        X_decoder.append(x_decoder)
        Y.append(y)
    return [np.array(X_encoder), np.array(X_decoder], np.array(Y)

现在,当您这样做时:

X, Y = getXY()

您会收到X(它是2个numpy数组的列表(根据您的模型要求),Y是一个numpy数组的列表。

我希望这对您有帮助

编辑

实际上,在生成数据集的代码中,您可以看到它们为输入构建了3维np数组。 RNN需要3维输入:-)

以下代码应解决形状问题:

def getXY():

    X_encoder, X_decoder, Y = list(), list(), list()
    for _ in range(100):
        x_encoder = [random.random() for _ in range(input_sequence_length)]
        # the decoder input is a sequence of 0's same length as target seq
        x_decoder = [0]*len(target_sequence_length)
        y = [random.random() for _ in range(target_sequence_length)]
        X_encoder.append(x_encoder)
        # Not really optimal but will work
        X_decoder.append(x_decoder)
        Y.append(y)

        # Make them as numpy arrays
        X_encoder = np.array(X_encoder)
        X_decoder = np.array(X_decoder)
        Y = np.array(Y)

        # Make them 3 dimensional arrays (with third dimension being of size 1) like the 1d vector: [1,2] can become 2 de vector [[1,2]]
        X_encoder = np.expand_dims(X_encoder, axis=2)
        X_decoder = np.expand_dims(X_decoder, axis=2)
        Y = np.expand_dims(Y, axis=2)

    return [X_encoder, X_decoder], Y
相关问题