Tensorflow 2+. Использование альтернативных функций активации в сетях с использованием градиентов

Всех приветствую!

Для решения дифференциальных уравнения я пытаюсь применить методику PINN, которая использует стандартный перцептрон, задаваемый функцией

def create_standart_model(layers, activation='tanh', 
                          kernel_initializer='glorot_uniform'):
    model = keras.models.Sequential()
    model.add(keras.layers.InputLayer(input_shape=(layers[0])))
    for i in range(1, len(layers) - 1):
        model.add(keras.layers.Dense(layers[i], activation=activation, 
                                     kernel_initializer=kernel_initializer))
    model.add(keras.layers.Dense(layers[-1], activation='linear'))
    return model

В процессе обучения сети используются следующие функции (применительно к одномерному уравнению Пуассона):

def __loss(self, u, u_pred):
    " Функция ошибки "
    f_pred = self.f_model()
    return tf.reduce_mean(tf.square(u - u_pred)) + \
           tf.reduce_mean(tf.square(f_pred))

def __grad(self, X, u):
    " Расчет градиентов "
    with tf.GradientTape() as tape:
        loss_value = self.__loss(u, self.model(X))
    return loss_value, tape.gradient(loss_value, self.model.trainable_variables)

def f_model(self):
    " Расчет градиентов и невязки уравнения "
    with tf.GradientTape(persistent=True) as tape:
        tape.watch(self.x_f)                                    
        u = self.model(self.x_f)                                
        u_x = tape.gradient(u, self.x_f)                        
    u_xx = tape.gradient(u_x, self.x_f)                         
    del tape                                                    
    return u_xx - self.x_f_init   

Далее производится обучение:

def fit(self, epochs=5000):
    X_u = tf.convert_to_tensor(X_u_global, dtype=self.dtype)
    u = tf.convert_to_tensor(u_global, dtype=self.dtype)
    for epoch in range(epochs):                                 
        loss_value, grads = self.__grad(X_u, u)
        self.optimizer.apply_gradients(zip(grads, self.model.trainable_variables))

Если кратко, то численно рассчитывается второй градиент по x, а ошибка представляет из себя сумму невязки решения уравнения и выполнения ГУ.

Так вот, если при задании модели указать activation='tanh', то никаких абсолютно проблем не встречается и все великолепным образом рассчитывается.

Если же я захочу другую функцию активации, например softsign, то, по идее, пользуясь Keras, я просто должен задать activation='softsign', но, к сожалению, выскакивает следующая ошибка:

LookupError: gradient registry has no entry for: SoftsignGrad

Если кто-то знает, каким образом можно легко решить эту проблему, то я буду искренне благодарен. Я слышал про возможность задавания активаций через @tf.custom_gradient, но никаких значительных примеров в сети не нашел.


Ответы (0 шт):