Iterador Keras con imágenes aumentadas y otras características

8

Supongamos que tiene un conjunto de datos que tiene imágenes y algunos datos en a .csvpara cada imagen. Su objetivo es crear un NN que tenga una rama de convolución y otra (en mi caso, un MLP).

Ahora, hay muchas guías ( una aquí , otra ) sobre cómo crear la red, ese no es el problema.

El problema aquí es cómo creo un iterador en forma de [[convolution_input, other_features], target]cuando convolution_inputes de un flujo de Keras que agrega imágenes aumentadas.ImageDataGenerator

Más específicamente, cuando la enésima imagen (que puede ser aumentada o no) se alimenta a la NN, quiero que tenga sus características originales en su interior other_features.

Encontré pocos intentos ( aquí y aquí , el segundo parecía prometedor, pero no pude descubrir cómo manejar imágenes aumentadas) al hacer exactamente eso, pero no parecen tener en cuenta la posible manipulación del conjunto de datos que el generador Keras hace.

Lamberto Basti
fuente
1
Pregunta: ¿estás de acuerdo flowo necesitas flow_from_directory? ( flowsignifica que puede mantener todas las imágenes cargadas en la memoria)
Daniel Möller
Bueno, solo quiero un flujo que maneje automáticamente la transformación de la imagen. En mi caso, estaba usando flow_from_dataframeporque tengo nombres de archivos, características y clases
Lamberto Basti

Respuestas:

3

Digamos que tiene un csv, de modo que sus imágenes y otras características están en el archivo.

donde id representa el nombre de la imagen, seguido de las características y su objetivo (clase para la clasificación, número para la regresión)

ingrese la descripción de la imagen aquí

Primero definamos un generador de datos y luego podemos anularlo.

leamos los datos del csv en un marco de datos de pandas y usemos flow_from_dataframe de keras para leer del marco de datos.

df = pandas.read_csv("dummycsv.csv")
datagen = ImageDataGenerator(rescale=1/255.)
generator = datagen.flow_from_dataframe(df,directory="out/",x_col="id",y_col=df.columns[1:],class_mode="raw",batch_size=1)

Siempre puede agregar su aumento en ImageDataGenerator.

Lo que hay que tener en cuenta en el código anterior en flow_from_dataframe es

x_col = el nombre de la imagen

y_col = típicamente columnas con el nombre de la clase, pero anulemos más adelante al proporcionar primero todas las otras columnas en el csv. es decir, feat_1, feat_2 .... hasta class_label

class_mode = raw, sugiera al generador que devuelva todos los valores en y tal como están.

Ahora anulemos / heredemos el generador anterior y creemos uno nuevo, de modo que devuelva [img, otherfeatures], [target]

Aquí está el código con comentarios como explicaciones.

def my_custom_generator():
count = 0 #to keep track of complete epoch
while True:
    if(count==len(df.index)): 
        #if the count is matching with the length of df, the one pass is completed, so reset the generator
        generator.reset()
        break
    count+=1
    data = generator.next() #get the data from the generator
    #the data looks like this [[img,img] , [other_cols,other_cols]]  based on the batch size

    imgs = []
    cols = []
    targets = []
    #iterate the data and append the necessary columns in the corresponding arrays 
    for k in range(batch_size):
        imgs.append(data[0][k]) #the first array contains all images

        cols.append(data[1][k][:-1])  #the second array contains all features with last column as class, so [:-1]
        targets.append(data[1][k][-1]) #the last column in the second array from data is the class

    yield [imgs,cols],targets  #this will yield the result as you expect.

cree una función similar para su generador de validación. Use train_test_split para dividir su marco de datos si lo necesita y crear 2 generadores y anularlos.

pasar la función en model.fit_generator como este

model.fit_generator(my_custom_generator(),.....other params)
venkata krishnan
fuente
Pero, ¿cómo se puede if(count==len(df.index))hacer un seguimiento de la época si el conjunto de datos aumentado es mucho más numeroso que el original?
Lamberto Basti
1
Los aumentos se aplican aleatoriamente a las imágenes. No aumentará el número de imágenes a menos que las guarde por separado y las use como una instancia única en el conjunto de entrenamiento. La forma en que el aumento ayuda es que durante cada época se aplica un aumento diferente al azar, lo que hace que se vean como imágenes diferentes
venkata krishnan
Wow, esa es una gran información. También recomendaría agregarlo a la respuesta. Además, ¿por qué esa información importante no está escrita explícitamente en la documentación de Keras?
Lamberto Basti
1
Incluso lo pensé yo mismo, porque cuando mencionamos los pasos por época en el entrenamiento, generalmente dividimos la longitud del entrenamiento por el tamaño del lote, lo que significa que, en una época, pasa todas las imágenes solo una vez. Espero tener razón ..
venkata krishnan