具有多种特征的 RNN

数据挖掘 机器学习 神经网络 喀拉斯
2021-10-09 21:41:46

我有一些使用机器学习算法(基本的随机森林和线性回归类型的东西)的自学知识。我决定扩展并开始使用 Keras 学习 RNN。在查看通常涉及股票预测的大多数示例时,除了 1 列是功能日期而另一列是输出之外,我找不到任何正在实现的多个功能的基本示例。我是否缺少关键的基本知识或其他东西?

如果有人有一个例子,我将不胜感激。

谢谢!

1个回答

循环神经网络 (RNN) 旨在学习序列数据。正如您所猜测的,它们绝对可以将多个特征作为输入!Keras 的 RNN 采用时间步T和特征F的 2D 输入( TF ) (我在这里忽略了批量维度)。

但是,您并不总是需要或想要中间时间步长t = 1, 2 ... ( T - 1)。因此,Keras 灵活地支持这两种模式。要让它输出所有T个时间步,请在构建时传递return_sequences=True给您的 RNN(例如,LSTMGRU)。如果您只想要最后一个时间步t = T,则使用return_sequences=False(如果您不传递return_sequences给构造函数,这是默认设置)。

以下是这两种模式的示例。

示例 1:学习序列

这是一个训练 LSTM(RNN 类型)的快速示例,它可以保持整个序列。在这个例子中,每个输入数据点有 2 个时间步长,每个时间步长有 3 个特征;输出数据有 2 个时间步长(因为return_sequences=True),每个时间步长有 4 个数据点(因为这是我传递给的大小LSTM)。

import keras.layers as L
import keras.models as M

import numpy

# The inputs to the model.
# We will create two data points, just for the example.
data_x = numpy.array([
    # Datapoint 1
    [
        # Input features at timestep 1
        [1, 2, 3],
        # Input features at timestep 2
        [4, 5, 6]
    ],
    # Datapoint 2
    [
        # Features at timestep 1
        [7, 8, 9],
        # Features at timestep 2
        [10, 11, 12]
    ]
])

# The desired model outputs.
# We will create two data points, just for the example.
data_y = numpy.array([
    # Datapoint 1
    [
        # Target features at timestep 1
        [101, 102, 103, 104],
        # Target features at timestep 2
        [105, 106, 107, 108]
    ],
    # Datapoint 2
    [
        # Target features at timestep 1
        [201, 202, 203, 204],
        # Target features at timestep 2
        [205, 206, 207, 208]
    ]
])

# Each input data point has 2 timesteps, each with 3 features.
# So the input shape (excluding batch_size) is (2, 3), which
# matches the shape of each data point in data_x above.
model_input = L.Input(shape=(2, 3))

# This RNN will return timesteps with 4 features each.
# Because return_sequences=True, it will output 2 timesteps, each
# with 4 features. So the output shape (excluding batch size) is
# (2, 4), which matches the shape of each data point in data_y above.
model_output = L.LSTM(4, return_sequences=True)(model_input)

# Create the model.
model = M.Model(input=model_input, output=model_output)

# You need to pick appropriate loss/optimizers for your problem.
# I'm just using these to make the example compile.
model.compile('sgd', 'mean_squared_error')

# Train
model.fit(data_x, data_y)

示例 2:学习最后一个时间步

另一方面,如果你想训练一个只输出序列中最后一个时间步长的 LSTM,那么你需要设置return_sequences=False(或者只是将它从构造函数中完全删除,因为False这是默认设置)。然后您的输出数据(data_y在上面的示例中)需要重新排列,因为您只需要提供最后一个时间步。所以在第二个例子中,每个输入数据点仍然有 2 个时间步长,每个时间步长有 3 个特征。然而,输出数据只是每个数据点的单个向量,因为我们已将所有内容扁平化为单个时间步长。但是,这些输出向量中的每一个仍然具有 4 个特征(因为这是我传递给的大小LSTM)。

import keras.layers as L
import keras.models as M

import numpy

# The inputs to the model.
# We will create two data points, just for the example.
data_x = numpy.array([
    # Datapoint 1
    [
        # Input features at timestep 1
        [1, 2, 3],
        # Input features at timestep 2
        [4, 5, 6]
    ],
    # Datapoint 2
    [
        # Features at timestep 1
        [7, 8, 9],
        # Features at timestep 2
        [10, 11, 12]
    ]
])

# The desired model outputs.
# We will create two data points, just for the example.
data_y = numpy.array([
    # Datapoint 1
    # Target features at timestep 2
    [105, 106, 107, 108],
    # Datapoint 2
    # Target features at timestep 2
    [205, 206, 207, 208]
])

# Each input data point has 2 timesteps, each with 3 features.
# So the input shape (excluding batch_size) is (2, 3), which
# matches the shape of each data point in data_x above.
model_input = L.Input(shape=(2, 3))

# This RNN will return timesteps with 4 features each.
# Because return_sequences=False, it will output 2 timesteps, each
# with 4 features. So the output shape (excluding batch size) is
# (2, 4), which matches the shape of each data point in data_y above.
model_output = L.LSTM(4, return_sequences=False)(model_input)

# Create the model.
model = M.Model(input=model_input, output=model_output)

# You need to pick appropriate loss/optimizers for your problem.
# I'm just using these to make the example compile.
model.compile('sgd', 'mean_squared_error')

# Train
model.fit(data_x, data_y)