`Concatenate` 层需要具有匹配形状的输入,但连接轴除外

`Concatenate` layer requires inputs with matching shapes except for the concat axis

from keras.layers import Input, Conv3D, MaxPooling3D, concatenate, Conv3DTranspose, BatchNormalization, Dropout,  Lambda
from keras.optimizers import Adam

我的图像的形状是(36,128,128,1)。如何改变u7的形状以便我可以进行拼接?如何修改这个?

def simple_unet_model(IMG_HEIGHT, IMG_WIDTH, IMG_DEPTH, IMG_CHANNELS, num_classes):
    #Build the model
        inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_DEPTH, IMG_CHANNELS))
        #s = Lambda(lambda x: x / 255)(inputs)   #No need for this if we normalize our inputs beforehand
        s = inputs
        inputs = Input(shape=(36,128,128),name='input')
        #Contraction path
        c1 = Conv3D(16, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(s)
        c1 = Dropout(0.1)(c1)
        c1 = Conv3D(16, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c1)
        p1 = MaxPooling3D((2, 2, 2))(c1)
        
        c2 = Conv3D(32, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(p1)
        c2 = Dropout(0.1)(c2)
        c2 = Conv3D(32, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c2)
        p2 = MaxPooling3D((2, 2, 2))(c2)
         
        c3 = Conv3D(64, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(p2)
        c3 = Dropout(0.2)(c3)
        c3 = Conv3D(64, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c3)
        p3 = MaxPooling3D((2, 2, 2))(c3)
         
        c4 = Conv3D(128, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(p3)
        c4 = Dropout(0.2)(c4)
        c4 = Conv3D(128, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c4)
        p4 = MaxPooling3D(pool_size=(2, 2, 2))(c4)
         
        c5 = Conv3D(256, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(p4)
        c5 = Dropout(0.3)(c5)
        c5 = Conv3D(256, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c5)
        
        #Expansive path 
        u6 = Conv3DTranspose(128, (2, 2, 2), strides=(2, 2, 2), padding='same')(c5)
        u6 = concatenate([u6, c4])
        c6 = Conv3D(128, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(u6)
        c6 = Dropout(0.2)(c6)
        c6 = Conv3D(128, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c6)
         
        u7 = Conv3DTranspose(64, (2, 2, 2), strides=(2, 2, 2), padding='same')(c6)
        u7 = concatenate([u7, c3])
        c7 = Conv3D(64, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(u7)
        c7 = Dropout(0.2)(c7)
        c7 = Conv3D(64, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c7)
         
        u8 = Conv3DTranspose(32, (2, 2, 2), strides=(2, 2, 2), padding='same')(c7)
        u8 = concatenate([u8, c2])
        c8 = Conv3D(32, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(u8)
        c8 = Dropout(0.1)(c8)
        c8 = Conv3D(32, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c8)
         
        u9 = Conv3DTranspose(16, (2, 2, 2), strides=(2, 2, 2), padding='same')(c8)
        u9 = concatenate([u9, c1])
        c9 = Conv3D(16, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(u9)
        c9 = Dropout(0.1)(c9)
        c9 = Conv3D(16, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c9)
         
        outputs = Conv3D(num_classes, (1, 1, 1), activation='softmax')(c9)
         
        model = Model(inputs=[inputs], outputs=[outputs])
        #compile model outside of this function to make it flexible. 
        model.summary()
        
        return model

我在 u7 = concatenate([u7, c3])

行遇到错误

Concatenate 层需要具有匹配形状的输入,但连接轴除外。得到输入形状:[(None, 32, 32, 8, 64), (None, 32, 32, 9, 64)] 但是如果我的图像的形状是 (64,128,128,1)。它有效 properly.But 如果我将深度从 36 增加到 64;图像改变了

构建模型

epochs = 10
model.fit(
    X_train,y_train,
    validation_data=(X_test,y_test),
    epochs=epochs,
    shuffle=True,
    verbose=2,
    callbacks = callbacks_list)

我遇到了错误 ValueError:输入 0 与图层模型不兼容:预期形状=(None, 36, 128, 128, 1),找到的形状=(None, 64, 128, 128, 1)

您可以尝试连接 axis=1 并删除两个 Input 层之一。你只需要一个。这是一个工作示例(虽然我不确定您的目标是什么):

from keras.layers import Input, Conv3D, MaxPooling3D, concatenate, Conv3DTranspose, BatchNormalization, Dropout,  Lambda
import tensorflow as tf

def simple_unet_model(IMG_HEIGHT, IMG_WIDTH, IMG_DEPTH, IMG_CHANNELS, num_classes):
    #Build the model
        kernel_initializer = tf.keras.initializers.GlorotNormal()
        inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_DEPTH, IMG_CHANNELS), name='input')
        #s = Lambda(lambda x: x / 255)(inputs)   #No need for this if we normalize our inputs beforehand
        s = inputs
        #Contraction path
        c1 = Conv3D(16, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(s)
        c1 = Dropout(0.1)(c1)
        c1 = Conv3D(16, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c1)
        p1 = MaxPooling3D((2, 2, 2))(c1)
        
        c2 = Conv3D(32, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(p1)
        c2 = Dropout(0.1)(c2)
        c2 = Conv3D(32, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c2)
        p2 = MaxPooling3D((2, 2, 2))(c2)
         
        c3 = Conv3D(64, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(p2)
        c3 = Dropout(0.2)(c3)
        c3 = Conv3D(64, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c3)
        p3 = MaxPooling3D((2, 2, 2))(c3)
         
        c4 = Conv3D(128, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(p3)
        c4 = Dropout(0.2)(c4)
        c4 = Conv3D(128, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c4)
        p4 = MaxPooling3D(pool_size=(2, 2, 2))(c4)
         
        c5 = Conv3D(256, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(p4)
        c5 = Dropout(0.3)(c5)
        c5 = Conv3D(256, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c5)
        
        #Expansive path 
        u6 = Conv3DTranspose(128, (2, 2, 2), strides=(2, 2, 2), padding='same')(c5)
        u6 = concatenate([u6, c4])
        c6 = Conv3D(128, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(u6)
        c6 = Dropout(0.2)(c6)
        c6 = Conv3D(128, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c6)
         
        u7 = Conv3DTranspose(64, (2, 2, 2), strides=(2, 2, 2), padding='same')(c6)
        u7 = concatenate([u7, c3], axis=1)
        c7 = Conv3D(64, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(u7)
        c7 = Dropout(0.2)(c7)
        c7 = Conv3D(64, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c7)
         
        u8 = Conv3DTranspose(32, (2, 2, 2), strides=(2, 2, 2), padding='same')(c7)
        u8 = concatenate([u8, c2], axis=1)
        c8 = Conv3D(32, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(u8)
        c8 = Dropout(0.1)(c8)
        c8 = Conv3D(32, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c8)
         
        u9 = Conv3DTranspose(16, (2, 2, 2), strides=(2, 2, 2), padding='same')(c8)
        u9 = concatenate([u9, c1], axis=1)
        c9 = Conv3D(16, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(u9)
        c9 = Dropout(0.1)(c9)
        c9 = Conv3D(16, (3, 3, 3), activation='relu', kernel_initializer=kernel_initializer, padding='same')(c9)
         
        outputs = Conv3D(num_classes, (1, 1, 1), activation='softmax')(c9)
         
        model = tf.keras.Model(inputs=[inputs], outputs=[outputs])
        #compile model outside of this function to make it flexible. 
        model.summary()
        
        return model


simple_unet_model(36,128,128, 1, 5)