pytorch两个层叠网络如何联合训练,梯度传播是否会有问题(比如在后面一个网络断开了)

作者:xaipxan
链接:https://www.zhihu.com/question/322192259/answer/749589285
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

对于两个net1 net2两个网络,如何同时反向传播。

对于这个问题,我自己做过简陋的实验。

x = torch.rand(2, 3)
net1 = nn.Linear(3, 3)
net2 = nn.Linear(3, 3)
a = net1(x)
b = net2(a)

tgt = torch.rand(2, 3)
loss_fun = torch.nn.MSELoss()
opt1 = torch.optim.Adam(net1.parameters(), 0.002)
opt2 = torch.optim.Adam(net2.parameters(), 0.002)

for i in range(100):
    tmp = net1(x)
    output = net2(tmp)
    loss = loss_fun(output, tgt)

    net1.zero_grad()
    net2.zero_grad()

    loss.backward()
    opt1.step()
    opt2.step()

    print('EPOCH:{},loss={}'.format(i, loss))

aa = net1(x)
bb = net2(aa)

print(a)
print(aa)
print(b)
print(bb)

先建立两个网络net1和net2,把net1的输出再输入net2 。

目的是用训练之前的net1输出a 和 net2输出b对比训练后的net1输出aa和net2输出bb。

训练中是net1用opt1(adam)优化,net2用opt2(adam)优化。

结果是a和aa,b和bb都不一样。说明权重得到了训练或者说发生了改变。

之后再用一个net把net1和net2封装进去。

xx = torch.rand(2, 3)


class net(nn.Module):
    def __init__(self):
        super().__init__()
        self.n1 = nn.Linear(3, 3)
        self.n2 = nn.Linear(3, 3)

    def forward(self, xx):
        output = self.n1(xx)
        print(output)
        output = self.n2(output)

        return output


n = net()

tgt = torch.rand(2, 3)
loss_fun = torch.nn.MSELoss()
opt_n = torch.optim.Adam(n.parameters(), 0.002)

for i in range(100):
    outout = n(xx)
    loss = loss_fun(outout, tgt)

    n.zero_grad()

    loss.backward()
    opt_n.step()
    print('EPOCH:{},loss={}'.format(i, loss))

目的跟之前的一样。

在net的forward的部分屏幕打印出net1的输出,方便观察每次输出的矩阵跟之前的一样否。

跟之前的不同的是这次只需要优化net一个的就可以了。

分割线

就像encoder-decoder网络一样,有些人是各自写完class encoder和class decoder后把他们装进class net中。这样只需要优化net的参数即可。

有些人喜欢用两个opt各自优化encoder和decoder的参数。

效果一样。

 

 

 

所以上面结果梯度传播并不会有问题,可以正常训练。

你可能感兴趣的:(pytorch两个层叠网络如何联合训练,梯度传播是否会有问题(比如在后面一个网络断开了))