【问题标题】:Error when training my CNN: ValueError: Shape must be rank 2 but is rank 4训练我的 CNN 时出错:ValueError: Shape must be rank 2 but is rank 4
【发布时间】:2021-06-07 16:09:20
【问题描述】:

我正在设计一个用于图像分割的 CNN。

模型如下:

def create_and_compile_model():
    theModel=models.Sequential([
        Conv2D(8, (3, 3), activation='relu', padding='same',input_shape=(64,64,3)),
        MaxPooling2D((2, 2), padding='same'),            
        Conv2D(16, (3, 3), activation='relu', padding='same'),
        Conv2D(32, (3, 3), activation='relu', padding='same'),
        Conv2D(64, (3, 3), activation='relu', padding='same'),
        UpSampling2D((2, 2)),
        Conv2D(3, (3, 3), activation='softmax', padding='same')
    ])

    theModel.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['categorical_accuracy','top_k_categorical_accuracy'])
    
    return theModel

# Now create and compile it
theModel=create_and_compile_model()

# Print the summary
theModel.summary()

总结:

Model: "sequential_26"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_104 (Conv2D)          (None, 64, 64, 8)         224       
_________________________________________________________________
max_pooling2d_30 (MaxPooling (None, 32, 32, 8)         0         
_________________________________________________________________
conv2d_105 (Conv2D)          (None, 32, 32, 16)        1168      
_________________________________________________________________
conv2d_106 (Conv2D)          (None, 32, 32, 32)        4640      
_________________________________________________________________
conv2d_107 (Conv2D)          (None, 32, 32, 64)        18496     
_________________________________________________________________
up_sampling2d_27 (UpSampling (None, 64, 64, 64)        0         
_________________________________________________________________
conv2d_108 (Conv2D)          (None, 64, 64, 3)         1731      
=================================================================
Total params: 26,259
Trainable params: 26,259
Non-trainable params: 0

我的数据生成器:

class DataGenerator(Sequence):
    def __init__(self,fileNames,doRandomize=False,imgPath='DATA/IMG',gtPath='DATA/GT',batchSize=10):
        # Store parameters
        self.imgPath=imgPath
        self.gtPath=gtPath
        self.fileNames=fileNames
        self.batchSize=batchSize
        self.doRandomize=doRandomize
        self.numImages=len(self.fileNames)
        self.on_epoch_end()

    def on_epoch_end(self):
        if self.doRandomize:
            random.shuffle(self.fileNames)
    
    def _load_image_pair_(self,imageIndex):
        # Place your code here
        
        img_IMG = skio.imread(os.path.join(self.imgPath, self.fileNames[imageIndex]))
        img_GT = skio.imread(os.path.join(self.gtPath, self.fileNames[imageIndex]))

        #convert to range [0,1]
        theImage = img_as_float(img_IMG)

        #convert to categorical
        gtImage = to_categorical(img_GT)


        # The method returns the modified sample image (within the interval [0,1]) (theImage)
        # and the categorical version of the ground truth (gtImage)
        return theImage,gtImage
            
    # Returns the number ot batches
    def __len__(self):
        return int(np.ceil(float(self.numImages)/float(self.batchSize)))

    # Provides the "theIndex-th" batch
    # Batch format:
    # - X : The data. Numpy array of shape (bs,nr,nc,3)
    # - y : The ground truth. Numpy array of shape (bs,nr,nc,3)
    # Where nb=batch size, nr=num rows, nc=num cols (in this case, nr=nc=64)
    # Since "y" is provided in categorical format the last dimension (3) is
    # the number of classes.
    def __getitem__(self,theIndex):
        X=[]
        y=[]
        bStart=max(theIndex*self.batchSize,0)
        bEnd=min((theIndex+1)*self.batchSize,self.numImages)

        for i in range(bStart,bEnd):
            [curImage,curGT]=self._load_image_pair_(i)
            X.append(curImage)
            y.append(curGT)
        return np.array(X),np.array(y)

所以,如果我这样做:

[X,y]=trainGenerator.__getitem__(0)
print(type(X))
print(X.shape)
print(type(y))
print(y.shape)

我明白了:

<class 'numpy.ndarray'>
(10, 64, 64, 3)
<class 'numpy.ndarray'>
(10, 64, 64, 3)

然后,我尝试使用我创建的数据生成器来训练模型:

train = theModel.fit(trainGenerator, epochs=10, validation_data=valGenerator)

我得到这个错误:

ValueError: Shape must be rank 2 but is rank 4 for '{{node in_top_k/InTopKV2}} = InTopKV2[T=DT_INT64](sequential_26/conv2d_108/Softmax, ArgMax_2, in_top_k/InTopKV2/k)' with input shapes: [?,64,64,3], [?,?,?], [].

我不明白为什么它抱怨形状。由于最后一层是我认为正确的形状(无、64、64、3)。图像为 64x64 像素,其中 3 个是像素可能具有的 3 个类别。

有人能解释一下这个错误吗?

谢谢

【问题讨论】:

  • trainGenerator 的对手在哪里?
  • 您的标签数据形状看起来不正确。
  • 我编辑添加了数据生成器类

标签: python tensorflow machine-learning keras conv-neural-network


【解决方案1】:

问题是我在 Google Colab 中运行此代码。并且默认安装的是Tensorflow 2.5。

我不得不降级 Tensorflow 的版本:

!pip install tensorflow==1.15.3

然后,其中一项指标给出了错误。 所以,我编译模型如下:

theModel.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['categorical_accuracy'])

【讨论】:

    猜你喜欢
    • 2021-12-29
    • 2022-07-16
    • 1970-01-01
    • 2020-02-28
    • 2021-02-08
    • 2019-07-15
    • 1970-01-01
    • 2018-10-20
    • 2018-06-01
    相关资源
    最近更新 更多