【问题标题】:Keras input value errorKeras输入值错误
【发布时间】:2018-09-15 00:15:09
【问题描述】:

我有张量形式的心电图数据(样本、时间步长、特征),例如(2464,15000,1)。

我的目标是对 1 到 5 范围内的标签进行分类。我对目标进行了热编码,使其具有尺寸 (2464,5)。

在开始使用 LSTM 之前,我想尝试一种基本方法。使用以下顺序模型:

 def build_model():  
        model = models.Sequential()                 
        model.add(layers.Dense(16, activation='relu',input_shape=(X_train.shape[1],X_train.shape[2]))) 
        model.add(layers.Dense(16, activation='relu'))           
        model.add(layers.Dense(y_train.shape[1], activation='softmax'))

        model.compile(loss='sparse_categorical_crossentropy',
                       optimizer='rmsprop',
                       metrics=['mae'])
        return model

    model=build_model()
    history=model.fit(X_train,
                      y_train,
                      epochs=20,
                      batch_size=512,
                      validation_data=(X_val,y_val))

不幸的是,我得到一个值错误:

文件 "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", 第 113 行,在 _standardize_input_data '带形状' + str(data_shape))

ValueError:检查目标时出错:预期 dense_13 有 3 尺寸,但得到了形状为 (2464, 5) 的数组

我搜索了其他有问题的主题。大多数情况下,输出层不符合预期目标,在我的情况下为 5。所以这应该是正确的。另一个问题通常是目标不是一个热编码的。但这也完成了。错误告诉我有三个维度(基于输入?)。但是,如果我添加一个维度以获得 (2464,5,1) 的目标维度,ValueError 会发生变化,期望与输入数据具有相同的维度,而我必须使用 softmax 层将其减少到 y 目标。

ValueError: 检查目标时出错:预期 dense_23 的形状为 (15000, 1) 但得到的数组的形状为 (5, 1)

我很困惑。能给我一个提示吗?

额外:我也尝试展平输入,但也得到了一个(不同的)ValueError(...形状(1,)但得到了形状为(5,)的数组)。这里的扁平化是正确的方法吗?

感谢您的帮助。

【问题讨论】:

    标签: python keras time-series


    【解决方案1】:

    这里的问题实际上是你的损失函数。由于您已经有 1-hot 编码的 y 向量,因此您不应该使用稀疏分类交叉熵,而应该使用分类交叉熵。试试这个

    分类交叉熵

    为了维度,我们只做一些虚拟数据。

    X_train = np.zeros((2464, 150, 1))
    y_train = np.zeros((2464,))
    
    X_val = np.zeros((2464, 150, 1))
    y_val = np.zeros((2464,))
    
    X_train_r = X_train.reshape(2464,150,)
    X_val_r = X_val.reshape(2464,150,)
    input_shape = (150,)
    
    print(X_train_r.shape)
    print(X_val_r.shape)
    

    (2464, 150)
    (2464, 150)

    现在我们将为标签获取一个热编码输出。

    num_classes = 5
    # Convert class vectors to binary class matrices. This uses 1 hot encoding.
    y_train_binary = keras.utils.to_categorical(y_train, num_classes)
    y_val_binary = keras.utils.to_categorical(y_val, num_classes)
    
    print(y_train_binary.shape)
    print(y_val_binary.shape)
    

    (2464, 5)
    (2464, 5)

    现在我们将制作我们的模型如下

    model = Sequential()                 
    model.add(Dense(16, activation='relu',input_shape=input_shape)) 
    model.add(Dense(16, activation='relu'))           
    model.add(Dense(num_classes, activation='softmax'))
    
    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer=keras.optimizers.Adadelta(),
                  metrics=['accuracy'])
    
    model.summary()
    
    history=model.fit(X_train_r,
                      y_train_binary,
                      epochs=5,
                      batch_size=8,
                      validation_data=(X_val_r, y_val_binary))
    

    这对你有用。

    稀疏分类交叉熵

    如果您想使用稀疏分类交叉熵,则不应使用 1-hot 编码标签。像这样

    X_train = np.zeros((2464, 150, 1))
    y_train = np.zeros((2464,))
    
    X_val = np.zeros((2464, 150, 1))
    y_val = np.zeros((2464,))
    
    X_train_r = X_train.reshape(2464,150,)
    X_val_r = X_val.reshape(2464,150,)
    input_shape = (150,)
    
    num_classes = 5
    
    model = Sequential()                 
    model.add(Dense(16, activation='relu',input_shape=input_shape)) 
    model.add(Dense(16, activation='relu'))           
    model.add(Dense(num_classes, activation='softmax'))
    
    model.compile(loss='sparse_categorical_crossentropy',
                           optimizer='rmsprop',
                           metrics=['mae'])
    
    model.summary()
    
    history=model.fit(X_train_r,
                      y_train,
                      epochs=5,
                      batch_size=8,
                      validation_data=(X_val_r, y_val))
    

    【讨论】:

    • 感谢您的回答。我只是好奇。我总是需要渠道维度吗?因为我正在处理时间序列数据,它只是一个 3D 张量。 Keras 没有检测到这一点吗?所以如果我理解正确,我只会在后面添加一个 1 的“假”通道。从 3D 张量中创建 4d 张量。
    • 或者是我选择的这种模型方法不适合时间序列。如果我只想使用这种经典的密集层方法,是否必须展平输入数据?谢谢
    • 您能否分享一小部分数据,以便我了解如何正确塑造它?
    • 是的,这只是输出的问题。它不受输入的影响。您的损失函数看不到您的输入,只有输出。所以你需要选择一个与输出大小兼容的损失函数。
    • 你是最棒的。感谢您的所有时间和努力。祝你生活愉快。
    猜你喜欢
    • 2018-09-18
    • 2019-05-07
    • 2017-10-15
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 2018-08-15
    相关资源
    最近更新 更多