Pytorch:torch.cat创建新的独立向量

时间:2020-04-03 10:34:00

标签: python machine-learning deep-learning concatenation pytorch

我是Pytorch的新手,在torch.cat遇到问题。

在我的场景中,我有一个训练有素的模型,该模型基本上是矢量矩阵,我想执行以下操作:

  • 向训练后的模型添加新矢量;
  • 将其连接到预先存在的向量矩阵;
  • 进行几次迭代,仅训练新的矢量,同时保持已冻结的旧的矢量“冻结”

这是我的计算和问题的最小示例:

    import torch
    from torch import optim
    from torch.nn.parameter import Parameter

    # the old, already-trained vectors (2 vecs with 5 elements each)
    old_vecs = torch.rand(2, 5)

    # the new vector to train (1 vec with 5 elements). 
    # This has to be a Parameter, so it can be passed to an Optimizer to have it trained
    new_vec = Parameter(torch.rand(1, 5))

    # concatenate old_vecs and new_vec
    all_vecs = torch.cat((old_vecs, new_vec), 0)

    # create the Optimizer with the new_vec to train
    optimizer = optim.SGD([new_vec], lr=1e-1)
    for epoch in range(5):
        loss = all_vecs.sum()
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

通过打印训练前后的向量值,我获得了以下读数:

    new_vec before training:
    Parameter containing: tensor([[0.4151, 0.6478, 0.5142, 0.2373, 0.5643]], requires_grad=True)

    new_vec after training:
    Parameter containing: tensor([[-0.0849,  0.1478,  0.0142, -0.2627,  0.0643]], requires_grad=True)

    all_vecs[2] after training:
    tensor([0.4151, 0.6478, 0.5142, 0.2373, 0.5643], grad_fn=<SelectBackward>)

很明显,new_vec已更新,但all_vecs [2]未更新。 显然,当运行torch.cat时,将生成新的张量all_vecs 具有独立的内容。所以vec_new和all_vecs [2]具有独立的值,并且由于我唯一的参数是new_vec,因此all_vecs [2]就像旧的冻结矢量一样。

这是问题,因为我的损失是根据all_vecs计算的,而不是根据new_vec计算的。 由于all_vecs无法更改,因此损耗及其梯度将永远不会减少(当然,这将影响new_vec的训练方式)。

我可以通过在每次迭代时手动更新all_vecs [2]的值来轻松解决问题:

    for epoch in range(5):
        with torch.no_grad():
            all_vecs[2] = new_vec
        loss = all_vecs.sum()
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

但是说实话,这感觉像是一个bad头,我需要使我的代码尽可能“干净”。 有什么建议?除了不为张量值分配新内存之外,torch.cat还有其他替代方法吗?

0 个答案:

没有答案
相关问题