如何修复Python Tensorflow Triplet Loss中的'ValueError:没有为任何变量提供渐变'错误

时间:2019-02-10 20:25:21

标签: python tensorflow

import cv2
import numpy as np
import tensorflow as tf


class Aclass:
    def __init__(self, xtrain, ytrain, xtest, ytest, batch_size: int = 32, epochs: int = 10):
        self.x_train, self.y_train, self.x_test, self.y_test = xtrain, ytrain, xtest, ytest
        self.margin = 1.0
        self.chnls = self.x_train.shape[-1]
        self.classes = list(set([int(n) for n in self.y_train.tolist()]))
        self.optimizer = tf.train.AdamOptimizer
        self.batch_size = batch_size
        self.epochs = epochs
        self.training_init_op = None
        self.next_element = None
        self.global_step = None
        self.cost = None

        with tf.name_scope("Train"):
            self.x_image = tf.placeholder(tf.float32,
                                          [None, self.x_train.shape[1], self.x_train.shape[2], self.chnls], name="Xn")
            self.x_image_pos = tf.placeholder(tf.float32,
                                            [None, self.x_train.shape[1], self.x_train.shape[2], self.chnls], name='Xp')
            self.x_image_neg = tf.placeholder(tf.float32,
                                            [None, self.x_train.shape[1], self.x_train.shape[2], self.chnls], name='Xe')

            self.y_label = tf.placeholder(tf.float32, [None, ])

            self.features_placeholder = tf.placeholder(self.x_train.dtype, self.x_train.shape)
            self.labels_placeholder = tf.placeholder(self.y_train.dtype, self.y_train.shape)

    def set_up(self):
        self.cost = self.calculate_stuff(self.x_image, self.x_image_pos, self.x_image_pos)
        self.global_step = tf.Variable(0, name='global_step', trainable=False)

        train_opt = self.training(self.cost, self.global_step)
        saverq = tf.train.Saver()

        training_dataset = tf.data.Dataset.from_tensor_slices((self.features_placeholder, self.labels_placeholder))
        batched_dataset = training_dataset.batch(self.batch_size)

        self.training_init_op = batched_dataset.make_initializable_iterator()
        self.next_element = self.training_init_op.get_next()

        return train_opt, saverq

    def calculate_stuff(self, anchor, positive, negative):
        d_pos = tf.reduce_sum(tf.square(anchor - positive), 1)
        d_neg = tf.reduce_sum(tf.square(anchor - negative), 1)

        loss = tf.maximum(0., self.margin + d_pos - d_neg)
        loss = tf.reduce_mean(loss)

        return loss

    def training(self, cost, global_step):
        learning_rate = tf.train.exponential_decay(0.01, global_step, 100, 0.96, staircase=True)
        optimizer = self.optimizer(learning_rate)
        train_opt = optimizer.minimize(cost, global_step=global_step)

        return train_opt

    def make_model(self):
        conv1 = tf.layers.conv2d(self.x_image, 32, kernel_size=[7, 7], padding="same", activation=tf.nn.relu)
        norm1 = tf.layers.batch_normalization(conv1)
        pool1 = tf.layers.max_pooling2d(inputs=norm1, pool_size=[2, 2], strides=2)

        conv2a = tf.layers.conv2d(inputs=pool1, filters=32, kernel_size=[1, 1], padding="same", activation=tf.nn.relu)
        conv2 = tf.layers.conv2d(inputs=conv2a, filters=64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu)
        norm2 = tf.layers.batch_normalization(conv2)
        pool2 = tf.layers.max_pooling2d(inputs=norm2, pool_size=[2, 2], strides=2)

        conv3a = tf.layers.conv2d(inputs=pool2, filters=32, kernel_size=[1, 1], padding="same", activation=tf.nn.relu)
        conv3 = tf.layers.conv2d(inputs=conv3a, filters=64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu)

        conv4a = tf.layers.conv2d(inputs=conv3, filters=32, kernel_size=[1, 1], padding="same", activation=tf.nn.relu)
        conv4 = tf.layers.conv2d(inputs=conv4a, filters=64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu)

        flat = tf.reshape(conv4, [-1, 7 * 7 * 64])

        fc_1 = tf.layers.dense(inputs=flat, units=128, activation=tf.nn.relu)

        embed = tf.layers.dense(inputs=fc_1, units=128)

        output = tf.nn.l2_normalize(embed, axis=1, epsilon=1e-12, name=None)

        return output

    def get_data(self, y_label, test: bool = False, is_equal: bool = True):
        indexs = []

        ydata = self.y_train
        xdata = self.x_train
        if test:
            ydata = self.y_test
            xdata = self.x_test

        if is_equal:
            indexs = np.where(np.array([int(n) for n in ydata.tolist()]) == int(y_label))[0]

        if not is_equal:
            indexs = np.where(np.array([int(n) for n in ydata.tolist()]) != int(y_label))[0]

        labels = ydata[indexs]
        images = xdata[indexs]

        return labels, images

    def run(self):
        init_op_l = tf.global_variables_initializer()

        with tf.Session() as sess:
            sess.run(init_op_l)

            for epoch in range(self.epochs):
                sess.run(self.training_init_op.initializer, feed_dict={self.features_placeholder: self.x_train,
                                                                  self.labels_placeholder: self.y_train})
                for cls in self.classes:
                    al_y_true_labels, al_x_true_images = self.get_data(int(cls), False, True)
                    al_y_false_labels, al_x_false_images = self.get_data(int(cls), False, False)

                    for batch in range(int(al_x_true_images.shape[0] / self.batch_size)):
                        rnd = np.random.randint(0, int(al_x_true_images.shape[0]), self.batch_size)
                        rnd2 = np.random.randint(0, int(al_x_false_images.shape[0]), self.batch_size)

                        x_images = al_x_true_images[self.batch_size * batch: self.batch_size * (batch + 1)]
                        x_sames = al_x_true_images[rnd]
                        x_difs = al_x_false_images[rnd2]

                        _, avg_cost = sess.run([train_op, self.cost], feed_dict={
                            self.x_image: x_images,
                            self.x_image_pos: x_sames,
                            self.x_image_neg: x_difs
                        })

                        if batch % 10 == 0:
                            print(f"Epoch #: {epoch} - Batch #: {batch} - loss: {avg_cost}")

                    saver.save(sess, "model_logs/model.h5")

            print("Optimization Finished!")

if __name__ == '__main__':
    TRAIN = True
    (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

    x_train = (x_train / 255).reshape(-1, x_train.shape[1], x_train.shape[2], 1).astype('float32')
    x_test = (x_test / 255).reshape(-1, x_test.shape[1], x_test.shape[2], 1).astype('float32')

    if TRAIN:
        hog = Aclass(x_train, y_train, x_test, y_test, epochs=3, batch_size=16)

        output_l = hog.make_model()
        train_op, saver = hog.set_up()
        hog.run()

我的TensorFlow-> 1.12.0

嗨,大家好!

我想按标签加载图像(我使用'get_data'函数执行此操作),并使用'三重损失'方法对它们进行分类,但是我遇到了此错误(当我使用tf.contrib.losses.metric_learning.triplet_semihard_loss和给y_label所有图像,但我想自己选择图像)->

ValueError: No gradients provided for any variable, check your graph for ops that do not support gradient

我的真实观点是将其用于人脸分类器,但我想在mnist上构建它,并稍后在人脸数据集上使用。

如果您能提供帮助,我将很高兴

0 个答案:

没有答案