Керас поддержал получение производной функции - PullRequest
2 голосов
/ 04 октября 2019

Я делаю нейронную сеть с двумя настроенными функциями активации. Первая функция активации - это f (x), а вторая - производная от f (x) по отношению к f (x). Вместо того, чтобы брать производные вручную, что очень сложно для моего реального случая, как я могу заставить Keras делать это автоматически?

Вот мой код:

import numpy as np
import math
import keras
from keras.models import Model, Sequential
from keras.layers import Input, Dense, Activation
from keras import regularizers
from keras import backend as K

def custom_activation_f(x):
    return (K.sigmoid(x) *2-1 )

def custom_activation_fprime(x):
    deriv(x)= # take the derivative of custom_activation_f(x)
    return deriv(x)

x_train=np.random.uniform(low=-1,high=1,size=(200,2))

model=Sequential([
     Dense(20,input_shape=(2,)),
     Activation(custom_activation_f),
     Dense(2,),
     Activation(custom_activation_fprime)
])

model.compile(optimizer='adam',loss='mean_squared_error')
model.fit(x_train,x_train,epochs=20,validation_split=0.1)

Обновление : после того, как я получил ответ от Пранит Котари:, я изменил часть custom_activation_fprim следующим образом:

def custom_activation_fprime(x):
    my_derivative= K.gradients(custom_activation_f, x)
    return my_derivative

Это то, как я должен использовать это? Вот ошибка:

Using TensorFlow backend.
WARNING: Logging before flag parsing goes to stderr.
W1004 12:07:29.987481  2280 deprecation_wrapper.py:119] From C:\ProgramData\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py:74: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.

W1004 12:07:30.011625  2280 deprecation_wrapper.py:119] From C:\ProgramData\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py:517: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.

W1004 12:07:30.016886  2280 deprecation_wrapper.py:119] From C:\ProgramData\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py:4138: The name tf.random_uniform is deprecated. Please use tf.random.uniform instead.

Traceback (most recent call last):
  File "C:\Users\r.jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\tensor_util.py", line 558, in make_tensor_proto
    str_values = [compat.as_bytes(x) for x in proto_values]
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\tensor_util.py", line 558, in <listcomp>
    str_values = [compat.as_bytes(x) for x in proto_values]
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\util\compat.py", line 65, in as_bytes
    (bytes_or_text,))
TypeError: Expected binary or unicode string, got <function custom_activation_f at 0x000002896662C1E0>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/p/CE/mytest3.py", line 24, in <module>
    Activation(custom_activation_fprime)
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\sequential.py", line 93, in __init__
    self.add(layer)
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\sequential.py", line 181, in add
    output_tensor = layer(self.outputs[0])
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\base_layer.py", line 457, in __call__
    output = self.call(inputs, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\layers\core.py", line 299, in call
    return self.activation(inputs)
  File "C:/p/CE/mytest3.py", line 15, in custom_activation_fprime
    my_derivative= K.gradients(custom_activation_f, x)
  File "C:\ProgramData\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py", line 2757, in gradients
    return tf.gradients(loss, variables, colocate_gradients_with_ops=True)
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\ops\gradients_impl.py", line 158, in gradients
    unconnected_gradients)
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\ops\gradients_util.py", line 594, in _GradientsHelper
    ys = ops.convert_n_to_tensor_or_indexed_slices(ys, name="y")
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\ops.py", line 1456, in convert_n_to_tensor_or_indexed_slices
    values=values, dtype=dtype, name=name, as_ref=False)
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\ops.py", line 1428, in internal_convert_n_to_tensor_or_indexed_slices
    value, dtype=dtype, name=n, as_ref=as_ref))
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\ops.py", line 1388, in internal_convert_to_tensor_or_indexed_slices
    value, dtype=dtype, name=name, as_ref=as_ref)
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\ops.py", line 1224, in internal_convert_to_tensor
    ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\constant_op.py", line 305, in _constant_tensor_conversion_function
    return constant(v, dtype=dtype, name=name)
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\constant_op.py", line 246, in constant
    allow_broadcast=True)
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\constant_op.py", line 284, in _constant_impl
    allow_broadcast=allow_broadcast))
  File "C:\Users\r. jack\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\framework\tensor_util.py", line 562, in make_tensor_proto
    "supported type." % (type(values), values))
TypeError: Failed to convert object of type <class 'function'> to Tensor. Contents: <function custom_activation_f at 0x000002896662C1E0>. Consider casting elements to a supported type.

Ответы [ 2 ]

1 голос
/ 11 октября 2019

Есть 2 способа решить эту проблему.

  1. Используйте K.gradients для получения производной, но для входа требуется тензор, но здесь это функция. Ниже приведен пример фрагмента его использования.

    пример фрагмента кода

    def custom_activation_fprime(x):
        my_derivative= K.gradients(tf.convert_to_tensor(custom_activation_f(x), dtype=tf.float32), x)
        return my_derivative
    

или 2. Создайте пользовательскую производную функцию и передайте эту функцию в качестве активациимодель

0 голосов
/ 04 октября 2019

Вы пробовали gradients из кераса?

from keras import backend
backend.gradients(loss, variable)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...