mxnet 参数共享的一些理解【转载】【侵权删】

1.参数共享,梯度也共享,但梯度计算是对所有共享层的梯度计算并加和

原文来自:模型参数的访问、初始化和共享 讨论区 - 课程讨论 - MXNet / Gluon 论坛

假设不共享的时候,第一层参数w1的导数为w1_grad,第二层参数w2的导数为w2_grad。
参数共享之后,w1和w2变为同一个自变量,这个自变量的导数为“w1_grad + w2_grad”。
编程验证方法:
建立两个网络,net1 和 net2.
net1 和 net2 的结构相同,参数初始值相同,loss相同,输入的x相同。
唯一不同的是:
(1)net1 每一层参数都是独立的。
第一层参数为w1,第三层参数为w3。w1 和 w3 数值相等,但是分别占用不同的存储空间。
(2)net2的 第一层 和 第三层 共享参数。
第一层参数 和 第三层参数 都是为w。并且设置 w = w1 = w3。
对两个网络定义相同的loss,然后采用相同的输入x,进行 前向传播 和 后向传播。
然后查看各个参数的grad。
预期结果:w.grad == w1.grad +w2.grad。

from mxnet import autograd, nd
from mxnet.gluon import loss as gloss

# 生成测试数据
X = nd.random.uniform(shape=(2, 20))
y = nd.random.uniform(shape=(2, 10))

# 创建共享参数的网络
# 第二隐藏层(shared变量)和第三隐藏层共享模型参数
net_shared = nn.Sequential()
shared = nn.Dense(8, activation='relu')
net_shared.add(nn.Dense(8, activation='relu'),
               shared,
               nn.Dense(8, activation='relu', params=shared.params),
               nn.Dense(10))

# 创建普与参数共享网络结构相同的普通网络
net_woShared = nn.Sequential()
net_woShared.add(nn.Dense(8, activation='relu'),
                 nn.Dense(8, activation='relu'),
                 nn.Dense(8, activation='relu'),
                 nn.Dense(10))

# 初始化网络,并进行前向传播
net_shared.initialize()
y_shared_hat = net_shared(X)

net_woShared.initialize()
y_woShared_hat = net_woShared(X)

# 两个网络参数不同,所以前向传播的结果不相同。
print('y_woShared_hat == y_shared_hat')
print(y_woShared_hat == y_shared_hat)


# 修改普通网络的参数,使其与 共享参数网络 中的参数相同。
net_woShared[0].weight.set_data(net_shared[0].weight.data())
net_woShared[0].bias.set_data(net_shared[0].bias.data())
net_woShared[1].weight.set_data(net_shared[1].weight.data())
net_woShared[1].bias.set_data(net_shared[1].bias.data())
net_woShared[2].weight.set_data(net_shared[2].weight.data())
net_woShared[2].bias.set_data(net_shared[2].bias.data())
net_woShared[3].weight.set_data(net_shared[3].weight.data())
net_woShared[3].bias.set_data(net_shared[3].bias.data())

# 修改参数之后,再一次前向传播
y_woShared_hat = net_woShared(X)

# 两个网络的参数相同,所以前向传播的结果相同。
y_woShared_hat == y_shared_hat
print('y_woShared_hat == y_shared_hat')
print(y_woShared_hat == y_shared_hat)


# 定义损失函数
loss = gloss.L2Loss()

# 先进行前向传播,然后后向传播计算梯度
with autograd.record():
    l = loss(net_woShared(X), y)
l.backward()

# 先进行前向传播,然后后向传播计算梯度
with autograd.record():
    l = loss(net_shared(X), y)
l.backward()

# 参数共享网络第二隐藏层的梯度 等于 非参数共享网络中 第二隐藏层和第三隐藏层的梯度 相加
net_shared[1].weight.grad() == net_woShared[1].weight.grad()  + net_woShared[2].weight.grad() 
print('net_shared[1].weight.grad() == net_woShared[1].weight.grad()  + net_woShared[2].weight.grad() ')
print(net_shared[1].weight.grad() == net_woShared[1].weight.grad()  + net_woShared[2].weight.grad() )

2.参数共享,梯度也共享,所以进行后向传播梯度只更新一次,然后共享

模型参数的访问、初始化和共享 讨论区 - 课程讨论 - MXNet / Gluon 论坛

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值