Модель с несколькими входами Keras с использованием flow_from_dataframe - PullRequest
0 голосов
/ 20 февраля 2019

Я пытался запустить сиамскую сеть.На данный момент я просто пытаюсь заставить его работать.Моя текущая итерация использует фрейм данных pandas, чтобы определить, какие изображения загружать.Фрейм данных имеет столбцы для Anchor_Id, Positive_Id, Negative_Id и соответствующих имен файлов под Anchor_Image, Positive_Image, Negative_Image.Я использую функцию потери Triplet для определения различий во вложениях изображений.

Сейчас моя ошибка в том, что модель ожидает 3 массива, но она получает только список из 1 массива.Я знаю, что generator_generator_triplet (см. Ниже) помещает эти потоки в список, но это похоже на другие итерации этой модели.Моя предыдущая проблема заключалась в том, что мне нужна была моя окончательная модель внедрения, чтобы иметь плотный слой с ровно таким же количеством узлов, что и категорий (примерно 5000).Это не имело смысла для меня, и я думаю, что эта проблема была связана с моделями, снабжающими вектор с одной горячей меткой вместе со значениями X (изображения).

Часть этого кода была получена из различных стековых потоков иKeras github отправляет сообщения, но я не могу заставить все работать под одним капотом.

Если бы кто-то мог мне помочь, даже переработав то, что у меня ниже, я был бы в восторге.Я читал каждый пост, который мог найти о потере триплета, но ничего не существовало, включая использование нескольких экземпляров flow_from_dataframe.

bs = 32

train_gen = ImageDataGenerator(rescale = 1/.255,
                                     shear_range = 0.2,
                                     zoom_range = 0.2,
                                     horizontal_flip = False)


def generate_generator_triplet(generator, df, path1, batch_size, img_height, img_width):
    gen_anchor = generator.flow_from_dataframe(dataframe = df,
                                          directory = path1,
                                          x_col = 'Anchor_Image',
                                          y_col = 'Anchor_Id',
                                          target_size = (img_height,img_width),
                                          class_mode = 'categorical',
                                          batch_size = batch_size,
                                          shuffle=False, 
                                          seed=8,
                                          drop_duplicates = False)

    gen_pos = generator.flow_from_dataframe(dataframe = df,
                                          directory = path1,
                                          x_col = 'Pos_Image',
                                          y_col = 'Pos_Id',
                                          target_size = (img_height,img_width),
                                          class_mode = 'categorical',
                                          batch_size = batch_size,
                                          shuffle=False, 
                                          seed=8,
                                          drop_duplicates = False)

    gen_neg = generator.flow_from_dataframe(dataframe = df,
                                          directory = path1,
                                          x_col = 'Neg_Image',
                                          y_col = 'Neg_Id',
                                          target_size = (img_height,img_width),
                                          class_mode = 'categorical',
                                          batch_size = batch_size,
                                          shuffle=False, 
                                          seed=8,
                                          drop_duplicates = False)


    while True:
            Anchori = gen_anchor.next()
            Posi = gen_pos.next()
            Negi = gen_neg.next()
            yield [Anchori[0], Posi[0], Negi[0]], Anchori[1]

inputgenerator = generate_generator_triplet(generator=train_gen,
                                           df = new,
                                           path1=path,
                                           batch_size=bs,
                                           img_height=128,
                                           img_width=128)

## Triplet Loss
ALPHA = .2

def triplet_loss(y_true, y_pred, alpha = ALPHA):


    anchor, pos, neg = y_pred[0], y_pred[1], y_pred[2]

    pos_dist = K.sum(K.square(anchor - pos), axis = 0)
    neg_dist = K.sum(K.square(anchor - neg), axis = 0)

    loss = K.maximum(pos_dist - neg_dist + alpha, 0.0)

    return loss


## Model Construction

data_input = Input(shape = [128,128,3])
siam = Conv2D(64, (4,4), strides = (1,1))(data_input)
siam = Activation(activation = 'relu')(siam)
siam = Conv2D(128, (5,5), strides = (1,1))(siam)
siam = Activation(activation = 'relu')(siam)
siam = MaxPooling2D()(siam)

siam = Flatten()(siam)
siam = Dense(64)(siam)
siam = Activation(activation = 'relu')(siam)

siam = Dense(512)(siam)
out = Activation(activation = 'sigmoid')(siam)

siam_model = Model(inputs = data_input, outputs = out)

anchor_input = Input(shape = [128, 128, 3])
pos_input = Input(shape = [128, 128, 3])
neg_input = Input(shape = [128, 128, 3])

anchor_embed = siam_model(anchor_input)
pos_embed = siam_model(pos_input)
neg_embed = siam_model(neg_input)

optimizer = Adam(0.00006)

siamese_net = Model(inputs = [anchor_input, pos_input, neg_input],
                    outputs = [anchor_embed, pos_embed, neg_embed])

siamese_net.compile(optimizer = optimizer, loss = triplet_loss, metrics = ['accuracy'])

siamese_net.summary()

siamese_net.fit_generator(inputgenerator,
                steps_per_epoch = len(new)/bs,
                epochs = 5,
                shuffle = False
                #,validation_data = ([test_left, test_right], test_targets)
                )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...