在具有张量流后端的keras中定义弹球损失函数

时间:2017-04-01 01:10:31

标签: machine-learning tensorflow keras

我试图定义一个用于实现“分位数回归”的pinbal loss函数。在Keras的神经网络中(Tensorflow作为后端)。

定义如下:pinball loss

很难实现传统的K.means()等功能,因为它们处理整批y_pred,y_true,但我必须考虑y_pred,y_true和here这里的每个组件。我的原始代码:

def pinball_1(y_true, y_pred):
    loss = 0.1
    with tf.Session() as sess:
        y_true = sess.run(y_true)
        y_pred = sess.run(y_pred)
    y_pin = np.zeros((len(y_true), 1))
    y_pin = tf.placeholder(tf.float32, [None, 1])
    for i in range((len(y_true))):
        if y_true[i] >= y_pred[i]:
            y_pin[i] = loss * (y_true[i] - y_pred[i])
        else:
            y_pin[i] = (1 - loss) * (y_pred[i] - y_true[i])
    pinball = tf.reduce_mean(y_pin, axis=-1)
    return K.mean(pinball, axis=-1)

sgd = SGD(lr=0.1, clipvalue=0.5)
model.compile(loss=pinball_1, optimizer=sgd)
model.fit(Train_X, Train_Y, nb_epoch=10, batch_size=20, verbose=2)

我试图将y_pred,y_true传递给矢量化数据结构,所以我可以用索引引用它们,并处理各个组件,但由于缺乏处理y_pred,y_true的知识,似乎出现了问题。

我试图潜入错误导致的行,但我几乎迷路了。

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

我该如何解决?谢谢!

2 个答案:

答案 0 :(得分:4)

我自己用Keras后端想出了这个:

# Determine the platform
UNAME_S := $(shell uname -s)

# CC
CC := g++

# Folders
SRCDIR := src
BUILDDIR := build
TARGETDIR := bin

# Targets
EXECUTABLE := NSDG
TARGET := $(TARGETDIR)/$(EXECUTABLE)

# Final Paths
INSTALLBINDIR := /usr/local/bin

# Code Lists
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))

# Folder Lists
# Note: Intentionally excludes the root of the include folder so the lists are clean
INCDIRS := $(shell find includes/**/* -name '*.h' -exec dirname {} \; | sort | uniq)
INCLIST := $(patsubst includes/%,-I include/%,$(INCDIRS))
BUILDLIST := $(patsubst includes/%,$(BUILDDIR)/%,$(INCDIRS))

# Shared Compiler Flags
CFLAGS := -c
INC := -I include $(INCLIST) -I /usr/local/include
LIB := -L /usr/local/lib -lblas -llapacke -lgsl -lgslcblas -lm

# Platform Specific Compiler Flags
CFLAGS += -std=c++11

$(TARGET): $(OBJECTS)
    @mkdir -p $(TARGETDIR)
    @echo "Linking..."
    @echo "  Linking $(TARGET)"; $(CC) $^ -o $(TARGET) $(LIB)

$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
    @mkdir -p $(BUILDLIST)
    @echo "Compiling $<..."; $(CC) $(CFLAGS) $(INC) -c -o $@ $<

clean:
    @echo "Cleaning $(TARGET)..."; $(RM) -r $(BUILDDIR) $(TARGET)

install:
    @echo "Installing $(EXECUTABLE)..."; cp $(TARGET) $(INSTALLBINDIR)

distclean:
    @echo "Removing $(EXECUTABLE)"; rm $(INSTALLBINDIR)/$(EXECUTABLE)

.PHONY: clean

答案 1 :(得分:0)

这是一个更有效的版本:

def pinball_loss(y_true, y_pred, tau):
    err = y_true - y_pred
    return K.mean(K.maximum(tau * err, (tau - 1) * err), axis=-1)

使用附加参数和functools.partial函数是恕我直言,为tau设置不同值的最简单方法:

model.compile(loss=functools.partial(pinball_loss, tau=0.1), optimizer=sgd)