【问题标题】:Q: ValueError Keras expected conv2d_14_input to have shape (3, 12, 1) but got array with shape (3, 12, 6500)?问:ValueError Keras 期望 conv2d_14_input 的形状为 (3, 12, 1) 但得到的数组的形状为 (3, 12, 6500)?
【发布时间】:2020-12-20 13:49:17
【问题描述】:

我正在 Window 10 上的 Keras 2.1.0 中为非图像数据构建一个 CNN。

我的输入特征是一个 3x12 的非负数矩阵,我的输出是一个长度为 6x1 的二进制多标签向量

我遇到了这个错误预计 conv2d_14_input 的形状为 (3, 12, 1) 但得到的数组的形状为 (3, 12, 6500)

下面是我的代码

import tensorflow as tf
from scipy.io import loadmat
import numpy as np
from tensorflow.keras.layers import BatchNormalization
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout
from tensorflow.keras.layers import Conv2D, MaxPool2D, Flatten


reshape_channel_train = loadmat('reshape_channel_train')
reshape_channel_test = loadmat('reshape_channel_test.mat')
reshape_label_train = loadmat('reshape_label_train')
reshape_label_test = loadmat('reshape_label_test')

X_train = reshape_channel_train['store_train']
X_test = reshape_channel_test['store_test']

X_train = np.expand_dims(X_train,axis = 0)
X_test  = np.expand_dims(X_test, axis = 0)

Y_train = reshape_label_train['label_train']
Y_test = reshape_label_test['label_test']

classifier = Sequential()
classifier.add(Conv2D(8, kernel_size=(3,3) , input_shape=(3, 12, 1), padding="same"))
classifier.add(BatchNormalization())
classifier.add(Activation('relu'))

classifier.add(Conv2D(8, kernel_size=(3,3), input_shape=(3, 12, 1), padding="same"))
classifier.add(BatchNormalization())
classifier.add(Activation('relu'))

classifier.add(Flatten())
classifier.add(Dense(8, activation='relu'))
classifier.add(Dense(6, activation='sigmoid'))
classifier.compile(optimizer='nadam', loss='binary_crossentropy', metrics=['accuracy'])

history = classifier.fit(X_train, Y_train, batch_size = 32, epochs=100,
                         validation_data=(X_test, Y_test), verbose=2)

经过一番搜索,我使用了维度扩展技巧,但似乎不起作用

X_train = np.expand_dims(X_train,axis = 0)
X_test  = np.expand_dims(X_test, axis = 0)

包含 6500 个训练实例的 X_train 变量是从尺寸为 3x12x6500 的 Matlab .mat 文件加载的。

每个训练实例都是一个 3x12 矩阵。

使用 expand_dim 技巧之前,第 k 个训练样本可以由 X_train[:,:,k] 和 X_train[:,:,k] 调用.shape 将返回 (3,12)。 X_train.shape 也会返回 (3, 12, 6500)

之后使用 expand_dim 技巧命令 X_train[:,:,k].shape 将返回 (1, 3, 6500)

请帮帮我! 谢谢

【问题讨论】:

    标签: keras multidimensional-array numpy-ndarray conv-neural-network numpy-slicing


    【解决方案1】:

    您错误地管理数据。 Conv2D 层接受 (n_sample, height, width, channels) 这种格式的数据,在您的情况下(对于您的 X_train)变成 (6500,3,12,1)。你需要简单地重新处理这个案例

    # create data as in your matlab data
    n_class = 6
    n_sample = 6500
    X_train = np.random.uniform(0,1, (3,12,n_sample)) # (3,12,n_sample)
    Y_train = tf.keras.utils.to_categorical(np.random.randint(0,n_class, n_sample)) # (n_sample, n_classes)
    
    # reshape your data for conv2d
    X_train = X_train.transpose(2,0,1) # (n_sample,3,12)
    X_train = np.expand_dims(X_train, -1) # (n_sample,3,12,1)
    
    classifier = Sequential()
    classifier.add(Conv2D(8, kernel_size=(3,3) , input_shape=(3, 12, 1), padding="same"))
    classifier.add(BatchNormalization())
    classifier.add(Activation('relu'))
    
    classifier.add(Conv2D(8, kernel_size=(3,3), padding="same"))
    classifier.add(BatchNormalization())
    classifier.add(Activation('relu'))
    
    classifier.add(Flatten())
    classifier.add(Dense(8, activation='relu'))
    classifier.add(Dense(n_class, activation='softmax'))
    classifier.compile(optimizer='nadam', loss='categorical_crossentropy', metrics=['accuracy'])
    
    history = classifier.fit(X_train, Y_train, batch_size = 32, epochs=2, verbose=2)
    
    # get predictions
    pred = np.argmax(classifier.predict(X_train), 1)
    

    我还使用带有categorical_crossentropysoftmax 激活,它更适合多类问题,但您也可以修改它。记得对您的测试数据应用相同的数据处理

    【讨论】:

    • 哦,非常感谢,其实我的问题是多标签而不是多类。但这是否意味着我应该准备我的数据集,以便表格应该是 6500x3x12(正确)而不是 3x12x6500(错误)?
    • ok 多类或多标签无关紧要(您可以相应地修改网络)。是的,您的数据必须是(6500x3x12x1)...记得像我在代码中所做的那样添加最后一个维度并展开暗淡...不要忘记投票并接受它;-)
    【解决方案2】:

    你需要传递 data_format="channels_last" 参数,因为你的频道最后

    你试试这个:

    x_train=x_train.reshape((6500,3,12,1))
    x_test=x_test.reshape((-1,3,12,1))
    
    
    and in each of conv2d layer conv2D(<other args>, data_format="channels_last")
    

    【讨论】:

      猜你喜欢
      • 2019-03-11
      • 2018-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多