Я пытаюсь использовать последовательность изображений для прогнозирования значения (от изображения к регрессии). Генератор должен генерировать на каждой итерации пакета массив, имеющий форму (batch_size, sequence, height, width, nbr_channels). Когда я пытаюсь подогнать свою модель к данным, сгенерированным генератором, возникает следующая ошибка: InvalidArgumentError: 2 root error(s) found. (0) Invalid argument: TypeError: 'generator' yielded an element that could not be converted to the expected type. The expected type was float32, but the yielded element was [array([[[[193., 177., 144.], ... [[141., 123., 99.] [Op:__inference_train_function_14739] Function call stack: train_function
Это генератор:
def generator(df, label, seq, bs, width, height):
#the column 'flat_images' of df contains the paths to images
X = []
Y = []
list_ID = df.index
while True:
for i in range(bs):
#random index
index = random.randint(0, len(df) - seq-1)
index = list_ID[index]
img_seq = [image.load_img(img_path, target_size=(height,width)) for img_path in df[index:index+seq].flat_images.values] #img_seq is of class list
img_seq_arr = np.array([image.img_to_array(img) for img in img_seq]) #shape(seq, hight, width, channels), class=np.ndarray
X.append(img_seq_arr)
Y.append(label[index+seq])
yield np.array(X), np.array(Y)
вот модель (вдохновленная из здесь ):
from tensorflow import keras
from tensorflow.keras import layers
from sklearn.model_selection import train_test_split
import numpy as np
import pylab as plt
#a model that takes as input seq_imgs of shape (nbr_images, width, height, channels)
model = keras.Sequential(
[
keras.Input( shape=(5, 40, 40, 3) ),
layers.ConvLSTM2D(filters=40, kernel_size=(3, 3), padding="same", return_sequences=True),
layers.BatchNormalization(),
layers.ConvLSTM2D(filters=40, kernel_size=(3, 3), padding="same", return_sequences=True),
layers.BatchNormalization(),
layers.ConvLSTM2D(filters=40, kernel_size=(3, 3), padding="same", return_sequences=True),
layers.BatchNormalization(),
layers.ConvLSTM2D(filters=40, kernel_size=(3, 3), padding="same", return_sequences=True),
layers.BatchNormalization(),
layers.Conv3D(filters=1, kernel_size=(3, 3, 3), activation="sigmoid", padding="same"),
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.Dropout(0.5),
layers.Dense(256, activation='relu'),
layers.Dropout(0.5),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(1),
]
)
print(model.summary())
model.compile(loss="mse", optimizer="adam", metrics=["accuracy"])
и подходящая деталь
#train test split
split_rate = 0.7
img_df_train = img_df[: int(split_rate * len(img_df))]
img_df_valid = img_df[int(split_rate * len(img_df)) :]
#generate samples
bs=32
train_gen = generator(img_df_train, img_df_train['GHI_avg'], seq=5, bs=32, width=40, height=40)
valid_gen = generator(img_df_valid, img_df_valid['GHI_avg'], seq=5, bs=32, width=40, height=40)
train_len = len(img_df_train)
valid_len = len(img_df_valid)
#then start to train
model.fit(
train_gen,
steps_per_epoch = train_len//bs,
epochs=50,
validation_data = valid_gen,
validation_steps = valid_len//bs,
verbose =1)