张量流'mul'运算符中的尺寸不相等

时间:2019-07-01 11:25:50

标签: python tensorflow keras

我有一个网络,可以向其中馈送带有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],[100,10]的“ mul”(op:“ Mul”)的尺寸必须为5和10。

以某种方式获得5张测试图像,我得到的输出(100,10)我无法理解为什么。有人可以帮我指出我的错误吗?

1 个答案:

答案 0 :(得分:0)

广泛地有两个导致混乱的问题。

问题1:

您正在从模型返回logit:

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

因此,对于每个输入示例,您都可以期望一行具有10维的输出。通常,这用于分类问题,每个条目代表该示例属于给定类的概率。

您可以通过使用tf.argmax

获取最高价值索引来找到预测类别。

问题2:

您正在以批处理大小(大概是5个?)运行20个步骤,因此您可以通过调用model.predict来获取多个预测,这些预测被串联为一个序列:

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

这意味着您将获得100个预测(试图与5个标签进行比较)