【问题标题】:Keras custom loss function using other arguments than y_pred and y_true使用 y_pred 和 y_true 以外的其他参数的 Keras 自定义损失函数
【发布时间】:2020-09-21 16:05:06
【问题描述】:

我正在考虑使用类似感知器的神经网络来解决我的问题。为了简单起见,我有一个数据集,如下所示:

id entryWoodLength entryWoodThickness cuttingToolPos1 cuttingToolPos2 exitWoodLength exitWoodThickness
1        5.5              1.6               2.1             2.2             4.2            1.6
2        5.7              1.5               2.2             2.6             4.2            1.5
3        6.5              1.8               2.6             2.7             4.3            1.6
4        5.9              1.7               2.4             2.9             4.2            1.5
5        5.8              1.5               2.2             2.6             4.1            1.5

我曾想过尝试一个前馈神经网络,其中输入是木材尺寸(entryWoodLenth 和 entryWoodThickness),输出是切割工具的位置(cuttingToolPos1 和 cuttingToolPos2)。我们已经知道出口木材的理想尺寸应该是多少(例如,长度为 4.2,厚度为 1.5)。因此,从技术上讲,我们希望我们的网络能够根据木材的实际值(exitWoodLength 和 exitWoodThickness)进行自我优化。这意味着将 exitWoodLength 和 exitWoodThickness 的 MSE 与 4.2 和 1.5 的参考值一起使用,如下所示:

mean_squared_error(exitWoodLength, 4.2) + mean_squared_error(exitWoodThickness, 1.5)

然而,Keras 只允许使用y_predy_true 参数的自定义损失函数,在我们的例子中是cuttingToolPos1 和cuttingToolPos2,而不是我们想要的损失函数的值。我正在考虑使用闭包函数,而只是忽略 y_predy_true 参数,在某种意义上:

def custom_loss(exitWoodLength, exitWoodThickness):

    def loss(y_pred, y_true):

        mean_squared_error(exitWoodLength, 4.2) + mean_squared_error(exitWoodThickness, 1.5)

        return loss

但我担心索引是否可行。

有没有人经历过类似的事情?我在使用神经网络的道路上是正确的还是完全错误的?

【问题讨论】:

    标签: python tensorflow keras loss-function


    【解决方案1】:

    从您的问题陈述来看,您似乎需要首先训练您的神经网络并找到优化的输入变量。但是,从您的代码看来,您在定义自定义损失时遇到了麻烦。虽然我不清楚您的问题陈述,但您可以这样做来制作自定义损失函数(从 akensert 的答案扩展):

    from keras import backend as K 
    #custom loss
    def custom_error(y_true, y_pred):
            return K.mean(K.square(y_pred[:,0] - 4.2)) +K.mean(K.square(y_pred[:,1] - 1.5))
    
    model.compile(loss=custom_error, optimizer='sgd')
    
    history = model.fit(X, y, epochs=100, verbose=1)
    

    【讨论】:

      【解决方案2】:

      根据我的理解,您要么希望您的机器将入口块切割成接近所需尺寸(出口块),因为您试图预测所需的工具位置,或者相反(在您的问题中不清楚) .您可以通过两种方式对此问题进行建模。

      选项 1:预测最佳工具位置,以生成具有特定尺寸输入块所需尺寸的输出块。输入:入口块(厚度和长度)和出口块(厚度和长度);输出:最佳工具位置。

      选项 2:预测给定输入块尺寸和工具位置的输出块大小。输入:入口块(厚度和长度)和刀具位置;输出:出口块(厚度和长度)。

      这两种方法都是对系统建模的有效方法,您可以根据应用选择一种,即取决于您要预测的内容,是出口块的尺寸还是给定的最佳工具位置输入和期望的输出。

      这两个选项都可以使用您的 MSE 损失函数轻松建模。

      【讨论】:

        【解决方案3】:

        据我了解,使用您当前的损失函数,您将无法训练神经网络。损失函数的当前输入不是神经网络的输出。确保 y_true 是您的目标变量,而 y_pred 是神经网络的预测(输出)。

        如果我错了,请纠正我:您想根据一些入口木材长度/厚度来预测获得最佳结果的切割位置(出口木材长度/厚度)?所以在“现实生活”中,你会从只有 entryWood 值开始?

        此选项可能不令人满意,但第一步可能是使用 entryWood 和 cutPos 作为输入,并使用 exitWood 作为目标变量。通过这种方式,神经网络可以学习根据特定的 entryWood/cuttingPos 来预测存在的Wood。然后对于第二步,[基于一些 entryWood 值],您可以搜索给出 4.2/1.5 存在木的cuttingPos。目前,我不太确定您如何[优雅地] 将其制成单个(端到端)模型

        例子:

        import pandas as pd
        import numpy as np
        import tensorflow as tf # (TensorFlow version 2.2)
        
        # define dataset
        df = pd.DataFrame(
            {'entryWoodLength':    [5.5, 5.7, 6.5, 5.9, 5.8],
             'entryWoodThickness': [1.6, 1.5, 1.8, 1.7, 1.5],
             'cuttingToolPos1':    [2.1, 2.2, 2.6, 2.4, 2.2],
             'cuttingToolPos2':    [2.2, 2.6, 2.7, 2.9, 2.6],
             'exitWoodLength':     [4.2, 4.2, 4.3, 4.2, 4.1],
             'exitWoodThickness':  [1.6, 1.5, 1.6, 1.5, 1.5]}
        )
        
        # STEP 1
        # create and compile model
        model = tf.keras.Sequential([
            tf.keras.layers.Dense(8, activation='relu', dtype='float32'), # hidden layer
            tf.keras.layers.Dense(2, activation='linear', dtype='float32'), # output layer
        ])
        # mse = (exitWood_pred - exitWood_true)^2
        model.compile(loss='mse', optimizer='sgd')
        
        X = df.iloc[:, :4] # entryWoodLength, entryWoodThickness, cuttingToolPos1, cuttingToolPos2
        y = df.iloc[:, 4:] # exitWoodLength, exitWoodThickness
        
        # fit to the data, find a relationship between X and y
        history = model.fit(X, y, epochs=100, verbose=0)
        
        
        # STEP 2
        # dummy example 
        entry_wood_dimemsions = [6.0, 1.8]
        # let's try some "random" tool_position (this has to be searched for)
        cut_tool_position = [2.1, 2.7]
        # model input
        x = np.array([[entry_wood_dimemsions + cut_tool_position]])
        # predict based on entry_wood_dimemsions and [manually selected] cut_tool_position
        exitWood_pred = model.predict(x)
        
        print("existWood pred =", np.squeeze(exitWood_pred))
        
        >> existWood pred = [4.078477  1.4972893]
        

        请记住,[尤其是在这个虚拟案例中],模型(神经网络)对输入和输出之间的关系的描述非常糟糕(所以我现在不相信这个预测)。但是随着更多的数据,这个模型(可能)会变得更好。另请记住,我不知道您正在处理/使用的主题/数据,因此这些只是一些可能帮助您入门/指导您的想法/示例。

        【讨论】:

          猜你喜欢
          • 2018-04-02
          • 2016-12-05
          • 2020-03-07
          • 2020-09-27
          • 2018-12-30
          • 1970-01-01
          • 2016-11-12
          • 1970-01-01
          • 2020-10-12
          相关资源
          最近更新 更多