We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
实验一种共生模型,大致思想如下:
共生模型分为宿主模型:host 寄生模型:parasitic, 而 parasitic 能补足 host 的不足之处。
大致结构如下图: 每个节点代表一张 feature map,每层代表一个 Block
首先,选一个 base model 作为 host,host 先单独训练。
host 训练完成后,固定住 host 的参数,开始构建 parasitic,parasitic 的 block 数目和 host 相同
对于每一层 block,parasitic 的 Input 要 concat 上一层的 host 和 parasitic 的 Output .
因此,parasitic block 的 Input Channel 为 host 的 1.5 倍数 Output Channel 为 host 的 0.5 倍数,
以此,构建出寄生于 host 的 parasitic 主干网络
接下来移植 TreeSegNet 中的构建树状网络的方法,根据 host 在 validation set 上的性能,构建一颗树状网络:Tree net
将 Tree net, 接在 parasitic 主干网络后面, 使得整个 parasitic 能够学到 host 的不足之处
接下来训练 parasitic 网络,此时 host 的参数是固定的。为避免多余的计算,传给 parasitic 的 feature 要 detach
通过看 pytorch-summary 的源码,学会了通过 model.apply(regist_hook) 注册 hook 函数来探索网络内部结构,这个操作非常 Hack,但坑也特别多,下文会说。
model.apply(regist_hook)
使用 model.apply(regist_hook) 实现了自动检测 host 的网络结构及每个 block 的内部信息,并自动构建出对应的 parasitic 主干网络
接下来就是训练过程,一开始 我的方案是在 parasitic 内的 self.host=host 使 host 成为 parasitic 的子网络。
self.host=host
在 parasitic.foward(x) 内部, 先用 self.host.eval() 阻止计算 host 的 grad,再通过 self.host.apply(regist_hook) 注册提取 feature 的钩子函数, 在 self.host(x) 后, 便能通过钩子函数 提取出 host 的 feature。
parasitic.foward(x)
self.host.eval()
self.host.apply(regist_hook)
self.host(x)
这样下来发觉计算很慢,一个 epoch 比以前多花几倍的时间。经排查,在host.eval()模式下,host 网络参数的 grad 本应该为 None ,而运行后该参数的 grad 为 0矩阵。这说明 self.host.eval() 失效,整个 host 计算了 grad,哪怕 detach 了,也只是把 detach 部分的导数设置为 0,继续向后计算 grad。这个问题和之前提出来的 不在计算图中仍会计算 grad 的 issue 很相似
host.eval()
None
为避免 host.grad 的无效计算,不能把 host 作为 parasitic 的子网络。于是,我直接把 host 放到 parasitic 外部 作为全局变量,在 parasitic.foward(x) 内部再调用 host(x) 提取 feature。 这种方案在单卡上表现完美。但在多卡情况下,系统复杂性上升了一个数量集,各种错误。
(下都以双卡为例) 在多卡中,module 要被封装成为 torch.nn.DataParallel 通过查看文档和源码,DataParallel 的原理是:
因此,parasitic.foward(x) 内部的 x 是被 DataParallel 分离出来的 半个 batch_size 的 x_i 了, 而且 x_i 已经是分配到了特定卡上的变量, 只有也在特定卡上的 module 才能处理
我还试过把 feature 打包为 list,作为 host 的输出,再传入 parasitic,但实验发现 DataParallel 只允许 return tensor,遂作罢。
经过不断的实验,最后多卡提取 feature 的方案是:在运行 parasitic.foward(x) 前,先运行 host(x) 并通过钩子函数将 host 的 feature 存储到全局变量 shareDic。钩子函数会根据 feature 所在的 device.id 把 feature 分开存储。在 parasitic.foward(x) 时,会根据 x 所在的 device.id 提取 shareDic 中对应 device 上的 feature ,然后前向计算 parasitic 的输出。
host(x)
实验表面 上述方法可在 多卡中正常运行,不会计算 host 的 grad,单个 epoch 的时间也下降到了正常水平。
在上述实验中:
接下来还要把 TreeSegNet 中的 tree net 接上, 再跑实验
mapmp
mapmt
setup.py
pip install boxx
$DISPLAY
logc
>>> from boxx import logc >>> a, b = 1, 2 >>> logc("c = a + b") Code: c = a + b └──—— 3 = 1 + 2
The text was updated successfully, but these errors were encountered:
需要约个事件当面讨论
Sorry, something went wrong.
No branches or pull requests
Review
一. 在 Furniture 数据集上实验一种共生模型
1. 实验简介
实验一种共生模型,大致思想如下:
共生模型分为宿主模型:host 寄生模型:parasitic, 而 parasitic 能补足 host 的不足之处。
大致结构如下图:
每个节点代表一张 feature map,每层代表一个 Block
首先,选一个 base model 作为 host,host 先单独训练。
host 训练完成后,固定住 host 的参数,开始构建 parasitic,parasitic 的 block 数目和 host 相同
对于每一层 block,parasitic 的 Input 要 concat 上一层的 host 和 parasitic 的 Output .
因此,parasitic block 的 Input Channel 为 host 的 1.5 倍数 Output Channel 为 host 的 0.5 倍数,
以此,构建出寄生于 host 的 parasitic 主干网络
接下来移植 TreeSegNet 中的构建树状网络的方法,根据 host 在 validation set 上的性能,构建一颗树状网络:Tree net
将 Tree net, 接在 parasitic 主干网络后面, 使得整个 parasitic 能够学到 host 的不足之处
接下来训练 parasitic 网络,此时 host 的参数是固定的。为避免多余的计算,传给 parasitic 的 feature 要 detach
2. 实现过程 (踩坑记)
通过看 pytorch-summary 的源码,学会了通过
model.apply(regist_hook)
注册 hook 函数来探索网络内部结构,这个操作非常 Hack,但坑也特别多,下文会说。使用
model.apply(regist_hook)
实现了自动检测 host 的网络结构及每个 block 的内部信息,并自动构建出对应的 parasitic 主干网络接下来就是训练过程,一开始 我的方案是在 parasitic 内的
self.host=host
使 host 成为 parasitic 的子网络。在
parasitic.foward(x)
内部, 先用self.host.eval()
阻止计算 host 的 grad,再通过self.host.apply(regist_hook)
注册提取 feature 的钩子函数, 在self.host(x)
后, 便能通过钩子函数 提取出 host 的 feature。这样下来发觉计算很慢,一个 epoch 比以前多花几倍的时间。经排查,在
host.eval()
模式下,host 网络参数的 grad 本应该为None
,而运行后该参数的 grad 为 0矩阵。这说明self.host.eval()
失效,整个 host 计算了 grad,哪怕 detach 了,也只是把 detach 部分的导数设置为 0,继续向后计算 grad。这个问题和之前提出来的 不在计算图中仍会计算 grad 的 issue 很相似为避免 host.grad 的无效计算,不能把 host 作为 parasitic 的子网络。于是,我直接把 host 放到 parasitic 外部 作为全局变量,在
parasitic.foward(x)
内部再调用 host(x) 提取 feature。这种方案在单卡上表现完美。但在多卡情况下,系统复杂性上升了一个数量集,各种错误。
(下都以双卡为例)
在多卡中,module 要被封装成为 torch.nn.DataParallel
通过查看文档和源码,DataParallel 的原理是:
因此,
parasitic.foward(x)
内部的 x 是被 DataParallel 分离出来的 半个 batch_size 的 x_i 了, 而且 x_i 已经是分配到了特定卡上的变量, 只有也在特定卡上的 module 才能处理我还试过把 feature 打包为 list,作为 host 的输出,再传入 parasitic,但实验发现 DataParallel 只允许 return tensor,遂作罢。
经过不断的实验,最后多卡提取 feature 的方案是:在运行
parasitic.foward(x)
前,先运行host(x)
并通过钩子函数将 host 的 feature 存储到全局变量 shareDic。钩子函数会根据 feature 所在的 device.id 把 feature 分开存储。在parasitic.foward(x)
时,会根据 x 所在的 device.id 提取 shareDic 中对应 device 上的 feature ,然后前向计算 parasitic 的输出。实验表面 上述方法可在 多卡中正常运行,不会计算 host 的 grad,单个 epoch 的时间也下降到了正常水平。
在上述实验中:
接下来还要把 TreeSegNet 中的 tree net 接上, 再跑实验
二. 完善工具库 Box-X
mapmp
、mapmt
setup.py
打包到了PyPI, 可通过pip install boxx
安装$DISPLAY
为空的情况logc
(log code)三. 看了两集台大李宏毅的 Machine Learning and having it deep and structured
Next
The text was updated successfully, but these errors were encountered: