Keras пользовательская функция потери dtype error
У меня есть NN, который имеет два идентичных CNN (аналогично сиамской сети), затем объединяет выходные данные и намеревается применить пользовательскую функцию потерь к объединенному выходу, что-то вроде этого:
----------------- -----------------
| input_a | | input_b |
----------------- -----------------
| base_network | | base_network |
------------------------------------------
| processed_a_b |
------------------------------------------
В моей пользовательской функции потерь мне нужно разбить y по вертикали на две части, а затем применить категориальную кросс-энтропийную потерю для каждой части. Тем не менее, я продолжаю получать ошибки dtype от моей функции потерь, например:
ValueError Traceback (последний вызов был последним) в () ----> 1 model.compile(loss=categoryorical_crossentropy_loss, оптимизатор = RMSprop ())
/usr/local/lib/python3.5/dist-packages/keras/engine/training.py в процессе компиляции (самообслуживание, оптимизатор, потеря, метрики, loss_weights, sample_weight_mode, **kwargs) 909 loss_weight = loss_weights_list[i] 910 output_loss = weighted_loss(y_true, y_pred, -> 911 sample_weight, mask) 912, если len (self.outputs)> 1: 913 self.metrics_tensors.append (output_loss)
/usr/local/lib/python3.5/dist-packages/keras/engine/training.py в взвешенном состоянии (y_true, y_pred, weights, mask) 451 # применить выборочное взвешивание 452, если веса не равны None: -> 453 score_array *= весов 454 score_array /= K.mean(K.cast(K.not_equal(weights, 0), K.floatx())) 455 вернуть K.mean (score_array)
/usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/math_ops.py в binary_op_wrapper(x, y) 827, если не isinstance(y, sparse_tensor.SparseTensor): 828 попытаться: -> 829 y = ops.convert_to_tensor(y, dtype=x.dtype.base_dtype, name="y") 830, за исключением TypeError: 831 # Если RHS не является тензорным, это может быть объект, распознающий тензор
/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py в convert_to_tensor (значение, dtype, name, предпочитаемый_dtype) 674 имя = имя, 675 предпочитаемый_д тип = предпочтительный тип, -> 676 as_ref= Неверно) 677 678
/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py в internal_convert_to_tensor(значение, dtype, имя, as_ref, предпочитаемый_dtype) 739 740, если ret отсутствует: -> 741 ret = translation_func (значение, dtype=dtype, name=name, as_ref=as_ref) 742 743, если ret не NotImplemented:
/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py в _TensorTensorConversionFunction(t, dtype, name, as_ref) 612 повышают ValueError( 613 "запрашивается преобразование Tensor dtype %s для Tensor с dtype %s: %r"-> 614 % (имя dtype.name, t.dtype.name, str (t))) 615 return t 616
ValueError: Запрошено преобразование Tensor dtype float64 для Tensor с dtype float32: 'Tensor("processing_a_b_sample_weights_1:0", shape=(?,), dtype=float32)'
Вот MWE, чтобы воспроизвести ошибку:
import tensorflow as tf
from keras import backend as K
from keras.layers import Input, Dense, merge, Dropout
from keras.models import Model, Sequential
from keras.optimizers import RMSprop
import numpy as np
# define the inputs
input_dim = 10
input_a = Input(shape=(input_dim,), name='input_a')
input_b = Input(shape=(input_dim,), name='input_b')
# define base_network
n_class = 4
base_network = Sequential(name='base_network')
base_network.add(Dense(8, input_shape=(input_dim,), activation='relu'))
base_network.add(Dropout(0.1))
base_network.add(Dense(n_class, activation='relu'))
processed_a = base_network(input_a)
processed_b = base_network(input_b)
# merge left and right sections
processed_a_b = merge([processed_a, processed_b], mode='concat', concat_axis=1, name='processed_a_b')
# create the model
model = Model(inputs=[input_a, input_b], outputs=processed_a_b)
# custom loss function
def categorical_crossentropy_loss(y_true, y_pred):
# break (un-merge) y_true and y_pred into two pieces
y_true_a, y_true_b = tf.split(value=y_true, num_or_size_splits=2, axis=1)
y_pred_a, y_pred_b = tf.split(value=y_pred, num_or_size_splits=2, axis=1)
loss = K.categorical_crossentropy(output=y_pred_a, target=y_true_a) + K.categorical_crossentropy(output=y_pred_b, target=y_true_b)
return K.mean(loss)
# compile the model
model.compile(loss=categorical_crossentropy_loss, optimizer=RMSprop())
1 ответ
Как показывает ваша ошибка, вы работаете с float32
данные и это ожидает float64
, Необходимо отследить ошибку до ее конкретной строки, чтобы точно знать, какой тензор нужно исправить, и чтобы помочь вам лучше.
Однако, похоже, это связано с K.mean()
метод, но ValueError
s также могут быть сгенерированы K.categorical_crossentropy()
метод. Поэтому проблема может быть с вашими тензорами loss
, и то и другое y_pred
с или оба y_true
s. Учитывая эти сценарии, я вижу две вещи, которые вы могли бы попытаться решить:
Вы можете разыграть свой тензор (ы) (предположим, что это
loss
) к нужному типу (float64), например так:from keras import backend as K new_tensor = K.cast(loss, dtype='float64')
Вы можете объявить свои входные данные как имеющие тип float64 в начале, передав параметр
dtype
кInput()
вызов (как предложено в этих примерах), например:input_a = Input(shape=(input_dim,), name='input_a', dtype='float64')