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() метод, но ValueErrors также могут быть сгенерированы K.categorical_crossentropy() метод. Поэтому проблема может быть с вашими тензорами loss, и то и другое y_predс или оба y_trues. Учитывая эти сценарии, я вижу две вещи, которые вы могли бы попытаться решить:

  1. Вы можете разыграть свой тензор (ы) (предположим, что это loss) к нужному типу (float64), например так:

    from keras import backend as K
    new_tensor = K.cast(loss, dtype='float64')
    
  2. Вы можете объявить свои входные данные как имеющие тип float64 в начале, передав параметр dtype к Input() вызов (как предложено в этих примерах), например:

    input_a = Input(shape=(input_dim,), name='input_a', dtype='float64')
    
Другие вопросы по тегам