我需要为Keras编写自定义损耗/度量函数的帮助。我的类别是二进制编码的(不是一次性的)。我想在真实类和预测类之间进行按位比较。
例如, 实标签:0x1111111111 预测标签:0x1011101111
预测标签的10位正确值为8位,因此此匹配的准确性应为0.8而不是0.0。我不知道如何使用Keras命令来支持这样做。
编辑1: 目前,我正在使用类似的方法,但是它还不能正常工作:
def custom_binary_error(y_true, y_pred, n=11):
diff_dec = K.tf.bitwise.bitwise_xor(K.tf.cast(y_true, K.tf.int32), K.tf.cast(y_pred, K.tf.int32))
diff_bin = K.tf.mod(K.tf.bitwise.right_shift(K.tf.expand_dims(diff_dec,1), K.tf.range(n)), 2)
diff_sum = K.tf.math.reduce_sum(diff_bin, 1)
diff_percent = K.tf.math.divide(diff_sum, 11)
return K.tf.math.reduce_mean(diff_percent, 0)
我收到此错误:
ValueError: Dimensions must be equal, but are 2048 and 11 for 'loss/activation_1_loss/RightShift' (op: 'RightShift') with input shapes: [?,1,2048], [11].
答案 0 :(得分:0)
我在尝试y_true, y_pred
是正整数的情况下进行尝试。
def custom_binary_error(y_true, y_pred):
width = y_true.bit_length() if y_true.bit_length() > y_pred.bit_length() else y_pred.bit_length() # finds the greater width of bit sequence, not sure if needed
diff = np.bitwise_xor(y_true, y_pred) # 1 when different, 0 when same
error = np.binary_repr(diff, width=width).count('1')/width # calculate % of '1's
return K.variable(error)
使用1-error
以获得准确性。我没有测试过;这只是一个想法。
答案 1 :(得分:0)
这是定义错误的方法:
import tensorflow as tf
def custom_binary_error(y_true, y_pred):
y_true = tf.cast(y_true, tf.bool)
y_pred = tf.cast(y_pred, tf.bool)
xored = tf.logical_xor(y_true, y_pred)
notxored = tf.logical_not(xored)
sum_xored = tf.reduce_sum(tf.cast(xored, tf.float32))
sum_notxored = tf.reduce_sum(tf.cast(notxored, tf.float32))
return sum_xored / (sum_xored + sum_notxored)
使用2个大小为6的标签进行测试:
import tensorflow as tf
y_train_size = 6
y_train = [[1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0]]
y_pred = tf.convert_to_tensor([[1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 1, 0]])
y = tf.placeholder(tf.int32, shape=(None, y_train_size))
error = custom_binary_error(y, y_pred)
with tf.Session() as sess:
res = sess.run(error, feed_dict={y:y_train})
print(res) # 0.25
在Keras
中使用它:
import tensorflow as tf
import numpy as np
y_train_size = 6
def custom_binary_error(y_true, y_pred):
y_true = tf.cast(y_true, tf.bool)
y_pred = tf.cast(y_pred, tf.bool)
xored = tf.logical_xor(y_true, y_pred)
notxored = tf.logical_not(xored)
sum_xored = tf.reduce_sum(tf.cast(xored, tf.float32))
sum_notxored = tf.reduce_sum(tf.cast(notxored, tf.float32))
return sum_xored / (sum_xored + sum_notxored)
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(y_train_size))
model.compile(optimizer=tf.keras.optimizers.SGD(0.01),
loss=[tf.keras.losses.MeanAbsoluteError()],
metrics=[custom_binary_error])
y_train = np.array([[1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0]])
x_train = np.random.normal(size=(2, 2))
model.fit(x_train, y_train, epochs=2)
将导致:
Epoch 1/2
2/2 [==============================] - 0s 23ms/sample - loss: 1.4097 - custom_binary_error: 0.5000
Epoch 2/2
2/2 [==============================] - 0s 328us/sample - loss: 1.4017 - custom_binary_error: 0.5000
注意
如果您想要准确性而不是 error ,则custom_binary_error()
函数应返回
sum_notxored / (sum_xored + sum_notxored)