2017-01-23 39 views
1

我需要定义keras定制的度量与tensorflow后端,以获得ADR和FAR指标,其中:自定义指标的ADR和FAR在Keras

  • ADR是正确的数量之间的比例检测到的第1类元素和第1类元素的总数。

  • FAR是被错误地归类为第1类元素的第0类元素的数量与第0类元素的总数之间的比率。

现在,我已经能够计算在每类元素的总数:现在

def false_rates(y_true, y_pred): 
    total_1 = K.sum(tf.cast(tf.equal(y_true, 1), 'int32')) 
    total_0 = K.sum(tf.cast(tf.equal(y_true, 0), 'int32')) 
    # [...] 

,在张量各指标i,我需要算多少:

  • y_true[i] == 1 and y_pred[i] == 1的ADR
  • y_true[i] == 0 and y_pred[i] == 1为FAR

但我不知道如何与tensorflow操作要做到这一点,我得到的最接近是这样的:

adr = K.sum(
     tf.cast(
      tf.equal(
       tf.add(
        tf.cast(tf.equal(y_true, 1), 'int32'), 
        tf.cast(tf.equal(y_pred, 1), 'int32')), 2), 'int32')) 

# far = ...? 

但它似乎并不返回任何东西比0

谢谢为你提供帮助!


编辑,包括完整的代码:

# coding: utf-8 
import csv 
import numpy as np 
import os 

os.environ["KERAS_BACKEND"] = "tensorflow" 

from keras import backend as K 
from keras.callbacks import ModelCheckpoint, EarlyStopping, TensorBoard 
from keras.layers import Convolution2D 
from keras.models import Sequential 
from keras.optimizers import RMSprop, SGD 
from keras.layers.core import Dense, Dropout 
from keras.layers.recurrent import LSTM 
from keras.layers.embeddings import Embedding 
from keras.preprocessing.sequence import pad_sequences 
from keras.preprocessing.text import one_hot 

def build_model(input_shape, n1, dropout_p, n_symbols, n_sequence): 
    model = Sequential() 
    model.add(Embedding(n_symbols+1, 
         output_dim=n1, 
         input_length=n_sequence)) 
    model.add(LSTM(n1)) 
    model.add(Dropout(dropout_p)) 
    model.add(Dense(1)) 
    return model 

def load_sequences(path): 
    X, y = [], [] 
    with open(path,'r') as file: 
     reader = csv.reader(file) 
     for line in reader: 
       X.append(line[0]) 
       y.append(int(line[1])) 
    return np.array(X), np.array(y) 

def adr_and_far(y_true, y_pred): 
    total_adr = K.sum(K.tf.cast(K.tf.equal(y_true, 1), 'int32')) 
    total_far = K.sum(K.tf.cast(K.tf.equal(y_true, 0), 'int32')) 

    adr_idx = K.tf.equal(y_true, 1) & K.tf.equal(y_pred, 1) 
    adr_idx = K.tf.reshape(K.tf.where(adr_idx), [-1]) 

    far_idx = K.tf.equal(y_true, 0) & K.tf.equal(y_pred, 1) 
    far_idx = K.tf.reshape(K.tf.where(far_idx), [-1]) 

    num_adr = K.tf.shape(adr_idx)[0] # 3 
    num_far = K.tf.shape(far_idx)[0] # 2 

    return { 'total_adr': total_adr, 
      'adr': num_adr/total_adr, 
      'total_far': total_far, 
      'far': num_far/total_far 
      } 

simbols = ['1','a','A','r','2','b','B','s','3','c','C','t','4','d','D','u','5','e','E','v','6','f','F','w','7','g','G','x','8','h','H','y','9','i','I','z', ',', '.', '*', '+', '0'] 
n_symbols = len(simbols) # dimensionality of your word vectors 

max_len_sequence = 20 
input_shape = (max_len_sequence, n_symbols) 
n1 = 128 # From Paper 
dropout_p = 0.1 
loss_method = 'binary_crossentropy' 

optimizer = 'adam' 
model = build_model(input_shape, n1, dropout_p, n_symbols, max_len_sequence) 
model.compile(loss=loss_method, optimizer=optimizer, metrics=['accuracy', adr_and_far]) 

和错误:

Using TensorFlow backend. 
Traceback (most recent call last): 
    File "1%29+Training+RNN+Single+Model.py", line 68, in <module> 
    model.compile(loss=loss_method, optimizer=optimizer, metrics=['accuracy', adr_and_far]) 
    File "/usr/local/lib/python2.7/site-packages/keras/models.py", line 594, in compile 
    **kwargs) 
    File "/usr/local/lib/python2.7/site-packages/keras/engine/training.py", line 716, in compile 
    metric_result = metric_fn(y_true, y_pred) 
    File "1%29+Training+RNN+Single+Model.py", line 43, in adr_and_far 
    adr_idx = K.tf.reshape(K.tf.where(adr_idx), [-1]) 
TypeError: select() takes at least 3 arguments (1 given) 

回答

1

你只需要算?

y_true = tf.constant([1, 1, 1, 0, 0, 0, 1, 1, 1]) 
y_pred = tf.constant([1, 1, 0, 1, 1, 0, 1, 0, 0]) 

adr_idx = tf.equal(y_true, y_pred) & tf.equal(y_true, 1) 
adr_idx = tf.reshape(tf.where(adr_idx), [-1]) # [0, 1, 6] 

far_idx = tf.equal(y_true, 0) & tf.equal(y_pred, 1) 
far_idx = tf.reshape(tf.where(far_idx), [-1]) # [3, 4] 

num_adr = tf.shape(adr_idx)[0] # 3 
num_far = tf.shape(far_idx)[0] # 2 

with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 
    a, b = sess.run([num_adr, num_far]) 

使用keras 1.2.1版本tensorflow 0.11
我想原因是不同的形状
y_true的形状是(?, ?)和y_pred是(?, 1)形状?

def adr_and_far(y_true, y_pred): 
    total_adr = K.sum(K.tf.cast(K.tf.equal(y_true, 1), 'int32')) 
    total_far = K.sum(K.tf.cast(K.tf.equal(y_true, 0), 'int32')) 

    adr_idx = K.tf.equal(y_true, 1) & K.tf.equal(y_pred, 1) 
    adr_idx = K.sum(K.tf.cast(K.reshape(adr_idx, [-1]), 'int32')) 

    far_idx = K.tf.equal(y_true, 0) & K.tf.equal(y_pred, 1) 
    far_idx = K.sum(K.tf.cast(K.reshape(far_idx, [-1]), 'int32')) 


    return { 'total_adr': total_adr, 
      'adr': adr_idx/total_adr, 
      'total_far': total_far, 
      'far': far_idx/total_far 
      } 
+0

你的答案似乎很接近我所需要的,但每次我尝试使用'tf.where'我得到这个'类型错误:选择()至少需要3个参数(1给出)' – VMRuiz

+0

以前的错误只有在导入Keras和Tensorflow时才会出现。 – VMRuiz

+0

所以如果只是进口keras或tensorflow是好的?如果您使用tensorflow作为后端,您是否需要导入它们两个? – xxi