2017-04-23 85 views
4

我是Keras的新手,我试图定义我自己的指标。它计算一致性指数,这是衡量回归问题的指标。Keras自定义指标迭代

def cindex_score(y_true, y_pred): 
    sum = 0 
    pair = 0  
    for i in range(1, len(y_true)): 
     for j in range(0, i): 
      if i is not j: 
       if(y_true[i] > y_true[j]): 
        pair +=1 
        sum += 1* (y_pred[i] > y_pred[j]) + 0.5 * (y_pred[i] == y_pred[j]) 
    if pair is not 0: 
     return sum/pair 
    else: 
     return 0 


def baseline_model(hidden_neurons, inputdim): 
    model = Sequential() 
    model.add(Dense(hidden_neurons, input_dim=inputdim, init='normal', activation='relu')) 
    model.add(Dense(hidden_neurons, init='normal', activation='relu')) 
    model.add(Dense(1, init='normal')) #output layer 

    model.compile(loss='mean_squared_error', optimizer='adam', metrics=[cindex_score]) 
    return model 

def run_model(P_train, Y_train, P_test, model): 
    history = model.fit(numpy.array(P_train), numpy.array(Y_train), batch_size=50, nb_epoch=200) 
    plotLoss(history) 
    return model.predict(P_test) 

baseline_model,run_model和cindex_score功能在one.py和下面的函数是在two.py,我叫模型,

def experiment(): 
    hidden_neurons = 250 
    dmodel=baseline_model(hidden_neurons, train_pair.shape[1]) 
    predicted_Y = run_model(train_pair,train_Y, test_pair, dmodel) 

,但我得到了下面的错误,“对象类型'Tensor'没有len()“。它也不适用于shape属性。例如,y_true表示为Tensor(“dense_4_target:0”,shape =(?,?),dtype = float32),其形状为Tensor(“strided_slice:0”,shape =(),dtype = INT32)。

请问如何在Tensor对象内迭代?

最佳,

+0

你为什么选中“如果我不是J” ......是不是真的所有的时间? – Pedia

回答

1

,那么你可以尝试使用此代码来代替:

def cindex_score(y_true, y_pred): 

    g = tf.subtract(tf.expand_dims(y_pred, -1), y_pred) 
    g = tf.cast(g == 0.0, tf.float32) * 0.5 + tf.cast(g > 0.0, tf.float32) 

    f = tf.subtract(tf.expand_dims(y_true, -1), y_true) > 0.0 
    f = tf.matrix_band_part(tf.cast(f, tf.float32), -1, 0) 

    g = tf.reduce_sum(tf.multiply(g, f)) 
    f = tf.reduce_sum(f) 

    return tf.where(tf.equal(g, 0), 0.0, g/f) 

以下是验证两种方法均为eq的代码uivalent:

def _ref(J, K): 
    _sum = 0 
    _pair = 0 
    for _i in range(1, len(J)): 
     for _j in range(0, _i): 
      if _i is not _j: 
       if(J[_i] > J[_j]): 
        _pair +=1 
        _sum += 1* (K[_i] > K[_j]) + 0.5 * (K[_i] == K[_j]) 
    return 0 if _pair == 0 else _sum/_pair 

def _raw(J, K): 

    g = tf.subtract(tf.expand_dims(K, -1), K) 
    g = tf.cast(g == 0.0, tf.float32) * 0.5 + tf.cast(g > 0.0, tf.float32) 

    f = tf.subtract(tf.expand_dims(J, -1), J) > 0.0 
    f = tf.matrix_band_part(tf.cast(f, tf.float32), -1, 0) 

    g = tf.reduce_sum(tf.multiply(g, f)) 
    f = tf.reduce_sum(f) 

    return tf.where(tf.equal(g, 0), 0.0, g/f) 


for _ in range(100): 
    with tf.Session() as sess: 
     inputs = [tf.placeholder(dtype=tf.float32), 
        tf.placeholder(dtype=tf.float32)] 
     D = np.random.randint(low=10, high=1000) 
     data = [np.random.rand(D), np.random.rand(D)] 

     r1 = sess.run(_raw(inputs[0], inputs[1]), 
         feed_dict={x: y for x, y in zip(inputs, data)}) 
     r2 = _ref(data[0], data[1]) 

     assert np.isclose(r1, r2) 

请注意,这只适用于一维张量(很少情况下,你会在keras中)。

+0

感谢您的回答。我对tensorflow一点都不舒服。我试图理解你的翻译。虽然,看到上面的代码工作,我包括“导入tensorflow为tf”我得到这两个连续的错误,第一个是“一个”变量没有定义,然后“返回tf.where(tf.equal(g,0 ),0.0,g/f)TypeError:其中()需要1到2个位置参数,但3个被给出“ –

+0

您有哪个版本的tensorflow? – Pedia

+0

另外,你在哪一行得到未定义的变量? – Pedia

1

更换len(y_true)y_true.shape[0]

如果旧版本TensorFlow的如果您正在使用tensorflow舒适的使用y_true.get_shape()

+0

我有以下错误,ylen = y_true.shape [0] AttributeError:'Tensor'对象没有'形状'属性。 –

+0

看到这个答案,你可能会在TF的旧版本。 http://stackoverflow.com/questions/38666040/tensorflow-attributeerror-tensor-object-has-no-attribute-shape/ “在TensorFlow 1.0之前的版本tf.Tensor没有.shape属性。应该使用Tensor.get_shape()“ – pyCthon

+0

对不起,我反应太快了,我纠正为get_shape(),但我现在有这个错误,”我在范围内(1,ylen): TypeError:__index__返回非int (类型为NoneType)“ –

2

我用@Pedia代码为三维张量来计算的多标签分类排名的损失:

def rloss(y_true, y_pred): 
    g = tf.subtract(tf.expand_dims(y_pred[1], -1), y_pred[1]) 
    g = tf.cast(g == 0.0, tf.float32) * 0.5 + tf.cast(g > 0.0, tf.float32) 
    f = tf.subtract(tf.expand_dims(y_true[1], -1), y_true[1]) > 0.0 
    f = tf.matrix_band_part(tf.cast(f, tf.float32), -1, 0) 
    g = tf.reduce_sum(tf.multiply(g, f)) 
    f = tf.reduce_sum(f) 
return tf.where(tf.equal(g, 0), 0.0, g/f) 


model = Sequential() 
model.add(Dense(label_length, activation='relu')) 
model.add(Dense(label_length, activation='relu')) 
model.add(Dense(label_length, activation='sigmoid')) 
model.summary() 


adgard = optimizers.Adagrad(lr=0.01, epsilon=1e-08, decay=0.0) 
model.compile(loss='binary_crossentropy', 
      optimizer=adgard, metrics=[rloss]) 
model.fit(X_train, y_train, 
     batch_size=batch_size, 
     epochs=n_epoch, 
     validation_data=(X_test, y_test), 
     shuffle=True)