Keras自定义丢失函数dtype错误

时间:2017-07-14 20:28:09

标签: python tensorflow keras cross-entropy loss-function

我有一个NN有两个相同的CNN(类似于Siamese网络),然后合并输出,并打算在合并输出上应用自定义丢失函数,如下所示:

     -----------------        -----------------
     |    input_a    |        |    input_b    |
     -----------------        -----------------
     | base_network  |        | base_network  |
     ------------------------------------------
     |           processed_a_b                |
     ------------------------------------------

在我的自定义丢失函数中,我需要将y垂直分成两部分,然后在每个部分上应用分类交叉熵损失。但是,我不断从我的损失函数中得到dtype错误,例如:

  

ValueError Traceback(最近一次调用   最后)in()   ----> 1个model.compile(loss = categorical_crossentropy_loss,optimizer = RMSprop())

     

/usr/local/lib/python3.5/dist-packages/keras/engine/training.py in   编译(自我,优化器,损失,指标,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 in   加权(y_true,y_pred,权重,掩码)       451#应用样本加权       452如果权重不是无:    - > 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   in convert_to_tensor(value,dtype,name,preferred_dtype)       674 name = name,       675 preferred_dtype = preferred_dtype,    - > 676 as_ref = False)       677       678

     

/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py   在internal_convert_to_tensor中(value,dtype,name,as_ref,   preferred_dtype)       739       740如果ret为None:    - > 741 ret = conversion_func(value,dtype = dtype,name = name,as_ref = as_ref)       742       743如果ret未实现:

     

/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py   在_TensorTensorConversionFunction(t,dtype,name,as_ref)中       612提出ValueError(       613"张量转换为Tensor请求dtype%s,dtype为%s:%r"    - > 614%(dtype.name,t.dtype.name,str(t)))       615返回t       616

     

ValueError:Tensor转换为Tensor请求dtype float64   dtype float32:' Tensor(" processed_a_b_sample_weights_1:0",shape =(?,),   D型= 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 个答案:

答案 0 :(得分:0)

如您的错误所示,您正在处理float32数据,并且预计会float64。有必要将错误跟踪到其特定行,以确定要纠正的张量,并能够更好地帮助您。

但是,似乎K.mean()方法相关,但ValueError方法也可以生成K.categorical_crossentropy()。因此问题可能在于您的张量lossy_predy_true。鉴于这些情况,我看到你可以尝试解决问题的两件事:

  1. 您可以cast张量(假设它是loss)到所需的(float64)类型,如下所示:

    from keras import backend as K
    new_tensor = K.cast(loss, dtype='float64')
    
  2. 您可以通过将参数dtype传递给Input()调用(如these示例中所示),将开头的输入声明为float64类型,例如这样:

    input_a = Input(shape=(input_dim,), name='input_a', dtype='float64')