【发布时间】:2020-10-28 18:15:27
【问题描述】:
正如标题所示,我正在尝试基于 SimCLR 框架训练模型(见本文:https://arxiv.org/pdf/2002.05709.pdf - NT_Xent 损失在等式 (1) 和算法 1 中说明)。
我已经设法创建了损失函数的 numpy 版本,但这不适合训练模型,因为 numpy 数组无法存储反向传播所需的信息。我很难将我的 numpy 代码转换为 Tensorflow。这是我的 numpy 版本:
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# Define the contrastive loss function, NT_Xent
def NT_Xent(zi, zj, tau=1):
""" Calculates the contrastive loss of the input data using NT_Xent. The
equation can be found in the paper: https://arxiv.org/pdf/2002.05709.pdf
Args:
zi: One half of the input data, shape = (batch_size, feature_1, feature_2, ..., feature_N)
zj: Other half of the input data, must have the same shape as zi
tau: Temperature parameter (a constant), default = 1.
Returns:
loss: The complete NT_Xent constrastive loss
"""
z = np.concatenate((zi, zj), 0)
loss = 0
for k in range(zi.shape[0]):
# Numerator (compare i,j & j,i)
i = k
j = k + zi.shape[0]
sim_ij = np.squeeze(cosine_similarity(z[i].reshape(1, -1), z[j].reshape(1, -1)))
sim_ji = np.squeeze(cosine_similarity(z[j].reshape(1, -1), z[i].reshape(1, -1)))
numerator_ij = np.exp(sim_ij / tau)
numerator_ji = np.exp(sim_ji / tau)
# Denominator (compare i & j to all samples apart from themselves)
sim_ik = np.squeeze(cosine_similarity(z[i].reshape(1, -1), z[np.arange(z.shape[0]) != i]))
sim_jk = np.squeeze(cosine_similarity(z[j].reshape(1, -1), z[np.arange(z.shape[0]) != j]))
denominator_ik = np.sum(np.exp(sim_ik / tau))
denominator_jk = np.sum(np.exp(sim_jk / tau))
# Calculate individual and combined losses
loss_ij = - np.log(numerator_ij / denominator_ik)
loss_ji = - np.log(numerator_ji / denominator_jk)
loss += loss_ij + loss_ji
# Divide by the total number of samples
loss /= z.shape[0]
return loss
我相当有信心这个函数会产生正确的结果(尽管速度很慢,因为我在网上看到了它的其他矢量化版本的实现——例如 Pytorch 的这个:https://github.com/Spijkervet/SimCLR/blob/master/modules/nt_xent.py(我的代码产生了相同的结果)相同的输入),但我看不出它们的版本在数学上如何等同于论文中的公式,因此我尝试构建自己的版本)。
作为第一次尝试,我已将 numpy 函数转换为它们的 TF 等效项(tf.concat、tf.reshape、tf.math.exp、tf.range 等),但我相信我唯一/主要的问题是sklearn的cosine_similarity函数返回一个numpy数组,我不知道自己在Tensorflow中如何构建这个函数。有什么想法吗?
【问题讨论】:
标签: python tensorflow scikit-learn backpropagation cosine-similarity