使用Keras中的K.eval()将Tensor转换为np.array会返回InvalidArgumentError

时间:2018-03-09 10:49:36

标签: python numpy tensorflow keras

这是在Keras中定义自定义丢失功能。代码如下:

from keras import backend as K
from keras.models import Sequential
from keras.layers import Dense
from keras.callbacks import EarlyStopping
from keras.optimizers import Adam

def custom_loss_function(y_true, y_pred):
    a_numpy_y_true_array = K.eval(y_true)
    a_numpy_y_pred_array = K.eval(y_pred)

    # some million dollar worth custom loss that needs numpy arrays to be added here...

    return K.mean(K.binary_crossentropy(y_true, y_pred), axis=-1)


def build_model():
    model= Sequential()
    model.add(Dense(16, input_shape=(701, ), activation='relu'))
    model.add(Dense(16, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss=custom_loss_function, optimizer=Adam(lr=0.005), metrics=['accuracy'])  
    return model

model = build_model()
early_stop = EarlyStopping(monitor="val_loss", patience=1) 
model.fit(kpca_X, y, epochs=50, validation_split=0.2, callbacks=[early_stop], verbose=False)

以上代码返回以下错误:

---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
D:\milind.dalvi\personal\_python\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _do_call(self, fn, *args)
   1326     try:
-> 1327       return fn(*args)
   1328     except errors.OpError as e:

D:\milind.dalvi\personal\_python\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _run_fn(session, feed_dict, fetch_list, target_list, options, run_metadata)
   1305                                    feed_dict, fetch_list, target_list,
-> 1306                                    status, run_metadata)
   1307 

D:\milind.dalvi\personal\_python\Anaconda3\lib\contextlib.py in __exit__(self, type, value, traceback)
     88             try:
---> 89                 next(self.gen)
     90             except StopIteration:

D:\milind.dalvi\personal\_python\Anaconda3\lib\site-packages\tensorflow\python\framework\errors_impl.py in raise_exception_on_not_ok_status()
    465           compat.as_text(pywrap_tensorflow.TF_Message(status)),
--> 466           pywrap_tensorflow.TF_GetCode(status))
    467   finally:

InvalidArgumentError: You must feed a value for placeholder tensor 'dense_84_target' with dtype float and shape [?,?]
     [[Node: dense_84_target = Placeholder[dtype=DT_FLOAT, shape=[?,?], _device="/job:localhost/replica:0/task:0/cpu:0"]()]]

所以有人知道我们如何将y_truey_pred Tensor("dense_84_target:0", shape=(?, ?), dtype=float32)转换为numpy数组

修改 ----------------------------------------------- ---------

基本上我期望在损失函数中编写的内容如下:

def custom_loss_function(y_true, y_pred):

    classifieds = []
    for actual, predicted in zip(y_true, y_pred):
        if predicted == 1:
            classifieds.append(actual)
    classification_score = abs(classifieds.count(0) - classifieds.count(1))

    return SOME_MAGIC_FUNCTION_TO_CONVERT_INT_TO_TENSOR(classification_score)

3 个答案:

答案 0 :(得分:3)

使用模型编译损失函数。在编译时,y_truey_pred只是占位符张量,因此它们还没有值,因此无法进行评估。这就是您收到错误消息的原因。

你的损失函数应该使用Keras张量,而不是它们评估的numpy数组。如果您需要使用其他numpy数组,请使用variable keras.backend import keras.backend as K def custom_loss_function(y_true, y_pred): y_true = y_true*2 - K.ones_like(y_true) # re-codes values of y_true from {0,1} to {-1,+1} y_true = y_true*y_pred # makes the values that you are not interested in equal to zero classification_score = K.abs(K.sum(y_true)) 方法将其转换为张量。

修改

您仍然需要留在Keras功能空间内以使您的损失工作。如果这是您想要实现的具体损失函数,并假设您的值在{0,1},您可以尝试这样的事情:

      self.performSegue(withIdentifier: "showNominees", sender: indexPath)  

答案 1 :(得分:0)

  

所以任何人都知道我们如何将y_true和y_pred(即Tensor(“ dense_84_target:0”,shape =(?,?),dtype = float32)转换为numpy数组

the_tensor = K.arange(5)
// >>> Tensor("arange:0", shape=(5,), dtype=int32)
the_np = the_tensor.eval(session=K.get_session())
// >>> [0 1 2 3 4]

答案 2 :(得分:0)

  1. 您通过 4 个步骤 (1-4) 将 tensorflow TENSOR 转换为 NUMPY ARRAY:
  2. 您通过 2 个步骤 (A-B) 将 INT 或 FLOAT 转换为 tensorflow TENSOR:
  3. 在我看来,建议使用 dtype='float' 而不是 dtype='int'。在我的模型中,损失 int 不起作用。
  4. 您可以像这样在 Keras 中创建自定义损失函数。
  5. 将 tensorflow 张量转换为 Python 列表可以让 Pythoneer 更容易使用。
#STEP1 IMPORT TENSORFLOW AND KERAS LOSS
import tensorflow as tf
from keras.losses import Loss

#TO MAKE YOUR LOSS FUNCTION WORK YOU MUST DEFINE A CALL FUNCTION IN A CLASS INHERITING FROM KERAS LOSS CLASS
class yourLoss (Loss):
    def __init__ (self):
        super().__init__()
    def call (self, y_true, y_pred):
        #STEP_A: MAKE A VARIABLE HOLDING YOUR MODEL TENSOR PARAMETERS
        #MULTIPLYINIG IT BUT 0 MAKES IT EMPTY 
        shapeHolder = y_pred * 0

        #STEP3 CAST YOUR TENSOR
        y_true = tf.cast (y_true, dtype='float')
        y_pred = tf.cast (y_pred, dtype='float')

        #STEP4 CONVERT IT TO NUMPY ARRAY
        y_pred = y_pred.numpy ()
        y_true = y_true.numpy ()

        #YOU CAN CONVERT A TENSOR INTO PYTHON LIST AS WELL
        #YOU CAN WRITE THE STEPS IN ONE CODE LINE
        y_true = tf.cast (y_true, dtype='float').numpy ().tolist ()
        y_pred = tf.cast (y_pred, dtype='float').numpy ().tolist ()

        #loss = your loss function

        #STEP_B: CONVERT THE INTEGER LOSS TO THE WANTED TENSOR
        #ADDING AN INT TO ZERO TENSOR MAKES ALL TENSOR NUMBERS THE INT
        #BUT I THINK IT'S BETTER TO USE FLOAT NOT INT 
        return shapeHolder + loss

#STEP2 TURN ON TRACING
tf.config.run_functions_eagerly (True)
model.fit (....)

#IT IS RECOMENDED TO TURN IT OFF LATER, A TRACING IS EXPENSIVE
tf.config.run_functions_eagerly (False)