ValueError:张量转换请求 dtype float64 为具有 dtype float32 的张量

问题描述 投票:0回答:1

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

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

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

ValueError                                Traceback (most recent call last) <ipython-input-12-b01f2c4c71e3> in <module>()
----> 1 model.compile(loss=categorical_crossentropy_loss, optimizer=RMSprop())

/usr/local/lib/python3.5/dist-packages/keras/engine/training.py in compile(self, optimizer, loss, metrics, 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             if len(self.outputs) > 1:
    913                 self.metrics_tensors.append(output_loss)

/usr/local/lib/python3.5/dist-packages/keras/engine/training.py in weighted(y_true, y_pred, weights, mask)
    451         # apply sample weighting
    452         if weights is not None:
--> 453             score_array *= weights
    454             score_array /= K.mean(K.cast(K.not_equal(weights, 0), K.floatx()))
    455         return K.mean(score_array)

/usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/math_ops.py in binary_op_wrapper(x, y)
    827       if not isinstance(y, sparse_tensor.SparseTensor):
    828         try:
--> 829           y = ops.convert_to_tensor(y, dtype=x.dtype.base_dtype, name="y")
    830         except TypeError:
    831           # If the RHS is not a tensor, it might be a tensor aware object

/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 in internal_convert_to_tensor(value, dtype, name, as_ref, preferred_dtype)
    739 
    740         if ret is None:
--> 741           ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
    742 
    743         if ret is NotImplemented:

/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py in _TensorTensorConversionFunction(t, dtype, name, as_ref)
    612     raise ValueError(
    613         "Tensor conversion requested dtype %s for Tensor with dtype %s: %r"
--> 614         % (dtype.name, t.dtype.name, str(t)))
    615   return t
    616 

ValueError: Tensor conversion requested dtype float64 for Tensor with dtype float32: 'Tensor("processed_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())
python tensorflow machine-learning keras loss-function
1个回答
1
投票

正如您的错误所示,您正在使用

float32
数据,并且它需要
float64
。有必要将错误跟踪到其具体行,以确定要纠正哪个张量并能够更好地帮助您。

但是,它似乎

K.mean()
方法有关,但是
ValueError
也可以通过
K.categorical_crossentropy()
方法生成。因此,问题可能出在您的张量
loss
、两个
y_pred
或两个
y_true
。鉴于这些情况,我认为您可以尝试解决两件事:

  1. 您可以cast您的张量(假设它是

    loss
    )到所需的(float64)类型,如下所示:

    from keras import backend as K
    new_tensor = K.cast(loss, dtype='float64')
    
  2. 您可以在开始时将参数

    dtype
    传递给
    Input()
    调用(如 这些 示例中建议的那样),将输入声明为 float64 类型,如下所示:

    input_a = Input(shape=(input_dim,), name='input_a', dtype='float64')
    
© www.soinside.com 2019 - 2024. All rights reserved.