【问题标题】:ValueError: Error when checking target: expected conv2d_19 to have shape (None, 320, 320, 1) but got array with shape (18, 320, 320, 2)ValueError:检查目标时出错:预期 conv2d_19 的形状为 (None, 320, 320, 1) 但得到的数组的形状为 (18, 320, 320, 2)
【发布时间】:2020-01-07 12:17:31
【问题描述】:

我尝试在 keras 中使用常规分割(不是多类)训练 U-Net 模型,但出现以下错误:

ValueError: 检查目标时出错:预期 conv2d_19 的形状为 (None, 320, 320, 1) 但得到的数组的形状为 (18, 320, 320, 2)

我知道这与输入 Y_train 有关,我与 keras.utils.to_categorical 函数有关,但 to_categorical(Y_train) 和 to_categorical(Y_train, 2) 返回此错误,而 to_categorical(Y_train, 1) 返回 IndexError:对于大小为 1 的轴 1,索引 1 超出范围。

我什至试图通过将 Y_train 重塑为 (None, 320, 320, 1) 来更改它,但它返回了

'ValueError: 您正在传递一个形状为 (18, 320, 320, 1) 的目标数组,同时用作损失分类交叉熵。 categorical_crossentropy 期望目标是形状(样本、类)的二进制矩阵(1 和 0)。如果您的目标是整数类,您可以通过以下方式将它们转换为预期格式: 从 keras.utils 导入 to_categorical y_binary = to_categorical(y_int) 或者,您可以改用损失函数sparse_categorical_crossentropy,它确实需要整数目标。'

当我尝试使用训练函数拟合模型时返回错误。

    def preprocess_images(X_train, Y_train, X_test, Y_test):

        X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], X_train.shape[2], 1)
        X_test = X_test.reshape(X_test.shape[0], X_train.shape[1], X_train.shape[2], 1)

        X_train = X_train.astype("float32")
        X_test = X_test.astype("float32")
        X_train /= 255
        X_test /= 255

        Y_train /= 255
        Y_test /= 255
        #Y_train = Y_train.reshape(Y_train.shape[0], Y_train.shape[1], Y_train.shape[2], 1)
        #Y_test = Y_test.reshape(Y_test.shape[0], Y_train.shape[1], Y_train.shape[2], 1)
        Y_train = keras.utils.to_categorical(Y_train, 1)
        Y_test = keras.utils.to_categorical(Y_test, 1)

        return ((X_train, Y_train), (X_test, Y_test))


    def CNNs_layers(nb_conv_pool = 1, filters = 32, kernel_size = (3, 3), activation = 'relu', pool_size = (2 ,2), dropout_rate = 0.25, input_shape = (28, 28, 1), data_format = 'channels_last'):


        inputs = tf.keras.layers.Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))
        s = tf.keras.layers.Lambda(lambda x: x / 255)(inputs)

        c1 = tf.keras.layers.Conv2D(16, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(s)
        c1 = tf.keras.layers.Dropout(0.1)(c1)
        c1 = tf.keras.layers.Conv2D(16, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(c1)
        p1 = tf.keras.layers.MaxPooling2D((2, 2))(c1)

        c2 = tf.keras.layers.Conv2D(32, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(p1)
        c2 = tf.keras.layers.Dropout(0.1)(c2)
        c2 = tf.keras.layers.Conv2D(32, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(c2)
        p2 = tf.keras.layers.MaxPooling2D((2, 2))(c2)

        c3 = tf.keras.layers.Conv2D(64, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(p2)
        c3 = tf.keras.layers.Dropout(0.2)(c3)
        c3 = tf.keras.layers.Conv2D(64, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(c3)

        p3 = tf.keras.layers.MaxPooling2D((2, 2))(c3)

        c4 = tf.keras.layers.Conv2D(128, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(p3)
        c4 = tf.keras.layers.Dropout(0.2)(c4)
        c4 = tf.keras.layers.Conv2D(128, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(c4)
        p4 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(c4)

        c5 = tf.keras.layers.Conv2D(256, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(p4)
        c5 = tf.keras.layers.Dropout(0.3)(c5)
        c5 = tf.keras.layers.Conv2D(256, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(c5)

        u6 = tf.keras.layers.Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(c5)
        u6 = tf.keras.layers.concatenate([u6, c4])
        c6 = tf.keras.layers.Conv2D(128, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(u6)
        c6 = tf.keras.layers.Dropout(0.2)(c6)
        c6 = tf.keras.layers.Conv2D(128, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(c6)

        u7 = tf.keras.layers.Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(c6)
        u7 = tf.keras.layers.concatenate([u7, c3])
        c7 = tf.keras.layers.Conv2D(64, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(u7)
        c7 = tf.keras.layers.Dropout(0.2)(c7)
        c7 = tf.keras.layers.Conv2D(64, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(c7)

        u8 = tf.keras.layers.Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same')(c7)
        u8 = tf.keras.layers.concatenate([u8, c2])
        c8 = tf.keras.layers.Conv2D(32, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(u8)
        c8 = tf.keras.layers.Dropout(0.1)(c8)
        c8 = tf.keras.layers.Conv2D(32, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(c8)

        u9 = tf.keras.layers.Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same')(c8)
        u9 = tf.keras.layers.concatenate([u9, c1], axis=3)
        c9 = tf.keras.layers.Conv2D(16, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(u9)
        c9 = tf.keras.layers.Dropout(0.1)(c9)
        c9 = tf.keras.layers.Conv2D(16, (3, 3), activation=tf.keras.activations.elu, kernel_initializer='he_normal',
                                padding='same')(c9)

        outputs = tf.keras.layers.Conv2D(1, (1, 1), activation='sigmoid')(c9)

        model = tf.keras.Model(inputs=[inputs], outputs=[outputs])
         model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
        model.summary()

        return (model)


    def training(model, X_train, Y_train, loss = 'categorical_crossentropy', optimizer='adam', metrics=['accuracy'], batch_size = 32, nb_epoch = 100, verbose = 2, validation_split = 0.3):
        model.compile(loss = loss, optimizer = optimizer, metrics = metrics)
        history = model.fit(X_train, Y_train, batch_size = batch_size, epochs = nb_epoch, verbose = verbose, validation_split = validation_split)
        return (history)

【问题讨论】:

  • 为什么你的标签是(18、320、320、2)?形状中的最后一个元素(2)是什么意思?这些是 one-hot 编码的二进制标签吗?
  • 因为掩码是 0 和 1 的二进制矩阵,所以 to_categorical 函数创建了 2 个类。我真的不知道应该对输入标签做什么,但是当我查看 U-Net 图时,最后一个块由 2 个通道组成。

标签: python tensorflow keras conv-neural-network


【解决方案1】:

假设您的标签是一次性编码的,那么您应该将输出层更改为:

outputs = tf.keras.layers.Conv2D(2, (1, 1), activation='softmax')(c9)

而损失函数为categorical_crossentropy。如果您想使用当前模型和损失而不进行修改,那么您必须对标签进行 one-hot 编码,因为binary_crossentropy 直接采用 0-1 二进制标签而无需 one-hot 编码。

【讨论】:

  • 成功了,非常感谢!我没有看到这一点,因为我正在学习该模型的教程。
猜你喜欢
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 2020-08-09
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
相关资源
最近更新 更多