![](/img/trans.png)
[英]Using datagen.flow_from_directory with image segmination and number of classes
[英]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.