Tensorflow ADR和FAR的自定义公制单位(克朗)

Tensorflow ADR和FAR的自定义公制单位(克朗),tensorflow,keras,Tensorflow,Keras,我需要使用tensorflow后端在keras中定义一个自定义度量,以获取ADR和FAR度量,其中: 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

我需要使用tensorflow后端在keras中定义一个自定义度量,以获取ADR和FAR度量,其中:

  • 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
,我需要计算有多少:

  • ADR的y_真[i]==1和y_pred[i]==1
  • y_true[i]==0和y_pred[i]==1
但我不知道如何使用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)
使用TensorFlow后端。
回溯(最近一次呼叫最后一次):
文件“1%29+Training+RNN+Single+Model.py”,第68行,在
compile(loss=loss\u method,optimizer=optimizer,metrics=['accurity',adr\u和\u far])
文件“/usr/local/lib/python2.7/site packages/keras/models.py”,第594行,编译中
**kwargs)
文件“/usr/local/lib/python2.7/site packages/keras/engine/training.py”,第716行,编译
度量结果=度量fn(y\u真,y\u pred)
文件“1%29+培训+RNN+单一+模型.py”,第43行,adr\u和\u far
adr_idx=K.tf.重塑(K.tf.其中(adr_idx),[-1])
TypeError:select()至少接受3个参数(给定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
           }

您的答案似乎非常接近我所需要的,但每次我尝试使用
tf时,
我得到了这个
TypeError:select()至少接受3个参数(1个给定)
前面的错误仅在导入Keras和Tensorflow时出现。那么,如果只导入Keras或Tensorflow就可以了吗?如果您使用tensorflow作为后端,是否需要同时导入它们?对不起,我表达得不好。我的意思是,如果我导入Keras,Tensorflow将抛出该错误,无论我使用
tf
(来自Tensorflow模块)还是
K.tf
(Tensorflow来自Keras后端模块)。我还检查了Keras使用的Tensorflow版本是否与我在独立模式下使用Tensorflow时的版本相同。或者您可以粘贴代码。顺便说一句,如果您从keras导入后端的
作为K
,您是否使用
K
K.where
,而不是
K.tf.where