【问题标题】:Incompatible shapes: [128,1] vs. [128,3,3]不兼容的形状:[128,1] 与 [128,3,3]
【发布时间】:2020-11-16 09:57:09
【问题描述】:

我正在尝试创建一个 CNN 来对 SVHN 数据集进行分类,但在创建我的模型时遇到了不兼容的形状错误:不兼容的形状:[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 )

【问题讨论】:

  • 你能把整个追溯吗?
  • 嗨 Pygril,我试图在这里添加整个回溯,但它说我这么久

标签: python image tensorflow deep-learning conv-neural-network


【解决方案1】:

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

TensorFlow 中的一般模式是在输出该类的层之前使用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)

【讨论】:

  • 感谢 Abhishek 的帮助,我尝试添加一个 Flatten 层但出现错误:检查输入时出错:预期 conv_1_input 有 4 个维度,但得到的数组形状为 (73257, 32, 32 )
  • 你是在我添加的同一个地方添加的吗?
  • yes Abhishek 我在同一个地方添加了 Flatten 层,我得到一个新的错误 检查输入时出错:预期 conv_1_input 有 4 个维度,但得到的数组形状为 (73257, 32, 32跨度>
  • 告诉我你是如何在网络内发送数据的。这就是问题所在。
  • 谢谢 Abhishek,我复制了你的代码,我尝试运行它我告诉你结果,这就是我在网络外发送数据的方式,history = model.fit(train_images,train_labels, epochs = 30 ,validation_split = 0.15, callbacks=callbacks ,batch_size= 128, verbose = False )
【解决方案2】:

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

首先请确认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) 的形状表示输入形状的最后一个暗淡应该是 1。所以你应该把Conv2D的input_shape改成(32, 32, 1)

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

另外,train_images 也应该改为(32, 32, 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)

【讨论】:

  • 谢谢Gi的回复,train_labels的形状是(73257, 1),train_images的形状是(73257, 32, 32),train_labels的形式是:array([ [1], [9], [2],.... [6], [1]],我尝试添加一个 Flatten 层我得到了错误:检查输入时出错:预期 conv_1_input 有 4 个维度,但是得到形状为 (73257, 32, 32) 的数组
  • (73257, 32 ,32)的train_images的shape表示模型输入shape的最后一个维度应该是1。
猜你喜欢
  • 2021-09-07
  • 2020-10-03
  • 1970-01-01
  • 2021-12-31
  • 2019-12-16
  • 2021-09-18
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多