【发布时间】:2020-04-02 22:41:14
【问题描述】:
我正在尝试使用 PyTorch 以交替方式优化两个模型。第一个是一个神经网络,它正在改变我的数据的表示(即我的输入数据 x 上的映射 f(x),由一些权重 W 参数化)。第二个是在 f(x) 点上运行的高斯混合模型,即在神经网络空间中(而不是在输入空间中聚类点。我正在使用期望最大化来优化 GMM,因此参数更新是解析推导的,而不是使用梯度下降。
我这里有两个损失函数:第一个是距离||f(x) - f(y)||的函数,第二个是高斯混合模型的损失函数(即如何'聚集'一切看起来都在 NN 表示空间中)。我想要做的是使用上述两个损失函数(因为它取决于两者)在 NN 优化中迈出一步,然后对 GMM 执行期望最大化步骤。代码看起来像这样(因为代码很多,我删除了很多):
data, labels = load_dataset()
net = NeuralNetwork()
net_optim = torch.optim.Adam(net.parameters(), lr=0.05, weight_decay=1)
# initialize weights, means, and covariances for the Gaussian clusters
concentrations, means, covariances, precisions = initialization(net.forward_one(data))
for i in range(1000):
net_optim.zero_grad()
pairs, pair_labels = pairGenerator(data, labels) # samples some pairs of datapoints
outputs = net(pairs[:, 0, :], pairs[:, 1, :]) # computes pairwise distances
net_loss = NeuralNetworkLoss(outputs, pair_labels) # loss function based on pairwise dist.
embedding = net.forward_one(data) # embeds all data in the NN space
log_prob, log_likelihoods = expectation_step(embedding, means, precisions, concentrations)
concentrations, means, covariances, precisions = maximization_step(embedding, log_likelihoods)
gmm_loss = GMMLoss(log_likelihoods, log_prob, precisions, concentrations)
net_loss.backward(retain_graph=True)
gmm_loss.backward(retain_graph=True)
net_optim.step()
基本上,这就是正在发生的事情:
- 从数据集中抽取一些点对
- 通过 NN 推送点对并根据这些输出计算网络损失
- 使用 NN 嵌入所有数据点并在该嵌入空间中执行聚类 EM 步骤
- 根据聚类参数计算变分损失 (ELBO)
- 同时使用变分损失和网络损失更新神经网络参数
但是,要执行(5),我需要添加标志retain_graph=True,否则我会收到错误:
RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time.
似乎有两个损失函数意味着我需要保留计算图?
我不确定如何解决这个问题,就像 retain_graph=True 一样,在迭代 400 左右,每次迭代大约需要 30 分钟才能完成。有谁知道我该如何解决这个问题?我提前道歉——我对自动微分还很陌生。
【问题讨论】:
标签: python machine-learning pytorch mixture-model