Генератор изображений вызывает ошибку InvalidArgumentError при попытке уместить данные - PullRequest
1 голос
/ 07 августа 2020

Я пытаюсь использовать последовательность изображений для прогнозирования значения (от изображения к регрессии). Генератор должен генерировать на каждой итерации пакета массив, имеющий форму (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)
...