簡體   English   中英

在功能 API keras model 中使用 datagen.flow_from_directory() 出現不兼容的形狀錯誤

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

我是一個嘗試學習 TF 和 keras 的超級 n00b。 我想使用功能 API 創建一個 model 並由 ImageDataGenerator() 和 flow_from_directory() 提供。 我僅限於使用 spyder (5.1.5) 和 python 3.7、keras 2.8.0、tensorflow 2.8.0。

我已將示例補丁組織到帶標簽的文件夾中以支持 flow_from_directory()。 有 7 個類,每個補丁是一個 small.png 圖像,大小應該是 128 x 128 x 3。

但是,當我嘗試調用 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

我認為我的發電機沒有產生任何東西。 我認為這個問題與我的 model 被饋送類似 [50,7] (其中批量大小為 50,7 是類數)而不是 [50,128,128,3] 之類的東西有關,這將是從整個class 標記的文件夾。 所以它實際上並沒有訓練任何東西。

這是代碼:

# 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)

事實證明,我解決了以下問題:

在編譯器中將優化器更改為 Adam,在我的最終密集 (7) output 之前添加了一個 flatten() 層

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM