我正在尝试在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}))
此打印-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)
这会产生错误
<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)
我尝试通过提供默认值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)
当用作成本函数时仍然存在“无”的问题
嗨,你解决了这个问题吗?