python - Pytorch nn 模块泛化
问题描述
让我们看一下简单的类:
class Temp1(nn.Module):
def __init__(self, stateSize, actionSize, layers=[10, 5], activations=[F.tanh, F.tanh] ):
super(Temp1, self).__init__()
self.layer1 = nn.Linear(stateSize, layers[0])
self.layer2 = nn.Linear(layers[0], layers[1])
self.fcFinal = nn.Linear( layers[1], actionSize )
return
这是一个相当直接的 pytorch 模块。它创建了一个简单的顺序密集网络。如果我们检查它的隐藏参数,我们会看到以下内容:
t1 = Temp1(2, 2)
list(t1.parameters())
这是预期的结果...
[Parameter containing:
tensor([[-0.0311, -0.5513],
[-0.0634, -0.3783],
[-0.2514, 0.6139],
[ 0.4711, -0.0241],
[-0.1739, 0.2208],
[-0.1533, 0.3838],
[-0.6490, -0.5784],
[ 0.5312, 0.6703],
[ 0.3506, 0.3652],
[ 0.1768, -0.4158]], requires_grad=True), Parameter containing:
tensor([-0.3199, -0.4154, -0.5530, -0.6738, -0.4411, 0.2641, -0.3576, 0.0447,
0.0254, 0.0965], requires_grad=True), Parameter containing:
tensor([[-2.8257e-01, 6.7583e-02, 9.0356e-02, 1.0868e-01, 4.0876e-02,
4.0616e-02, 4.4419e-02, -8.1544e-02, 2.5244e-01, 3.8777e-03],
[-8.0950e-03, -1.4175e-01, -2.9492e-01, 3.1439e-01, -2.3065e-01,
-6.6631e-02, 3.0047e-01, 2.8353e-01, 2.3457e-01, -3.1399e-03],
[-5.2522e-02, -2.2183e-01, -1.5485e-01, 2.6317e-01, 2.8273e-01,
-7.4823e-02, -5.3704e-02, 9.3526e-02, -1.7916e-01, -3.1132e-04],
[ 8.9063e-02, 2.9263e-01, -1.0052e-01, 8.7005e-02, -1.1246e-01,
-2.7968e-01, 4.1411e-02, -1.6776e-01, 1.2363e-01, -2.2808e-01],
[ 2.9244e-02, 5.8296e-02, -2.9729e-01, -3.1437e-01, -9.3182e-02,
-7.5236e-03, 5.6159e-02, -2.2075e-02, 1.0337e-01, 8.1123e-02]],
requires_grad=True), Parameter containing:
tensor([ 0.2240, 0.0997, -0.0047, -0.1784, -0.0369], requires_grad=True), Parameter containing:
tensor([[ 0.3546, -0.2180, 0.1723, -0.0463, 0.2572],
[-0.1669, -0.1364, -0.0398, 0.2233, -0.1805]], requires_grad=True), Parameter containing:
tensor([ 0.0871, -0.1698], requires_grad=True)]
现在,让我们试着概括一下:
class Temp(nn.Module):
def __init__(self, stateSize, actionSize, layers=[10, 5], activations=[F.tanh, F.tanh] ):
super(Temp, self).__init__()
# Generate the fullly connected layer functions
self.fcLayers = []
oldN = stateSize
for i, layer in enumerate(layers):
self.fcLayers.append( nn.Linear(oldN, layer) )
oldN = layer
self.fcFinal = nn.Linear( oldN, actionSize )
return
原来这个模块内的参数个数已经不一样了……
t = Temp(2, 3)
list(t.parameters())
[Parameter containing:
tensor([[-0.3342, 0.4111, 0.0418, 0.4457, 0.0648],
[ 0.4364, -0.0360, -0.2239, 0.4025, 0.1661],
[ 0.1932, -0.0896, 0.3269, -0.2179, 0.1035]], requires_grad=True),
Parameter containing:
tensor([-0.2867, -0.1354, -0.0026], requires_grad=True)]
我相信理解为什么会这样。更大的问题是,我们如何克服这个问题?第二种,泛化方法,例如,不会正确地发送到 GPU,也不会被优化器训练。
解决方案
问题是nn.Linear
“通用”版本中的大多数层都存储在一个常规的 Pythonic 列表 ( self.fcLayers
) 中。pytorch不知道nn.Paramters
在nn.Module
.
解决方案:
如果您希望以pytorchnn.Modules
可以管理的方式存储,则需要使用专门的 pytorch 容器。
例如,如果您使用而不是常规的 pythonic 列表:nn.ModuleList
self.fcLayers = nn.ModuleList([])
您的示例应该可以正常工作。
顺便说一句,
您需要 pytorch 知道您的成员nn.Module
本身就是模块,不仅可以获取它们的参数,还可以获取其他功能,例如将它们移动到 gpu/cpu,将它们的模式设置为 eval/training 等。
推荐阅读
- django - “CELERY_BEAT_SCHEDULER”配置在 django 设置中不起作用
- sabre - 从 Sabre 查询通用产品属性
- mathematical-optimization - 如何计算不同数量的决策变量 - 线性规划
- python - Leetcode #377 组合总和 IV,我的代码中的意外行为
- python - Plotly 或 Bokeh Offline - 根据搜索框更新图表
- python - 将 else 条件添加到简化结构块
- r - 如何将data.frame列变成值变化最快的列
- reactjs - 如何将贝宝按钮转换为反应组件?
- ios - iOS、Node.js:Firebase 推送通知 JSON 签名
- python - 有什么方法可以将 AWS Lambda 函数(Python)连接到现有的外部 PostgresSQL 数据库