Python Keras:掩蔽和展平

Python Keras:掩蔽和展平,python,python-3.x,tensorflow,keras,deep-learning,Python,Python 3.x,Tensorflow,Keras,Deep Learning,我很难建立一个简单的模型来处理隐藏的输入值。我的训练数据由GPS轨迹的可变长度列表组成,即每个元素包含纬度和经度的列表 共有70个培训示例 因为它们的长度可变,所以我用零填充它们,目的是告诉Keras忽略这些零值 train_data = keras.preprocessing.sequence.pad_sequences(train_data, maxlen=max_sequence_len, dtype='float32',

我很难建立一个简单的模型来处理隐藏的输入值。我的训练数据由GPS轨迹的可变长度列表组成,即每个元素包含纬度和经度的列表

共有70个培训示例

因为它们的长度可变,所以我用零填充它们,目的是告诉Keras忽略这些零值

train_data = keras.preprocessing.sequence.pad_sequences(train_data, maxlen=max_sequence_len, dtype='float32', 
                                           padding='pre', truncating='pre', value=0)

然后我建立了一个非常基本的模型

model = Sequential()
model.add(Dense(16, activation='relu',input_shape=(max_sequence_len, 2)))
model.add(Flatten())
model.add(Dense(2, activation='sigmoid'))
在之前的一些尝试和错误之后,我意识到我需要
展平
层,否则拟合模型会抛出错误

ValueError: Error when checking target: expected dense_87 to have 3 dimensions, but got array with shape (70, 2)
但是,通过包含此
展平
层,我不能使用
掩蔽
层(忽略填充的零)或Keras抛出此错误

TypeError: Layer flatten_31 does not support masking, but was passed an input_mask: Tensor("masking_9/Any_1:0", shape=(?, 48278), dtype=bool)

我已经进行了广泛的搜索,在这里阅读了GitHub的问题和大量的Q/A,但我无法找到答案

屏蔽似乎确实被窃听了。但不要担心:0不会让你的模型变得更糟;至多效率较低

我建议使用卷积方法,而不是纯稠密或RNN。我认为这将非常适合GPS数据

请尝试以下代码:

from keras.preprocessing.sequence import pad_sequences
from keras import Sequential
from keras.layers import Dense, Flatten, Masking, LSTM, GRU, Conv1D, Dropout, MaxPooling1D
import numpy as np
import random

max_sequence_len = 70

n_samples = 100
num_coordinates = 2 # lat/long

data = [[[random.random() for _ in range(num_coordinates)]
         for y in range(min(x, max_sequence_len))]
        for x in range(n_samples)]

train_y = np.random.random((n_samples, 2))

train_data = pad_sequences(data, maxlen=max_sequence_len, dtype='float32',
                           padding='pre', truncating='pre', value=0)

model = Sequential()
model.add(Conv1D(32, (5, ), input_shape=(max_sequence_len, num_coordinates)))
model.add(Dropout(0.5))
model.add(MaxPooling1D())
model.add(Flatten())
model.add(Dense(2, activation='relu'))
model.compile(loss='mean_squared_error', optimizer="adam")
model.fit(train_data, train_y)

您可以使用全局池层,而不是使用
展平

这些适用于折叠长度/时间维度,而不丧失使用可变长度的能力

因此,您可以尝试使用
globalAveragePoolg1d
globalExpooling1d
而不是
flatte()

它们中没有一个在代码中使用
支持_掩蔽
,因此必须小心使用

平均值将考虑比最大值更多的输入(因此应该屏蔽的值)。p> 最大值将从长度中仅取一个。幸运的是,如果您所有的有用值都高于处于遮罩位置的值,它将间接保留遮罩。它可能需要比另一个更多的输入神经元

也就是说,是的,请尝试建议的
Conv1D
或RNN(
LSTM
)方法


使用掩码创建自定义池层 您还可以创建自己的池层(需要一个函数式API模型,在该模型中,您可以传递模型的输入和要池的张量)

下面是一个基于输入应用掩码的平均池的工作示例:

def customPooling(maskVal):
    def innerFunc(x):
        inputs = x[0]
        target = x[1]

        #getting the mask by observing the model's inputs
        mask = K.equal(inputs, maskVal)
        mask = K.all(mask, axis=-1, keepdims=True)

        #inverting the mask for getting the valid steps for each sample
        mask = 1 - K.cast(mask, K.floatx())

        #summing the valid steps for each sample
        stepsPerSample = K.sum(mask, axis=1, keepdims=False)

        #applying the mask to the target (to make sure you are summing zeros below)
        target = target * mask

        #calculating the mean of the steps (using our sum of valid steps as averager)
        means = K.sum(target, axis=1, keepdims=False) / stepsPerSample

        return means

    return innerFunc


x = np.ones((2,5,3))
x[0,3:] = 0.
x[1,1:] = 0.


print(x)

inputs = Input((5,3))
out = Lambda(lambda x: x*4)(inputs)
out = Lambda(customPooling(0))([inputs,out])

model = Model(inputs,out)
model.predict(x)

谢谢你的例子。不幸的是,这并没有提高我的准确性,但这很可能是我的数据中的一个错误。我注意到我的
max\u sequence\u len
(198720)和
min\u sequence\u len
(3!!)之间存在巨大差异,因此这显然是一个错误problem@PhilipO布莱恩:不用担心,可以理解!我建议只取序列的前几个部分,最后,比如说,200个部分。还包括序列长度的数字。那应该有帮助!谢谢你的解释。确实很难决定奖励哪一个答案,但我觉得PascalVKooten只是在直接适用于我的问题方面掩盖了它。