在tf中创建自定义分段损失函数.Keras有三个变量



我使用以下代码尝试使用包含三个变量的自定义分段损失函数来训练模型,但我无法使其工作。我是新的tensorflow,所以如果有人有任何建议,将是有帮助的。

我想加入第三个变量" "转化为损失函数,其中& & &;每个y_true/y_pred对不同。"p"表示原始数据框中的一列。对于这个问题& & & &;对于确定模型是否正确至关重要。如果模型是正确的,我将损失赋值为0如果模型不正确,我将损失赋值为1。我将损失值加起来,然后除以批大小,以确定该批的损失值。我想做的事情可能吗?如果没有,有什么方法可以让我达到预期的结果呢?

import tensorflow as tf
import pandas as pd
from tensorflow.keras import layers
# Read in statistics and outcomes dataframe
df = pd.read_csv(r'gs.csv')
df = df.drop(['prediction_ou'], axis=1)
# Change categorical columns to numeric
df['date'] = pd.Categorical(df['date'])
df['date'] = df.date.cat.codes
df['away_team'] = pd.Categorical(df['away_team'])
df['away_team'] = df.away_team.cat.codes
df['away_conf'] = pd.Categorical(df['away_conf'])
df['away_conf'] = df.away_conf.cat.codes
df['home_team'] = pd.Categorical(df['home_team'])
df['home_team'] = df.home_team.cat.codes
df['home_conf'] = pd.Categorical(df['home_conf'])
df['home_conf'] = df.home_conf.cat.codes
# Create target data
target = df.pop('actual_spread')
# Create tensorflow dataset
dataset = tf.data.Dataset.from_tensor_slices((df.values, target.values))
# Shuffle and batch
train_dataset = dataset.shuffle(len(df)).batch(32)
# Model
model = tf.keras.Sequential([
layers.Dense(128, activation='relu'),
layers.Dense(128, activation='relu'),
layers.Dense(1)
])


#  Custom loss function  
def cbb_loss_higher(p):

def cbb_loss(y_true,y_pred):
c=0

for i in range(len(y_true)):
if ((y_true[i]>p[i]) and (y_pred[i]<p[i])) or ((y_true[i]<p[i]) and (y_pred[i]>p[i])):
c+=1
elif ((y_true[i]>p[i]) and (y_pred[i]>p[i])) or ((y_true[i]<p[i]) and (y_pred[i]<p[i])):
c+=0
else:
c+=0.5

cbb_loss = c/len(y_true)
return cbb_loss

model.compile(optimizer='adam',
loss=cbb_loss_higher(p = df.prediction_spread),
metrics=['accuracy'])
model.fit(train_dataset,
epochs=10)

当代码按原样运行时,我收到以下错误:

File "cbb_ml.py", line 129, in <module>
epochs=10)
...
ValueError: No gradients provided for any variable: ['dense/kernel:0', 'dense/bias:0', 'dense_1/kernel:0', 'dense_1/bias:0', 'dense_2/kernel:0', 'dense_2/bias:0'].

损失函数是keras构建的计算图的一部分。你不能在里面使用python的len()函数。这个函数不支持梯度的反向传播。用tf.shape()代替

我刚刚重新安排了一下你的成本函数。因为我没有您的csv文件,所以我模拟了一些输入和一个简单的模型。

p = tf.random.normal(shape=[10])
#  Custom loss function  
def cbb_loss(y_true,y_pred):
c=0.0

for i in range(len(y_true)):
if ((y_true[i]>p[i]) and (y_pred[i]<p[i])) or ((y_true[i]<p[i]) and (y_pred[i]>p[i])):
c+=1.0
elif ((y_true[i]>p[i]) and (y_pred[i]>p[i])) or ((y_true[i]<p[i]) and (y_pred[i]<p[i])):
c+=0.0
else:
c+=0.5

cbb_loss = c/tf.cast(len(y_true),dtype=tf.float32)
return cbb_loss
x = tf.random.normal(shape=(10,10))
y = tf.random.normal(shape=(10,1))
model = tf.keras.Sequential([
layers.Dense(units=1)
])

model.compile(optimizer='adam',
loss=cbb_loss,
metrics=['accuracy'])    

model.fit(x=x, y=y, epochs=100,verbose=1)

相关内容

最新更新