繁体   English   中英

不兼容的形状:[128,1] 与 [128,3,3]

[英]Incompatible shapes: [128,1] vs. [128,3,3]

我正在尝试创建一个 CNN 来对 SVHN 数据集进行分类,但在创建 model 时遇到了不兼容的形状错误:不兼容的形状:[128,3,3,10] 与 [128,1]。 我如何解决它?

         model = Sequential([
                          Conv2D(filters=8, kernel_size=(3, 3), 
                           activation='relu', input_shape=(32, 32,3 
                           name='conv_1'),
                            
                           Conv2D(filters=8, kernel_size=(3, 3), 
                          activation='relu', padding= 'SAME',  
                                   `name='conv_2'),
                           MaxPooling2D(pool_size=(8, 8), name='pool_1'),
                            Dense(64,  kernel_regularizer = 
                            regularizers.l2(0.5),bias_initializer='ones',
                            activation='relu' , name='dense_1'),
                            Dropout(0.3),  
                            Dense(64,kernel_regularizer = 
                            regularizers.l2(0.5) , activation='relu' 
                           ,name='dense_2'),
                            BatchNormalization(),  
                            Dense(64,  kernel_regularizer = 
                            regularizers.l2(0.5) ,  activation='relu' 
                             ,name='dense_3'),
                             Dense(10,  activation='softmax' 
                             ,name='dense_4')
             ])


           model.compile(
           optimizer = 'adam',
           loss = 'sparse_categorical_crossentropy',
           metrics= ['accuracy' ])
   

           history = model.fit(train_images,train_labels , epochs = 30 
           ,validation_split = 0.15,
                batch_size= 128, verbose = False )

在最后一个Dense层之前放置一个Flatten层。 因为您没有这样做,所以在为您提供 class 的层之前,张量没有减少为单维张量。

TensorFlow 中的一般模式是在输出 class 的层之前使用Flatten

另外,我已经删除了您放置的随机密集层中的BatchNormalizationBatchNormalization层通常放在 Conv 层之后,但是您可以将它们放在Dense层之后。 如果你是 BatchNormalization,确保整个网络或相关的都有它。 不要只放一个随机BatchNormalization层。

这是您更改代码以执行此操作的方法。

 model = Sequential([Conv2D(filters=8, kernel_size=(3, 3), 
                           activation='relu', input_shape=(32, 32,3), 
                           name='conv_1'),
                     BatchNormalization(),
                     Conv2D(filters=8, kernel_size=(3, 3), 
                          activation='relu', padding= 'SAME',  
                          name='conv_2'),
                     BatchNormalization(),
                     MaxPooling2D(pool_size=(8, 8), name='pool_1'),
                     Flatten(),
                     Dense(64,  kernel_regularizer = 
                           regularizers.l2(0.5), bias_initializer='ones',
                           activation='relu' , name='dense_1'),
                     Dropout(0.3),  
                     Dense(64,kernel_regularizer = 
                           regularizers.l2(0.5) , activation='relu', 
                           name='dense_2'),
                     Dense(64,  kernel_regularizer = 
                           regularizers.l2(0.5) ,  activation='relu', 
                           name='dense_3'),
                     Dense(10,  activation='softmax', 
                           name='dense_4')
             ])


           model.compile(
           optimizer = 'adam',
           loss = 'sparse_categorical_crossentropy',
           metrics= ['accuracy' ])
   

           history = model.fit(train_images,train_labels , epochs = 30)

我认为您的代码中有两个问题。

首先,请检查train_labels的形状。 如果张量的Incompatible shapes的错误。 我认为[128, 1]的形状意味着train_label不是一种单热向量。 如果 train_label 形状如 [1, 3, 8, ..],则应将形状更改为[[0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0], ...]

其次,如上所述,您应该在Dense层之前添加Flatten层。

 model = Sequential([
       Conv2D(filters=8, kernel_size=(3, 3), activation='relu', input_shape=(32, 32, 3), name='conv_1'),
       ...
       MaxPooling2D(pool_size=(8, 8), name='pool_1'),
       
       Flatten(),

       Dense(64,  kernel_regularizer ...
             ])

(32, 32, 1)的形状意味着输入形状的最后一个暗淡应该是一个。 所以你应该将 Conv2D 的Conv2D更改为(32, 32, 1)

Conv2D(filters=8, kernel_size=(3, 3), activation='relu', input_shape=(32, 32, 1) ...

此外,train_images 也应更改为(32, 32, 1)因为图像的通道是 1。

train_images = tf.expand_dims(train_images, -1)

此外,您可以像这样获得train_labels的 one-hot 向量:

train_labels = tf.squeeze(train_labels)
train_labels = tf.one_hot(train_labels, depth=10)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM