为自动编码器重建丢失添加自定义丢失

时间:2017-11-02 14:52:16

标签: python tensorflow autoencoder

这是我在这里发表的第一篇文章,所以我希望它符合指南,除了我自己以外的其他人也很有意思。

我正在构建一个CNN自动编码器,它采用固定大小的输入矩阵,目的是获得它们的低维表示(我在这里称它们为哈希)。当矩阵相似时,我想使这些哈希值相似。由于我的数据只有少数标记,我想将损失函数组合成两个独立的函数。一部分是自动编码器的重建错误(这部分正常工作)。另一部分,我希望它是标记数据。由于我将有三个不同的类,我想在每个批处理中计算属于同一个类的哈希值之间的距离(我在实现它时遇到了麻烦)。

到目前为止我的努力:

X = tf.placeholder(shape=[None, 512, 128, 1], dtype=tf.float32)
class1_indices = tf.placeholder(shape=[None], dtype=tf.int32)
class2_indices = tf.placeholder(shape=[None], dtype=tf.int32)
hashes, reconstructed_output = self.conv_net(X, weights, biases_enc, biases_dec, keep_prob)
class1_hashes = tf.gather(hashes, class1_indices)
class1_cost = self.calculate_within_class_loss(class1_hashes)
class2_hashes = tf.gather(hashes, class2_indices)
class2_cost = self.calculate_within_class_loss(class2_hashes)
loss_all = tf.reduce_sum(tf.square(reconstructed_output - X))
loss_labeled = class1_cost + class2_cost
loss_op = loss_all + loss_labeled
optimizer = tf.train.AdagradOptimizer(learning_rate=learning_rate)
train_op = optimizer.minimize(loss_op)

其中calclulate_within_class_loss是我创建的单独函数。我目前只实现了它的一个类的第一个哈希与同一批次中该类的其他哈希的区别,但是,我对我当前的实现不满意,看起来它不起作用。

def calculate_within_class_loss(self, hash_values):
    first_hash = tf.slice(hash_values, [0, 0], [1, 256])
    total_loss = tf.foldl(lambda d, e: d + tf.sqrt(tf.reduce_sum(tf.square(tf.subtract(e, first_hash)))), hash_values, initializer=0.0)
    return total_loss

所以,我有两个问题/问题:

  1. 有没有简单的方法来计算每个原始物与张量中所有其他原物的距离?
  2. 我目前在类距离内的计算实现,即使只是第一个元素与其他元素,在我尝试优化它时会给我一个'nan'。
  3. 感谢您的时间和帮助:)

1 个答案:

答案 0 :(得分:0)

在示例代码中,您正在计算点之间的Eucledian距离之和。

为此,您必须遍历整个数据集并执行O(n^2 * m)计算并获得O(n^2 * m)空间,即Tensorflow图操作。 这里,n是向量的数量,m是散列的大小,即256。

但是,如果您可以将对象更改为以下内容:

然后,您可以使用nifty relationship between the squared Euclidean distance and the variance并重写与

相同的计算

其中mu_k是群集的k坐标的平均值。

这将允许您计算O(n * m)时间和O(n * m) Tensorflow操作中的值。

如果您认为这种变化(即从欧氏距离到欧几里德距离的平方)不会对您的损失函数产生不利影响,那么这将是一种方法。