Как сделать пользовательскую функцию активации в tenorflow - PullRequest
0 голосов
/ 18 января 2019

Мне нужно сделать функцию активации, которой нет в tenorflow. Как мне это сделать? Я когда-либо видел эту ссылку, Как сделать пользовательскую функцию активации только с Python в Tensorflow? но я все еще не знаю, как реализовать новый тип функции активации на картинке. relu, leaky_relu и новый тип relu

1 Ответ

0 голосов
/ 18 января 2019

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

Если вы используете функции Python, вам придется программировать как вперед, так и назад. Но проблема в том, что вам нужно сохранить маски функции кусочной функции в «кеше» (лично я не знаю, как это делается, и было бы интересно узнать).

import numpy as np
import tensorflow as tf

def new_relu(x, k=0.2):
    part_1 = tf.to_float(tf.math.less_equal(0.0, x))
    part_2 = tf.to_float(tf.math.logical_and(tf.math.less_equal(-1.0, x), tf.math.less(x, 0.0)))
    part_3 = tf.to_float(tf.math.less(x, -1.0))
    return part_1*x + part_2*x*k #+ part_3*0

def new_relu_test():

    # create data
    x = tf.random_normal([10])*10000
    y = new_relu(x)
    with tf.Session():
        diff = tf.test.compute_gradient_error(x, [10], y, [10])
        print(diff)

    # use in dense
    x = tf.placeholder(shape=[None, 3], dtype=tf.float32)
    nn = tf.layers.dense(x, 3, activation=new_relu)

EDIT: Если вы хотите, чтобы второй параметр тоже был тензорным, вы должны иметь тот же размер, что и входные.

import numpy as np
import tensorflow as tf

def new_relu(x, k=0.2):
    part_1 = tf.to_float(tf.math.less_equal(0.0, x))
    part_2 = tf.to_float(tf.math.logical_and(tf.math.less_equal(-1.0, x), tf.math.less(x, 0.0)))
    part_3 = tf.to_float(tf.math.less(x, -1.0))
    return part_1*x + part_2*x*k #+ part_3*0

def new_relu_test():
    # create data
    x = tf.random_normal([10])*10000
    y = new_relu(x)
    with tf.Session():
        diff = tf.test.compute_gradient_error(x, [10], y, [10])
        print(diff)

    # use in dense
    x = tf.placeholder(shape=[None, 3], dtype=tf.float32)
    x_b = tf.placeholder(shape=[None], dtype=tf.float32)
    nn_1 = tf.layers.dense(x, 3)
    nn_2 = tf.layers.dense(x, 3)
    nn = tf.layers.dense(nn_2, 1, activation=None)
    new_r = new_relu(x, tf.tile(tf.expand_dims(x_b, -1), [1, 3]))

    with tf.Session() as sess:
        sess.run(tf.initializers.global_variables())
        sess.run(new_r, feed_dict={x: np.random.rand(100, 3), x_b: np.random.rand(100)})

new_relu_test()

РЕДАКТИРОВАТЬ 2:

Использование conv2d

import numpy as np
import tensorflow as tf

def new_relu(x, k=0.2):
    part_1 = tf.to_float(tf.math.less_equal(0.0, x))
    part_2 = tf.to_float(tf.math.logical_and(tf.math.less_equal(-1.0, x), tf.math.less(x, 0.0)))
    part_3 = tf.to_float(tf.math.less(x, -1.0))
    return part_1*x + part_2*x*k #+ part_3*0

def new_relu_test():
    # create data
    x = tf.random_normal([10])*10000
    y = new_relu(x)
    with tf.Session():
        diff = tf.test.compute_gradient_error(x, [10], y, [10])
        print(diff)

    # use in dense
    x = tf.placeholder(shape=[None, 28, 28, 3], dtype=tf.float32)

    conv1_weights = tf.get_variable("weight",[3,3,3,32],initializer=tf.truncated_normal_initializer(stddev=0.1))
    conv1_biases = tf.get_variable("bias", [32], initializer=tf.constant_initializer(0.0))
    conv1 = tf.nn.conv2d(x, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
    relu1 = new_relu(tf.nn.bias_add(conv1, conv1_biases))

    with tf.Session() as sess:
        sess.run(tf.initializers.global_variables())
        sess.run(relu1, feed_dict={x: np.random.rand(100, 28, 28, 3)})
new_relu_test()
...