python - 多特征因果CNN——Keras实现

标签 python keras deep-learning conv-neural-network lstm

我目前正在使用基本的 LSTM 进行回归预测,我想实现因果 CNN,因为它在计算上应该更高效。

我正在努力弄清楚如何 reshape 我当前的数据以适应因果 CNN 单元并表示相同的数据/时间步长关系以及应该设置的扩张率。

我当前的数据是这样的:(示例数量、回溯、特征),这是我现在正在使用的 LSTM NN 的一个基本示例。

lookback = 20   #  height -- timeseries
n_features = 5  #  width  -- features at each timestep

# Build an LSTM to perform regression on time series input/output data
model = Sequential()
model.add(LSTM(units=256, return_sequences=True, input_shape=(lookback, n_features)))
model.add(Activation('elu'))

model.add(LSTM(units=256, return_sequences=True))
model.add(Activation('elu'))

model.add(LSTM(units=256))
model.add(Activation('elu'))

model.add(Dense(units=1, activation='linear'))

model.compile(optimizer='adam', loss='mean_squared_error')

model.fit(X_train, y_train,
          epochs=50, batch_size=64,
          validation_data=(X_val, y_val),
          verbose=1, shuffle=True)

prediction = model.predict(X_test)

然后我创建了一个新的 CNN 模型(虽然不是因果关系,因为 'causal' 填充只是 Conv1D 的一个选项,而不是 Conv2D ,根据 Keras 文档。如果我理解正确,通过具有多个功能,我需要使用 Conv2D,而不是 Conv1D 但是如果我设置 Conv2D(padding= 'causal'),我收到以下错误 - Invalid padding: causal)

无论如何,我还能够使用新形状(示例数量、回溯、特征,1) 来拟合数据,并使用 Conv2D 运行以下模型图层:

lookback = 20   #  height -- timeseries
n_features = 5  #  width  -- features at each timestep

 model = Sequential()
            model.add(Conv2D(128, 3, activation='elu', input_shape=(lookback, n_features, 1)))
model.add(MaxPool2D())
model.add(Conv2D(128, 3, activation='elu'))
model.add(MaxPool2D())
model.add(Flatten())
model.add(Dense(1, activation='linear'))

model.compile(optimizer='adam', loss='mean_squared_error')

model.fit(X_train, y_train,
          epochs=50, batch_size=64,
          validation_data=(X_val, y_val),
          verbose=1, shuffle=True)

prediction = model.predict(X_test)

但是,根据我的理解,这不会将数据传播为因果关系,而只是将整个集合 (lookback, features, 1) 作为图像传播。

有什么方法可以 reshape 我的数据以适应具有多个特征的 Conv1D(padding='causal') 层,或者以某种方式运行与 Conv2D 相同的数据和输入形状 使用 'causal' 填充?

最佳答案

我相信您可以对任意数量的输入特征进行因果填充膨胀。这是我建议的解决方案。

TimeDistributed layer是关键。

来自 Keras 文档:“此包装器将一层应用于输入的每个时间切片。输入应至少为 3D,索引一的维度将被视为时间维度。”

出于我们的目的,我们希望该层对每个特征应用“某物”,因此我们将特征移至时间索引,即 1。

同样相关的是 Conv1D documentation .

特别是关于 channel :“输入中维度的排序。“channels_last”对应于具有形状(批处理、步骤、 channel )的输入(Keras 中时间数据的默认格式)”

from tensorflow.python.keras import Sequential, backend
from tensorflow.python.keras.layers import GlobalMaxPool1D, Activation, MaxPool1D, Flatten, Conv1D, Reshape, TimeDistributed, InputLayer

backend.clear_session()
lookback = 20
n_features = 5

filters = 128

model = Sequential()
model.add(InputLayer(input_shape=(lookback, n_features, 1)))
# Causal layers are first applied to the features independently
model.add(Permute(dims=(2, 1)))  # UPDATE must permute prior to adding new dim and reshap
model.add(Reshape(target_shape=(n_features, lookback, 1)))
# After reshape 5 input features are now treated as the temporal layer 
# for the TimeDistributed layer

# When Conv1D is applied to each input feature, it thinks the shape of the layer is (20, 1)
# with the default "channels_last", therefore...

# 20 times steps is the temporal dimension
# 1 is the "channel", the new location for the feature maps

