Кусочная функция активации в тензорном потоке и математическая операция вещания

Я пытаюсь реализовать и протестировать функцию активации, которую я прочитал в статье.

Я использую Keras с бэкэндом tensorflow и хочу передать функцию активации методу подгонки моей модели. Вот математическая форма функции:

кусочная формула

Я пытался реализовать это двумя способами:

def function_1(x):

    cond1 = tf.greater(x , 2.0)
    cond2 = tf.logical_and(tf.less_equal(x, 2.0), tf.greater_equal(x, 0.0))
    cond3 = tf.logical_and(tf.less(x, 0.0), tf.greater_equal(x, -2.0))
    cond4 = tf.less(x, -2.0)

    y = tf.where(cond1, tf.constant(1.0) , tf.where(cond2,
    x - 0.25*tf.square(x), tf.where(cond3, x + 0.25*tf.square(x), 
    tf.where(cond4, tf.constant(-1.0), tf.constant(-1.0)))))

    return y

def function_2(x):

    cond1 = tf.greater(x , 2.0)
    cond2 = tf.logical_and(tf.less_equal(x, 2.0), tf.greater_equal(x, 0.0))
    cond3 = tf.logical_and(tf.less(x, 0.0), tf.greater_equal(x, -2.0))
    cond4 = tf.less(x, -2.0)

    y = tf.case({cond1: lambda x: tf.constant(1.0), cond2: lambda x: x - 
    0.25*tf.square(x), cond3: lambda x: x + 0.25*tf.square(x),
    cond4: lambda x: tf.constant(-1.0)}, exclusive = True)

    return y

В обоих случаях я получаю одинаковую ошибку:

InvalidArgumentError: Формы должны иметь одинаковый ранг, но 0 и 2 для 'dense_22/Select' (op: 'Select') с входными фигурами: [?,5], [], [].

Каков правильный путь к этому и что не так с моим кодом?


person Reza    schedule 15.01.2019    source источник


Ответы (2)


Проблема в том, что вы сравниваете тензор формы [None, 5] (ранг 2) с скейлером (ранг 0), что невозможно с tf.greater или tf.less. Вместо этого вы можете использовать tf.math..., которые поддерживают трансляцию.

Вот одно из возможных решений для реализации этой функции:

import tensorflow as tf

x = tf.placeholder(dtype=tf.float32, shape=[1, 5])

cond1 = tf.cast(tf.math.greater(x, 2.0), tf.float32)
cond2 = tf.cast(tf.math.logical_and(tf.math.less_equal(x, 2.0), tf.math.greater_equal(x, 0.0)), tf.float32)
cond3 = tf.cast(tf.math.logical_and(tf.math.less(x, 0.0), tf.math.greater_equal(x, -2.0)), tf.float32)
cond4 = tf.cast(tf.math.less(x, -2.0), tf.float32)

a = tf.math.multiply(cond1, 1.0)
b = tf.math.multiply(cond2, (x - tf.square(x) / 4))
c = tf.math.multiply(cond3, (x + tf.square(x) / 4))
d = tf.math.multiply(cond4, -1.0)

f = a + b + c + d

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(f, feed_dict={x: [[-1.0, -5, 1.5, -1.5, 5]]})) 
person Amir    schedule 15.01.2019
comment
Спасибо. Проблема решена! Не обратил внимания на вещание в функциях tf.math - person Reza; 16.01.2019

Вы можете попробовать слой lambda, который очень удобен для добавления нашего пользовательского слоя или функции в сеть. Вот пример:

dense1 = Dense(dims)(input)   
act1 = Lambda(customFunc, output_shape)(dense1)

def customFunc(x):
    """-----operations----""""
    # final output y of shape defined as above in layer
    y = conditioned-output
    return y

Вот ссылка для получения дополнительной информации Это еще одна полезная ссылка, поясняемая на примере.

person Ankish Bansal    schedule 15.01.2019