如何为Keras中Wavenet的实现准备输入以进行时间序列预测

4
在Keras实现的Wavenet中,输入形状为(None,1)。我有一个时间序列(val(t)),其中目标是在给定过去值窗口的情况下预测下一个数据点(窗口大小取决于最大膨胀)。 Wavenet中的输入形状很困惑。 我对此有一些问题:
  1. 当给出完整序列时,Keras如何确定输入维度(None)?根据膨胀,我们希望输入长度为2^8。
  2. 如果将形状为(1M,1)的输入序列作为训练X提供,是否需要生成2 ^ 8个时间步的向量作为输入? 似乎我们可以直接使用输入序列作为wavenet的输入(不确定为什么原始时间序列输入不会出现错误)。
  3. 通常情况下,我们如何调试这样的Keras网络。 我尝试在数值数据上应用函数,如Conv1D(16,1,padding ='same',activation ='relu')(inputs),但是它报错了。

#

n_filters = 32
filter_width = 2
dilation_rates = [2**i for i in range(7)] * 2 

from keras.models import Model
from keras.layers import Input, Conv1D, Dense, Activation, Dropout, Lambda, Multiply, Add, Concatenate
from keras.optimizers import Adam

history_seq = Input(shape=(None, 1))
x = history_seq

skips = []
for dilation_rate in dilation_rates:

    # preprocessing - equivalent to time-distributed dense
    x = Conv1D(16, 1, padding='same', activation='relu')(x) 

    # filter
    x_f = Conv1D(filters=n_filters,
                 kernel_size=filter_width, 
                 padding='causal',
                 dilation_rate=dilation_rate)(x)

    # gate
    x_g = Conv1D(filters=n_filters,
                 kernel_size=filter_width, 
                 padding='causal',
                 dilation_rate=dilation_rate)(x)

    # combine filter and gating branches
    z = Multiply()([Activation('tanh')(x_f),
                    Activation('sigmoid')(x_g)])

    # postprocessing - equivalent to time-distributed dense
    z = Conv1D(16, 1, padding='same', activation='relu')(z)

    # residual connection
    x = Add()([x, z])    

    # collect skip connections
    skips.append(z)

# add all skip connection outputs 
out = Activation('relu')(Add()(skips))

# final time-distributed dense layers 
out = Conv1D(128, 1, padding='same')(out)
out = Activation('relu')(out)
out = Dropout(.2)(out)
out = Conv1D(1, 1, padding='same')(out)

# extract training target at end
def slice(x, seq_length):
    return x[:,-seq_length:,:]

pred_seq_train = Lambda(slice, arguments={'seq_length':1})(out)

model = Model(history_seq, pred_seq_train)
model.compile(Adam(), loss='mean_absolute_error')

1
你正在使用非常大的膨胀率,我建议你将它们减小。在第三步中,你遇到了哪个错误? - Marco Cerliani
在第三步中) ValueError: 意外地发现了一个类型为<class 'numpy.ndarray'>的实例。预期是一个符号张量实例。 - Roy
1
我在第三步没有问题,我尝试将该模型应用于数字数据,没有问题...如果您感兴趣,我可以为您提供示例。 - Marco Cerliani
是的,那会很有帮助。 - Roy
1个回答

5
你正在使用极端的膨胀速率,这些值没有意义。尝试使用例如 [1, 2, 4, 8, 16, 32] 的序列来减少它们。膨胀速率不是传递输入的维度的限制。
你的网络只是简单地传递这个输入。
n_filters = 32
filter_width = 2
dilation_rates = [1, 2, 4, 8, 16, 32]

....

model = Model(history_seq, pred_seq_train)
model.compile(Adam(), loss='mean_absolute_error')

n_sample = 5
time_step = 100

X = np.random.uniform(0,1, (n_sample,time_step,1))

model.predict(X)

在Keras中指定一个无维度意味着模型可以接收任何维度的输入。但这并不意味着你可以传递具有不同维度的样本,它们始终必须具有相同的格式...你可以每次使用不同的维度大小构建模型。
for time_step in np.random.randint(100,200, 4):

  print('temporal dim:', time_step)
  n_sample = 5

  model = Model(history_seq, pred_seq_train)
  model.compile(Adam(), loss='mean_absolute_error')

  X = np.random.uniform(0,1, (n_sample,time_step,1))

  print(model.predict(X).shape)

我建议您在Keras中使用预制库,提供WAVENET实现: https://github.com/philipperemy/keras-tcn 您可以将其用作基线,并调查创建WAVENET的代码


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接