向自动编码器重建损失添加自定义损失
Add a custom loss to the autoencoder reconstruction loss
这是我第一次post来到这里,所以我希望它符合指南并且对除我以外的其他人也很有趣。
我正在构建一个 CNN 自动编码器,它将固定大小的输入矩阵作为输入矩阵,目的是获得它们的低维表示(我在这里称它们为哈希)。当矩阵相似时,我想让这些散列相似。由于只有少数数据被标记,我想使损失函数成为两个独立函数的组合。一部分是自动编码器的重建错误(这部分工作正常)。另一部分,我希望它用于标记数据。因为我将有三个不同的 classes,所以我希望在每个批次上计算属于相同 class 的哈希值之间的距离(我在实现这个时遇到了麻烦)。
我目前的努力:
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 是我创建的一个单独函数。我目前仅针对 class 的第一个哈希值与同一批次 class 的其他哈希值的差异实现了它,但是,我对当前的实现不满意,看起来它不管用。
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
所以,我有两个问题:
- 有什么简单的方法可以计算张量中每个原始数据与所有其他原始数据的距离吗?
- 我当前在 class 距离内计算的实现,即使它只是针对第一个元素和其他元素,在我尝试优化它时也会给我一个 'nan'。
感谢您的宝贵时间和帮助:)
在示例代码中,您正在计算点之间的欧几里得距离之和。
为此,您将必须遍历整个数据集并进行 O(n^2 * m)
计算并进行 O(n^2 * m)
space,即 Tensorflow 图形操作。
这里,n
是向量的数量,m
是散列的大小,即 256。
但是,如果您可以将对象更改为以下内容:
然后,您可以使用 nifty relationship between the squared Euclidean distance and the variance 并重写与
相同的计算
其中 mu_k
是群集的第 k
个坐标的平均值。
这将允许您在 O(n * m)
时间和 O(n * m)
Tensorflow 操作中计算值。
如果您认为这种变化(即从欧几里德距离到平方欧几里德距离)不会对您的损失函数产生不利影响,那么这就是方法。
这是我第一次post来到这里,所以我希望它符合指南并且对除我以外的其他人也很有趣。
我正在构建一个 CNN 自动编码器,它将固定大小的输入矩阵作为输入矩阵,目的是获得它们的低维表示(我在这里称它们为哈希)。当矩阵相似时,我想让这些散列相似。由于只有少数数据被标记,我想使损失函数成为两个独立函数的组合。一部分是自动编码器的重建错误(这部分工作正常)。另一部分,我希望它用于标记数据。因为我将有三个不同的 classes,所以我希望在每个批次上计算属于相同 class 的哈希值之间的距离(我在实现这个时遇到了麻烦)。
我目前的努力:
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 是我创建的一个单独函数。我目前仅针对 class 的第一个哈希值与同一批次 class 的其他哈希值的差异实现了它,但是,我对当前的实现不满意,看起来它不管用。
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
所以,我有两个问题:
- 有什么简单的方法可以计算张量中每个原始数据与所有其他原始数据的距离吗?
- 我当前在 class 距离内计算的实现,即使它只是针对第一个元素和其他元素,在我尝试优化它时也会给我一个 'nan'。
感谢您的宝贵时间和帮助:)
在示例代码中,您正在计算点之间的欧几里得距离之和。
为此,您将必须遍历整个数据集并进行 O(n^2 * m)
计算并进行 O(n^2 * m)
space,即 Tensorflow 图形操作。
这里,n
是向量的数量,m
是散列的大小,即 256。
但是,如果您可以将对象更改为以下内容:
然后,您可以使用 nifty relationship between the squared Euclidean distance and the variance 并重写与
相同的计算其中 mu_k
是群集的第 k
个坐标的平均值。
这将允许您在 O(n * m)
时间和 O(n * m)
Tensorflow 操作中计算值。
如果您认为这种变化(即从欧几里德距离到平方欧几里德距离)不会对您的损失函数产生不利影响,那么这就是方法。