Керас пользовательской активации, чтобы сбросить при определенных условиях
Я пытаюсь сбросить значения меньше 1 и больше -1 в моей пользовательской активации, как показано ниже.
def ScoreActivationFromSigmoid(x, target_min=1, target_max=9) :
condition = K.tf.logical_and(K.tf.less(x, 1), K.tf.greater(x, -1))
case_true = K.tf.reshape(K.tf.zeros([x.shape[1] * x.shape[2]], tf.float32), shape=(K.tf.shape(x)[0], x.shape[1], x.shape[2]))
case_false = x
changed_x = K.tf.where(condition, case_true, case_false)
activated_x = K.sigmoid(changed_x)
score = activated_x * (target_max - target_min) + target_min
return score
тип данных имеет 3 измерения: batch_size x sequence_length x количество объектов.
Но я получил эту ошибку
nvalidArgumentError: Inputs to operation activation_51/Select of type Select must have the same size and shape. Input 0: [1028,300,64] != input 1: [1,300,64]
[[{{node activation_51/Select}} = Select[T=DT_FLOAT, _class=["loc:@training_88/Adam/gradients/activation_51/Select_grad/Select_1"], _device="/job:localhost/replica:0/task:0/device:GPU:0"](activation_51/LogicalAnd, activation_51/Reshape, dense_243/add)]]
[[{{node metrics_92/acc/Mean_1/_9371}} = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_473_metrics_92/acc/Mean_1", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]
Я понимаю, в чем проблема; Пользовательская функция активации не может найти правильный размер пакета входов. Но я не знаю, как их контролировать.
Может кто-нибудь исправить это или предложить другие методы для замены некоторых значений элемента в некоторых условиях?
1 ответ
Сообщение об ошибке, которое я получил при запуске вашего кода:
ValueError: Невозможно изменить тензор с 19200 элементами для формирования [1028,300,64] (19737600 элементов) для 'Reshape_8' (op: 'Reshape') с входными формами: [19200], [3] и с входными тензорами, вычисленными как частичные формы: входные данные [1] = [1028,300,64].
И проблема должна заключаться в том, что вы не можете изменить форму тензора от [x.shape[1] * x.shape[2]] до (K.tf.shape(x)[0], x.shape[1], x.shape[2]). Это потому, что их количество элементов отличается.
Таким образом, решение заключается в создании нулевого массива в правильной форме. Эта строка:
case_true = K.tf.reshape(K.tf.zeros([x.shape[1] * x.shape[2]], tf.float32), shape=(K.tf.shape(x)[0], x.shape[1], x.shape[2]))
следует заменить на:
case_true = K.tf.reshape(K.tf.zeros([x.shape[0] * x.shape[1] * x.shape[2]], K.tf.float32), shape=(K.tf.shape(x)[0], x.shape[1], x.shape[2]))
или используя K.tf.zeros_like
:
case_true = K.tf.zeros_like(x)
Работоспособный код:
import keras.backend as K
import numpy as np
def ScoreActivationFromSigmoid(x, target_min=1, target_max=9) :
condition = K.tf.logical_and(K.tf.less(x, 1), K.tf.greater(x, -1))
case_true = K.tf.zeros_like(x)
case_false = x
changed_x = K.tf.where(condition, case_true, case_false)
activated_x = K.tf.sigmoid(changed_x)
score = activated_x * (target_max - target_min) + target_min
return score
with K.tf.Session() as sess:
x = K.tf.placeholder(K.tf.float32, shape=(1028, 300, 64), name='x')
score = sess.run(ScoreActivationFromSigmoid(x), feed_dict={'x:0':np.random.randn(1028, 300, 64)})
print(score)