Keras中的自定义损失函数,如何处理占位符

Ily*_*lya 5 python-3.x keras gini tensorflow loss-function

我正在尝试在 TF/Keras 中生成自定义损失函数,如果它在会话中运行并传递常量,则损失函数会起作用,但是,它在编译成 Keras 时停止工作。

成本函数(感谢 Lior 将其转换为 TF)

def ginicTF(actual,pred):

    n = int(actual.get_shape()[-1])

    inds =  K.reverse(tf.nn.top_k(pred,n)[1],axes=[0]) 
    a_s = K.gather(actual,inds) 
    a_c = K.cumsum(a_s)
    giniSum = K.sum(a_c)/K.sum(a_s) - (n+1)/2.0

    return giniSum / n

def gini_normalizedTF(a,p):
    return -ginicTF(a, p) / ginicTF(a, a)

#Test the cost function

sess = tf.InteractiveSession()

p = [0.9, 0.3, 0.8, 0.75, 0.65, 0.6, 0.78, 0.7, 0.05, 0.4, 0.4, 0.05, 0.5, 0.1, 0.1]
a = [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]    

ac = tf.placeholder(shape=(len(a),),dtype=K.floatx())
pr = tf.placeholder(shape=(len(p),),dtype=K.floatx())

print(gini_normalizedTF(ac,pr).eval(feed_dict={ac:a,pr:p}))
Run Code Online (Sandbox Code Playgroud)

这将打印 -0.62962962963,这是正确的值。

现在让我们把它放到 Keras MLP 中

def makeModel(n_feat):

    model = Sequential()

    #hidden layer #1
    model.add(layers.Dense(12, input_shape=(n_feat,)))
    model.add(layers.Activation('selu'))
    model.add(layers.Dropout(0.2))

    #output layer
    model.add(layers.Dense(1))
    model.add(layers.Activation('softmax'))

    model.compile(loss=gini_normalizedTF,  optimizer='sgd', metrics=['binary_accuracy'])

    return model

model=makeModel(n_feats)
model.fit(x=Mout,y=targets,epochs=n_epochs,validation_split=0.2,batch_size=batch_size)
Run Code Online (Sandbox Code Playgroud)

这会产生错误

<ipython-input-62-6ade7307336f> in ginicTF(actual, pred)
      9 def ginicTF(actual,pred):
     10 
---> 11     n = int(actual.get_shape()[-1])
     12 
     13     inds =  K.reverse(tf.nn.top_k(pred,n)[1],axes=[0])

TypeError: __int__ returned non-int (type NoneType)
Run Code Online (Sandbox Code Playgroud)

我尝试通过提供默认值 n/etc 来解决它,但这似乎没有任何意义。

有人可以解释这个问题的性质以及我如何解决它吗?

谢谢!

编辑:

更新内容以将其保持为张量,然后进行转换

def ginicTF(actual,pred):


    nT = K.shape(actual)[-1]
    n = K.cast(nT,dtype='int32')
    inds =  K.reverse(tf.nn.top_k(pred,n)[1],axes=[0]) 
    a_s = K.gather(actual,inds) 
    a_c = K.cumsum(a_s)
    n = K.cast(nT,dtype=K.floatx())
    giniSum =  K.cast(K.sum(a_c)/K.sum(a_s),dtype=K.floatx()) - (n+1)/2.0

    return giniSum / n

def gini_normalizedTF(a,p):
    return ginicTF(a, p) / ginicTF(a, a)
Run Code Online (Sandbox Code Playgroud)

当用作成本函数时仍然存在“none”的问题