model.add(TimeDistributed(Conv1D(filters, 3, activation="elu", padding="causal", dilation_rate=2**0)))
# You could add pooling here if you want. 
# If you want interaction between features AND causal/dilation, then apply later
model.add(TimeDistributed(Conv1D(filters, 3, activation="elu", padding="causal", dilation_rate=2**1)))
model.add(TimeDistributed(Conv1D(filters, 3, activation="elu", padding="causal", dilation_rate=2**2)))


# Stack feature maps on top of each other so each time step can look at 
# all features produce earlier
model.add(Permute(dims=(2, 1, 3)))  # UPDATED to fix issue with reshape
model.add(Reshape(target_shape=(lookback, n_features * filters)))  # (20 time steps, 5 features * 128 filters)
# Causal layers are applied to the 5 input features dependently
model.add(Conv1D(filters, 3, activation="elu", padding="causal", dilation_rate=2**0))
model.add(MaxPool1D())
model.add(Conv1D(filters, 3, activation="elu", padding="causal", dilation_rate=2**1))
model.add(MaxPool1D())
model.add(Conv1D(filters, 3, activation="elu", padding="causal", dilation_rate=2**2))
model.add(GlobalMaxPool1D())
model.add(Dense(units=1, activation='linear'))

model.compile(optimizer='adam', loss='mean_squared_error')

model.summary()

最终模型总结

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
reshape (Reshape)            (None, 5, 20, 1)          0         
_________________________________________________________________
time_distributed (TimeDistri (None, 5, 20, 128)        512       
_________________________________________________________________
time_distributed_1 (TimeDist (None, 5, 20, 128)        49280     
_________________________________________________________________
time_distributed_2 (TimeDist (None, 5, 20, 128)        49280     
_________________________________________________________________
reshape_1 (Reshape)          (None, 20, 640)           0         
_________________________________________________________________
conv1d_3 (Conv1D)            (None, 20, 128)           245888    
_________________________________________________________________
max_pooling1d (MaxPooling1D) (None, 10, 128)           0         
_________________________________________________________________
conv1d_4 (Conv1D)            (None, 10, 128)           49280     
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 5, 128)            0         
_________________________________________________________________
conv1d_5 (Conv1D)            (None, 5, 128)            49280     
_________________________________________________________________
global_max_pooling1d (Global (None, 128)               0         
_________________________________________________________________
dense (Dense)                (None, 1)                 129       
=================================================================
Total params: 443,649
Trainable params: 443,649
Non-trainable params: 0
_________________________________________________________________

编辑:

“为什么需要 reshape 并使用 n_features 作为时间层”

n_features 最初需要位于时间层的原因是因为具有扩张和因果填充的 Conv1D 一次只能处理一个特征,并且因为 TimeDistributed 层的实现方式。

来自他们的文档 “考虑一批 32 个样本,其中每个样本是 10 个 16 维向量的序列。层的批输入形状是 (32, 10, 16),并且 input_shape ,不包括样本维度,是 (10, 16)。

然后您可以使用 TimeDistributed 将 Dense 层独立地应用到 10 个时间步中的每一个:“

通过将 TimeDistributed 层独立应用于每个特征,它减少了问题的维度,就好像只有一个特征(这很容易允许膨胀和因果填充)。有 5 个特征,首先需要分别处理它们。

  • 在您进行修改后,此建议仍然适用。

  • 无论 InputLayer 包含在第一层中还是单独包含在网络方面,都不应该有区别,因此如果可以解决问题,您绝对可以将其放在第一个 CNN 中。

关于python - 多特征因果CNN——Keras实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55850797/

相关文章:

Python 在 IDLE 中播放声音,但在 Thonny 中给出 "no module called gi"错误; Ubuntu 终端中的混合结果

python - 对子文档 python Bottle 进行排序

python - 使用 ImageDataGenerator 和 flow_from_directory 时,Keras 中的数据增强是否应用于验证集

python - 使用 TENSORFLOW 进行多标签分类---COST 和 Weights 中的 NaN

python - 映射和合并来自另一个数据框的值

Python 正则表达式间距

python-3.x - keras 的 lstm 模型的训练和评估精度不同

python - 使用 Python 使用 Keras 进行深度学习的介绍部分

python - Keras LSTM input_shape : expected lstm_1_input to have shape (500, 2) 出现问题,但得到形状为 (500, 5) 的数组

python - 在无法访问模型类代码的情况下保存 PyTorch 模型