Keras自定义损失函数使用y_pred和y_true

时间:2020-06-03 03:22:10

标签: python tensorflow keras loss-function

我当时正在考虑使用类似感知器的神经网络来解决我的问题的想法。为了简单起见,我有一个数据集,看起来像这样:

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参数的自定义损失函数,在我们的情况下将是cutingToolPos1和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

但是我担心索引以及它是否完全可行。

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

3 个答案:

答案 0 :(得分:0)

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

如果我写错了,请纠正我:您想根据某些输入木材的长度/厚度来预测可获得最佳结果的切割位置(出口木材的长度/厚度)吗?因此,在“现实生活”中,您将从仅具有entryWood值开始?

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

示例:

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]

请记住,[特别是在这种虚拟情况下],模型(神经网络)对输入和输出之间的关系描述得很差(因此,我现在不相信这种预测)。但是,有了更多数据,此模型将(可能)变得更好。还请记住,我不知道您正在使用/使用的主题/数据,因此这些只是一些想法/示例,可能会帮助您入门/指导您。

答案 1 :(得分:0)

从问题陈述中看来,您似乎需要首先训练神经网络并找到优化的输入变量。但是,从您的代码看来,您很难定义自定义损失。尽管我不太清楚您的问题陈述,但是您可以这样做以创建自定义损失函数(从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 :(得分:0)

据我所知,您要么希望机器将进入块切割成接近所需尺寸(退出块),要么试图预测所需工具的位置,否则反过来(问题中不清楚) 。您可以通过两种方式对此问题进行建模。

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

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

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

使用MSE损失函数可以轻松地对这两个选项进行建模。