Неравномерность размеров в операторе 'mul' тензорного потока - PullRequest
1 голос
/ 01 июля 2019

У меня есть сеть, в которую я передаю изображения с 6 объектами разных цветов и 2 уникальными формами. Изображения имеют тип RGB с размерами 75. Для каждого изображения есть два набора по 10 вопросов, один - набор относительных вопросов, а другой - набор не относительных вопросов. Каждый вопрос имеет длину 11, а соответствующий ответ имеет длину 10, где и вопрос, и ответ на самом деле представляют собой вектор с горячим кодированием.

Ниже приведена форма моей сети:

class Model:
    def __init__(self):
        self.model = Sequential()
        self.model.add(Conv2D(24, 3, 2, 'valid', input_shape=(75, 75, 3)))
        self.model.add(BatchNormalization())
        self.model.add(Conv2D(24, 3, 2))
        self.model.add(BatchNormalization())
        self.model.add(Conv2D(24, 3, 2))
        self.model.add(BatchNormalization())
        self.model.add(Conv2D(24, 3, 2))
        self.model.add(BatchNormalization())
        self.model.add(Flatten())

    def get_model(self):
        return self.model


class CNN_MLP:
    def __init__(self, args):
        model = Model()
        self.model = model.get_model()
        self.optimizer = optimizers.Adam(lr=args.lr)
        self.sequence = Input(shape=(75, 75, 3), name='Sequence')
        self.features = Input(shape=(11,), name='Features')

    def get_model(self):
        self.model = self.extend_model(self.model)
        return self.model

    def extend_model(self, model):
        self.model = model
        conv_sequence = self.model(self.sequence)
        merged_features = concatenate([conv_sequence, self.features])
        fc1 = Dense(256, activation='relu')(merged_features)
        fc2 = Dense(256, activation='relu')(fc1)
        logits = Dense(10, activation='softmax')(fc2)

        self.model = tf.keras.models.Model(inputs=[self.sequence, self.features], outputs=[logits])
        self.model.compile(loss='categorical_crossentropy', optimizer=self.optimizer, metrics=['accuracy'])
        return self.model

У меня 20 тренировочных и 5 тестовых изображений. Используя тренировочные образы, я тренирую модель. Позже я использую ту же модель, чтобы предсказать вывод тестовых изображений. Тестирование выполняется следующим образом:

from tensorflow.keras import backend as K

def cvt_data_axis(data):
    img = [e[0] for e in data]
    qst = [e[1] for e in data]
    ans = [e[2] for e in data]
    return img, qst, ans

def tensor_data(data, i):
    img = tf.convert_to_tensor(np.asarray(data[0][bs*i:bs*(i+1)]),
                           dtype=tf.int64)
    qst = tf.convert_to_tensor(np.asarray(data[1][bs*i:bs*(i+1)]),
                           dtype=tf.int64)
    ans = tf.convert_to_tensor(np.asarray(data[2][bs*i:bs*(i+1)]),
                           dtype=tf.int64)
    input_img = tf.identity(img)
    input_qst = tf.identity(qst)
    label = tf.identity(ans)

def test(rel, norel):
    rel = cvt_data_axis(rel)
    norel = cvt_data_axis(norel)

    for batch_idx in range(len(rel[0]) // bs):
        tensor_data(rel, batch_idx)
        predictions = model.predict({'Sequence': input_img,
                                     'Features': input_qst},
                                    batch_size=bs,
                                    steps=20,
                                    verbose=1)

        # at the execution of next satement I will get the error
        rel_balanced_accuracy_score = balanced_recall(
            label,
            tf.convert_to_tensor(predictions, dtype=tf.int64)
        )

Внутри метода balanced_recall я выполняю оператор

true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)), axis=0).

Здесь я получаю ошибку Размеры должны быть равны, но равны 5 и 10 для 'mul' (op: 'Mul') с входными формами: [5], [100,10].

Каким-то образом для 5 тестовых изображений я получаю вывод (100, 10), который я не могу понять, почему. Может ли кто-нибудь помочь мне, указав на мою ошибку?

1 Ответ

0 голосов
/ 01 июля 2019

В целом есть 2 проблемы, которые приводят к путанице.

Выпуск 1:

Вы возвращаете логиты из вашей модели:

...
logits = Dense(10, activation='softmax')(fc2)
...

Таким образом, для каждого входного примера вы можете ожидать одну строку с 10 измерениями в качестве вывода. Обычно это используется для задач классификации, и каждая запись представляет вероятность того, что пример принадлежит данному классу.

Вы можете найти прогнозируемую категорию, взяв индекс наибольшего значения, используя tf.argmax

Выпуск 2:

Вы выполняете 20 шагов с размером пакета (предположительно 5?), Так что вы возвращаете несколько прогнозов, которые объединяются в одну последовательность путем вызова model.predict:

...
predictions = model.predict({'Sequence': input_img,
                                     'Features': input_qst},
                                    batch_size=bs,
                                    steps=20,
                                    verbose=1)
...

Это означает, что вы получаете 100 прогнозов назад (которые вы пытаетесь сравнить с 5 метками)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...