【问题标题】:How to create custom neural network with custom weight initialization in tensorflow or pytorch如何在 tensorflow 或 pytorch 中使用自定义权重初始化创建自定义神经网络
【发布时间】:2019-09-05 10:18:08
【问题描述】:

我正在尝试创建一个在神经元之间具有自定义连接的小型神经网络。如图所示,连接应该存在于多个层上,而不是完全连接(稀疏)。我还想手动而不是完全随机地进行权重初始化。我的目标是确定连接是积极的还是消极的。是否可以在 tensorflow (python/js) 或 pytorch 中创建这样的神经网络?

【问题讨论】:

    标签: python tensorflow neural-network pytorch feed-forward


    【解决方案1】:

    总结一下:
    你能做到吗? -- 是的,绝对的。
    会好看吗? -- 没有,绝对没有。

    在我的解释中,我将进一步关注 PyTorch,因为这是我更熟悉的库,如果你有可以轻松地以 Python 方式表达的自定义操作,它尤其有用。 Tensorflow 也有急切的执行模式(如果我没记错的话,从第 2 版开始更认真的集成),但它传统上是使用计算图完成的,这使得整个事情比它需要的更丑陋。

    您希望知道,反向传播(任何 ANN 中的“学习”步骤)基本上是通过网络的反向传递,以计算梯度,或者至少足够接近我们手头问题的真相。重要的是,torch 函数存储了这个“反向”方向,这使得用户调用反向传播函数变得微不足道。

    要对您图片中描述的简单网络进行建模,我们只有一个主要缺点:
    可用的操作通常在他们正在做的事情上表现出色,因为它们简单并且可以进行大量优化。在您的情况下,您必须将不同的层表示为自定义操作,这通常扩展得非常差,除非您可以将泛函表示为某种形式的矩阵操作,我在您的示例中没有直接看到。我进一步假设您正在应用某种形式的非线性,否则它将成为would fail for any non-linearly separable problem 的网络。

    import torch
    import torch.nn as nn
    class CustomNetwork(nn.module):
        def __init__(self):
            self.h_1_1 = nn.Sequential(nn.Linear(1,2), nn.ReLU) # top node in first layer
            self.h_1_2 = nn.Sequential(nn.Linear(1,2), nn.ReLU) # bottom node in first layer
            # Note that these nodes have no shared weights, which is why we
            # have to initialize separately.
            self.h_2_1 = nn.Sequential(nn.Linear(1,1), nn.ReLU) # top node in second layer
            self.h_2_2 = nn.Sequential(nn.Linear(1,1), nn.ReLU) # bottom node in second layer
    
            self.h_2_1 = nn.Sequential(nn.Linear(2,1), nn.ReLU) # top node in third layer
            self.h_2_2 = nn.Sequential(nn.Linear(2,1), nn.ReLU) # bottom node in third layer
           # out doesn't require activation function due to pairing with loss function
            self.out = nn.Linear(2,1)
    
        def forward(self, x):
            # x.shape: (batch_size, 2)
    
            # first layer. shape of (batch_size, 2), respectively
            out_top = self.h_1_1(x[:,0])
            out_bottom = self.h_1_2(x[:,1])
    
            # second layer. shape of (batch_size, 1), respectively
            out_top_2 = self.h_2_1(out_top[:,0])
            out_bottom_2 = self.h_2_2(out_bottom[:,0])
    
            # third layer. shape of (batch_size, 1), respectively
            # additional concatenation of previous outputs required.
            out_top_3 = self.h_3_1(torch.cat([out_top_2, -1 * out_top[:,1]], dim=1))
            out_bottom_3 = self.h_3_2(torch.cat([out_bottom_2, -1 * out_bottom[:,1]], dim=1))
            return self.out(torch.cat([out_top_3, out_bottom_3], dim=1))
    

    如您所见,任何计算步骤都是(在这种情况下相当明确地)给出的,并且很有可能。同样,一旦你想为每一层扩展神经元的数量,你将不得不在处理方式上更有创意,但 for 循环在 PyTorch 中也做了很多工作。请注意,无论如何,这将比普通线性层慢得多。 如果您可以使用单独训练的权重,您也可以始终只定义较小尺寸的单独线性层,并以更方便的方式放置它们。

    【讨论】:

      猜你喜欢
      • 2021-06-25
      • 2019-10-09
      • 2017-06-17
      • 1970-01-01
      • 2018-09-05
      • 2018-04-27
      • 2011-08-07
      • 1970-01-01
      相关资源
      最近更新 更多