Обучаемый, многопараметрический Activ. Функция (RBF) NeuPy / Theano

Как реализовать пользовательскую функцию активации (ядро RBF со средним и отклонениями, скорректированными с помощью градиентного спуска) в Neupy или Theano для использования в Neupy.

{Quick Background: Gradient Descent работает с каждым параметром в сети. Я хочу создать специализированное пространство функций, содержащее оптимизированные параметры объектов, так что 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

Помощь будет высоко ценится, так как она поможет лучше понять, как настроить новые сети. Документация может использовать некоторую работу в некоторых областях, чтобы сказать наименее...

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))))

Хотя 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)

Это компилируется с правильными входными данными, целевым и средним значениями, а отклонения обновляются поэлементно.

Другие вопросы по тегам