简体   繁体   English

在功能 API keras model 中使用 datagen.flow_from_directory() 出现不兼容的形状错误

[英]incompatible shapes error using datagen.flow_from_directory() in a functional API keras model

I am a super n00b attempting to learn TF and keras.我是一个尝试学习 TF 和 keras 的超级 n00b。 I would like to create a model using the Functional API and fed by ImageDataGenerator() and flow_from_directory().我想使用功能 API 创建一个 model 并由 ImageDataGenerator() 和 flow_from_directory() 提供。 I am limited to using spyder (5.1.5) and python 3.7, keras 2.8.0, tensorflow 2.8.0.我仅限于使用 spyder (5.1.5) 和 python 3.7、keras 2.8.0、tensorflow 2.8.0。

I have organized sample patches into labelled folders to support flow_from_directory().我已将示例补丁组织到带标签的文件夹中以支持 flow_from_directory()。 There are 7 classes and each patch is a small.png image, size is supposed to be 128 x 128 x 3.有 7 个类,每个补丁是一个 small.png 图像,大小应该是 128 x 128 x 3。

However, when I attempt to call model.fit() I receive a ValueError:但是,当我尝试调用 model.fit() 时,我收到一个 ValueError:

Traceback (most recent call last):

  File ~\.spyder-py3\MtP_treeCounts\shape_error_code.py:129 in <module>
    history = model.fit(ds_train,

  File ~\Anaconda3\envs\tf28\lib\site-packages\keras\utils\traceback_utils.py:67 in error_handler
    raise e.with_traceback(filtered_tb) from None

  File ~\Anaconda3\envs\tf28\lib\site-packages\tensorflow\python\framework\func_graph.py:1147 in autograph_handler
    raise e.ag_error_metadata.to_exception(e)

ValueError: in user code:

    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\engine\training.py", line 1021, in train_function  *
        return step_function(self, iterator)
    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\engine\training.py", line 1010, in step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\engine\training.py", line 1000, in run_step  **
        outputs = model.train_step(data)
    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\engine\training.py", line 860, in train_step
        loss = self.compute_loss(x, y, y_pred, sample_weight)
    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\engine\training.py", line 918, in compute_loss
        return self.compiled_loss(
    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\engine\compile_utils.py", line 201, in __call__
        loss_value = loss_obj(y_t, y_p, sample_weight=sw)
    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\losses.py", line 141, in __call__
        losses = call_fn(y_true, y_pred)
    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\losses.py", line 245, in call  **
        return ag_fn(y_true, y_pred, **self._fn_kwargs)
    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\losses.py", line 1789, in categorical_crossentropy
        return backend.categorical_crossentropy(
    File "C:\Users\jlovitt\Anaconda3\envs\tf28\lib\site-packages\keras\backend.py", line 5083, in categorical_crossentropy
        target.shape.assert_is_compatible_with(output.shape)

    ValueError: Shapes (None, None) and (None, 128, 128, 1) are incompatible

I don't think my generator is generating anything.我认为我的发电机没有产生任何东西。 I assume the issue is linked to my model being fed something like [50,7] (where batch size is 50 and 7 is the number of classes) instead of [50,128,128,3] which would be 50 individual patches pulled randomly from across the class labelled folders.我认为这个问题与我的 model 被馈送类似 [50,7] (其中批量大小为 50,7 是类数)而不是 [50,128,128,3] 之类的东西有关,这将是从整个class 标记的文件夹。 So it's not actually training anything.所以它实际上并没有训练任何东西。

Here is the code:这是代码:

# set up
import numpy as np

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import models
from tensorflow.keras.layers import Input, Conv2D,Conv1D, UpSampling2D, concatenate,Dense, Flatten, Dropout,BatchNormalization, MaxPooling2D
from tensorflow.keras.models import Model, Sequential, load_model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.preprocessing import image_dataset_from_directory
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from keras import backend as K

K.clear_session()
del model
#build generator & train set

datagen = ImageDataGenerator(
    rotation_range=40,
    zoom_range=(0.95,0.95),
    width_shift_range=0.2,
    height_shift_range=0.2,
    dtype = np.float32,
    rescale=1/255,
    shear_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest',
    data_format = "channels_last",
    )

image_height = 128
image_width = 128
batch_size = 50


ds_train = datagen.flow_from_directory(
    directory=r"C:/Users/jlovitt/Pyworking/for_CNN_5/RGB_aerial/patches/train/rgb/organized/",
    target_size=(image_height,image_width),
    batch_size = batch_size,
    color_mode="rgb",
    class_mode = 'categorical',
    shuffle=True,
    seed =42,
    #subset='training',
    )
#set params

# STEP_SIZE_TRAIN = round(int(ds_train.n//ds_train.batch_size),-1)
STEP_SIZE_TRAIN = 180

# STEP_SIZE_VALID = round(int(ds_validation.n//ds_validation.batch_size),-1)
STEP_SIZE_VALID = 20

lr = 0.001
#define model


def U_model():
   
    in1 = Input(shape=(256,256,3))

    conv1 = Conv2D(32,(3, 3), activation='relu', kernel_initializer='he_normal', padding='same')(in1)
    conv1 = Dropout(0.1)(conv1)
    conv1 = Conv2D(32,(3, 3), activation='relu', kernel_initializer='he_normal', padding='same')(conv1)
    pool1 = MaxPooling2D((2,2))(conv1)

    conv2 = Conv2D(64,(3, 3), activation='relu', kernel_initializer='he_normal', padding='same')(pool1)
    conv2 = Dropout(0.1)(conv2)
    conv2 = Conv2D(64,(3, 3), activation='relu', kernel_initializer='he_normal', padding='same')(conv2)
    pool2 = MaxPooling2D((2,2))(conv2)

    conv3 = Conv2D(128,(3, 3), activation='relu', kernel_initializer='he_normal', padding='same')(pool2)
    conv3 = Dropout(0.1)(conv3)
    conv3 = Conv2D(128,(3, 3), activation='relu', kernel_initializer='he_normal', padding='same')(conv3)
    pool3 = MaxPooling2D((2,2))(conv3)
    
    conv4 = Conv2D(128, 3, activation='relu', kernel_initializer='he_normal', padding='same')(pool3)
    conv4 = Dropout(0.1)(conv4)
    conv4 = Conv2D(128, 3, activation='relu', kernel_initializer='he_normal', padding='same')(conv4)
    
    up1 = concatenate([UpSampling2D((2,2))(conv4),conv3],axis=-1)
    conv5 = Conv2D(64,(3,3), activation='relu', kernel_initializer='he_normal', padding='same')(up1)
    conv5 = Dropout(0.1)(conv5)
    conv5 = Conv2D(64,(3,3), activation='relu', kernel_initializer='he_normal', padding='same')(conv5)
    
    up2 = concatenate([UpSampling2D((2,2))(conv5), conv2], axis=-1)
    conv6 = Conv2D(64, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(up2)
    conv6 = Dropout(0.1)(conv6)
    conv6 = Conv2D(64, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(conv6)

    up3 = concatenate([UpSampling2D((2,2))(conv6), conv1], axis=-1)
    conv7 = Conv2D(32, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(up3)
    conv7 = Dropout(0.1)(conv7)
    conv7 = Conv2D(32, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(conv7)
    
    out1 = keras.layers.Dense(7)(conv7)
    
    #defining inputs and outputs of model
    model = Model(inputs=[in1], outputs=[out1])

    model.compile(loss="categorical_crossentropy", optimizer =keras.optimizers.SGD(learning_rate=lr,momentum=0.9),metrics=[tf.keras.metrics.MeanSquaredError(),tf.keras.metrics.MeanAbsoluteError()])
    
    return model

model = U_model()
model.summary()
#train model

history = model.fit(ds_train,
                    steps_per_epoch=STEP_SIZE_TRAIN,
                    validation_data=ds_validation,
                    validation_steps=STEP_SIZE_VALID,
                    epochs=10)

As it turns out I solved the issue with the following:事实证明,我解决了以下问题:

changed optimizer to Adam in compiler, added a flatten() layer prior to my final dense(7) output在编译器中将优化器更改为 Adam,在我的最终密集 (7) output 之前添加了一个 flatten() 层

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

相关问题 使用带有图像分割和类数的 datagen.flow_from_directory - Using datagen.flow_from_directory with image segmination and number of classes datagen.flow_from_directory 函数 - datagen.flow_from_directory function keras datagen.flow_from_directory class 模式分类获取标签错误 - keras datagen.flow_from_directory class mode categorical get labels wrong 形状与 Keras 功能 Model 和 VGG16 model 不兼容 - Shapes are incompatible with Keras Functional Model and VGG16 model 如何使用具有两个输入和两个输出并使用两个 ImageDataGenerator 方法 (flow_from_directory) 的功能 API 训练 Keras model - How to train a Keras model using Functional API which has two inputs and two outputs and uses two ImageDataGenerator methods (flow_from_directory) Keras 2 输入 model,不兼容的形状 - Keras 2 input model, incompatible Shapes 使用Keras fit_generator和datagen.flow时出现内存错误 - Memory error when using Keras fit_generator and datagen.flow 尝试使用 Keras 训练模型,得到一个 ValueError 说形状不兼容 - Trying to train model using Keras, getting a ValueError saying shapes are incompatible 使用Keras + Tensorflow训练ConvNet时出现不兼容的形状错误 - Incompatible shapes error while training ConvNet using Keras+Tensorflow 使用 Keras Functional API 微调模型 - fine tune a model using Keras Functional API
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM