Итератор Keras с дополненными изображениями и другими функциями - PullRequest
8 голосов
/ 03 марта 2020

Скажем, у вас есть набор данных, в котором есть изображения и некоторые данные в .csv для каждого изображения. Ваша цель - создать NN, у которого есть свёрточная ветвь и другая (в моем случае MLP).

Теперь есть множество направляющих ( одна здесь , еще один ) о том, как создать сеть, это не проблема.

Проблема здесь в том, как мне создать итератор в виде [[convolution_input, other_features], target], когда convolution_input от Keras ImageDataGenerator flow , который добавляет расширенные изображения.

В частности, когда n-е изображение (может быть увеличенным или нет) подается на NN, я хочу, чтобы его оригинальные функции были внутри other_features.

Я обнаружил несколько попыток ( здесь и здесь , второе выглядело многообещающе, но я не смог понять, как обрабатывать дополненные изображения), делая именно это, но, похоже, они не учитывают возможные манипуляции с наборами данных, которые делает генератор Keras.

1 Ответ

3 голосов
/ 06 марта 2020

Допустим, у вас есть CSV, так что ваши изображения и другие функции находятся в файле.

где id представляет имя изображения, сопровождаемое объектами и сопровождаемое вашей целью (класс для классификации, номер для повторного выражения)

enter image description here

Сначала давайте определим генератор данных, а затем мы можем переопределить его.

давайте прочитаем данные из csv в pandas фрейме данных и используем keras flow_from_dataframe для чтения из фрейма данных.

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)

Вы всегда можете добавить свое увеличение в ImageDataGenerator.

Обратите внимание, что в приведенном выше коде в flow_from_dataframe есть

x_col = имя изображения

y_col = обычно столбцы с именем класса, но давайте переопределим его позже первым предоставляя все остальные столбцы в CSV. т.е. feat_1, feat_2 .... до class_label

class_mode = raw, предложить генератору вернуть все значения в y как есть.

Теперь давайте переопределим / унаследуем вышеуказанный генератор и создадим новый, чтобы он возвращал [img, otherfeatures], [target]

Вот код с комментариями в качестве объяснений

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.

создайте аналогичную функцию для вашего генератора валидации. Используйте train_test_split, чтобы разделить ваш фрейм данных, если вам это нужно, создать 2 генератора и переопределить их.

передать функцию в model.fit_generator следующим образом

model.fit_generator(my_custom_generator(),.....other params)
...