如何使用Tensorflow或pytorch中的自定义权重初始化创建自定义神经网络

时间:2019-09-05 10:18:08

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

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

enter image description here

1 个答案:

答案 0 :(得分:0)

总结:
你可以做到吗? -绝对是
会很漂亮吗? -,绝对不是。

在我的解释中,我将进一步关注PyTorch,因为这是我更喜欢的库,如果您具有可以轻松地以pythonic方式表达的自定义操作,则该库特别有用。 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中也非常有用。请注意,无论如何,这将比香草线性层慢得多。 如果您可以使用经过单独训练的砝码,则始终也可以只定义较小尺寸的单独线性层,并以更方便的方式放置它们。