【问题标题】:Trainable, Multi-Parameter Activ. Function (RBF) NeuPy / Theano可训练的多参数激活。函数 (RBF) NeuPy / Theano
【发布时间】:2018-09-29 05:16:47
【问题描述】:

如何在 Neupy 或 Theano 中实现自定义激活函数(RBF 内核,通过梯度下降调整均值和方差)以用于 Neupy。

{快速背景:梯度下降适用于网络中的每个参数。我想制作一个包含优化特征参数的特殊特征空间,所以 Neupy}

我认为我的问题在于参数的创建、它们的大小以及它们是如何连接的。

感兴趣的主要功能。

激活函数类

class RBF(layers.ActivationLayer):
    def initialize(self):
        super(RBF, self).initialize()
        self.add_parameter(name='mean', shape=(1,),
                       value=init.Normal(), trainable=True)
        self.add_parameter(name='std_dev', shape=(1,),
                       value=init.Normal(), trainable=True)
    def output(self, input_value):
        return rbf(input_value, self.parameters)

RBF函数

def rbf(input_value, parameters):
    K = _outer_substract(input_value, parameters['mean'])
    return np.exp(- np.linalg.norm(K)/parameters['std_dev'])

造型功能?

def _outer_substract(x, y):
    return (x - y.T).T

我们将非常感谢您的帮助,因为这将提供有关如何自定义 neupy 网络的深刻见解。至少可以说,该文档可能会在某些领域使用一些工作......

【问题讨论】:

    标签: python machine-learning theano neupy


    【解决方案1】:

    虽然itdxer对这个问题的回答很充分,但我还是想为这个问题添加确切的解决方案。

    建筑的创造

    network = layers.Input(size) > RBF() > layers.Softmax(num_out)
    

    激活函数

        # Elementwise Gaussian (RBF)
        def rbf(value, mean, std):
            return T.exp(-.5*T.sqr(value-mean)/T.sqr(std))/(std*T.sqrt(2*np.pi))
    

    RBF 类

        class RBF(layers.BaseLayer):
     
            def initialize(self):
     
                # Begin by initializing.
                super(RBF, self).initialize()
     
                # Add parameters to train
                self.add_parameter(name='means', shape=self.input_shape,
                               value=init.Normal(), trainable=True)
                self.add_parameter(name='std_dev', shape=self.input_shape,
                               value=init.Normal(), trainable=True)
     
            # Define output function for the RBF layer.
            def output(self, input_value):
                K = input_value - self.means
                return rbf(input_value,self.means,self.std_dev
    

    培训

    如果您对培训感兴趣。就这么简单,

    # Set training algorithm
    gdnet = algorithms.Momentum(
        network,
        momenutm = 0.1
    )
    
    # Train. 
    gdnet.train(x,y,max_iter=100)
    

    这会使用正确的输入和目标进行编译,并且均值和方差会按元素进行更新。

    【讨论】:

      【解决方案2】:

      当图层改变输入变量的形状时,它必须通知后续图层有关更改。对于这种情况,它必须自定义 output_shape 属性。例如:

      from neupy import layers
      from neupy.utils import as_tuple
      import theano.tensor as T
      
      class Flatten(layers.BaseLayer):
          """
          Slight modification of the Reshape layer from the neupy library:
          https://github.com/itdxer/neupy/blob/master/neupy/layers/reshape.py
          """
          @property 
          def output_shape(self):
              # Number of output feature depends on the input shape 
              # When layer receives input with shape (10, 3, 4)
              # than output will be (10, 12). First number 10 defines
              # number of samples which you typically don't need to
              # change during propagation
              n_output_features = np.prod(self.input_shape)
              return (n_output_features,)
      
          def output(self, input_value):
              n_samples = input_value.shape[0]
              return T.reshape(input_value, as_tuple(n_samples, self.output_shape))
      

      如果你在终端运行它,你会看到它可以工作

      >>> network = layers.Input((3, 4)) > Flatten()
      >>> predict = network.compile()
      >>> predict(np.random.random((10, 3, 4))).shape
      (10, 12)
      

      在您的示例中,我可以看到一些问题:

      1. rbf 函数不返回 theano 表达式。它应该在函数编译期间失败
      2. 如果您不指定要沿其计算范数的轴,np.linalg.norm 之类的函数将返回标量。

      以下解决方案应该适合您

      import numpy as np
      from neupy import layers, init
      import theano.tensor as T
      
      
      def norm(value, axis=None):
          return T.sqrt(T.sum(T.square(value), axis=axis))
      
      
      class RBF(layers.BaseLayer):
          def initialize(self):
              super(RBF, self).initialize()
      
              # It's more flexible when shape of the parameters
              # denend on the input shape
              self.add_parameter(
                  name='mean', shape=self.input_shape,
                  value=init.Constant(0.), trainable=True)
      
              self.add_parameter(
                  name='std_dev', shape=self.input_shape,
                  value=init.Constant(1.), trainable=True)
      
          def output(self, input_value):
              K = input_value - self.mean
              return T.exp(-norm(K, axis=0) / self.std_dev)
      
      
      network = layers.Input(1) > RBF()
      predict = network.compile()
      print(predict(np.random.random((10, 1))))
      
      network = layers.Input(4) > RBF()
      predict = network.compile()
      print(predict(np.random.random((10, 4))))
      

      【讨论】:

      • 两个建议:(1)添加关于可训练性的评论/演示; (2) 情节总是有帮助的。但这非常有效,而且很有指导意义。谢谢!
      猜你喜欢
      • 2019-09-25
      • 1970-01-01
      • 2014-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多