二进制编码(非一个热编码)分类数据的Keras自定义丢失函数

二进制编码(非一个热编码)分类数据的Keras自定义丢失函数,keras,deep-learning,categorical-data,loss-function,multiclass-classification,Keras,Deep Learning,Categorical Data,Loss Function,Multiclass Classification,我需要帮助为Keras编写自定义损失/度量函数。我的分类是二进制编码的(不是一个热门的)。我想在实际类和预测类之间做一个逐位比较 比如说,, 实际标签:0x1111111 预测标签:0x1011101111 预测标签有8个10位正确,因此此匹配的精度应为0.8而不是0.0。我不知道我是如何支持Keras命令的 编辑1: 目前我正在使用类似的东西,但它还不起作用: def custom_binary_error(y_true, y_pred, n=11): diff_dec = K.tf.

我需要帮助为Keras编写自定义损失/度量函数。我的分类是二进制编码的(不是一个热门的)。我想在实际类和预测类之间做一个逐位比较

比如说,, 实际标签:0x1111111 预测标签:0x1011101111

预测标签有8个10位正确,因此此匹配的精度应为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].

我试着做一些事情,假设
y\u true,y\u 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
以确保准确性。我没有测试过它;这只是给你一个想法。

以下是定义错误的方法:

将tensorflow导入为tf
def自定义二进制错误(y_真,y_pred):
y_-true=tf.cast(y_-true,tf.bool)
y_pred=tf.cast(y_pred,tf.bool)
xored=tf.logical\u xor(y\u true,y\u pred)
notxored=tf.logical\u not(xored)
sum\u xored=tf.reduce\u sum(tf.cast(xored,tf.float32))
sum\u notxored=tf.reduce\u sum(tf.cast(notxored,tf.float32))
返回和/(和+和)
使用2个尺寸为6的标签进行测试:

将tensorflow导入为tf
y_系列尺寸=6
y_train=[[1,1,1,1,1],[0,0,0,0,0]]
y_pred=tf。将_转换为_张量([[1,1,1,0,0],[0,0,0,1,0]]))
y=tf.placeholder(tf.int32,shape=(无,y\u train\u size))
错误=自定义二进制错误(y,y)
使用tf.Session()作为sess:
res=sess.run(错误,feed_dict={y:y_train})
打印(分辨率)#0.25
Keras
中使用它:

将tensorflow导入为tf
将numpy作为np导入
y_系列尺寸=6
def自定义二进制错误(y_真,y_pred):
y_-true=tf.cast(y_-true,tf.bool)
y_pred=tf.cast(y_pred,tf.bool)
xored=tf.logical\u xor(y\u true,y\u pred)
notxored=tf.logical\u not(xored)
sum\u xored=tf.reduce\u sum(tf.cast(xored,tf.float32))
sum\u notxored=tf.reduce\u sum(tf.cast(notxored,tf.float32))
返回和/(和+和)
model=tf.keras.models.Sequential()
模型.添加(tf.keras.layers.Dense(y_系列尺寸))
compile(optimizer=tf.keras.optimizers.SGD(0.01),
损失=[tf.keras.loss.MeanAbsoluteError()],
度量=[自定义\u二进制\u错误])
y_train=np.数组([[1,1,1,1,1,1],[0,0,0,0,0]]
x_序列=np.随机.正常(大小=(2,2))
模型拟合(x_序列,y_序列,历元=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
注意

如果希望准确而不是错误,则
自定义二进制错误()
函数应返回

sum\u notxored/(sum\u xored+sum\u notxored)

您的预测结果如何?它是一个整数值还是别的什么?对我来说,这是一种奇怪的编码方式!请问您为什么选择将模型设计为输出实数(稍后需要转换为整数)的方式?相反,您可以将其建模为一个多标签分类任务,其中sigmoid层作为最后一层。因此,我的最后一层将是一个密集层,其节点数量与我的类编码中的位数量相同,并通过sigmoid激活将输出映射到0-1。那么,我的损失/准确度度量是什么呢?这似乎是相关的:@RyanHope,没错。你需要使用
binary\u crossentropy
作为损失,使用
accurity
作为度量(它会自动切换到
binary\u accurity
)。是的,y\u true和t\u pred都是正整数,我会试一试,让我知道。这个想法在Python中有效。没有登记入住凯拉斯。希望我没有错过任何Keras特有的东西。如果我没有在Keras工作,我应该更具体地了解你的真实情况,而你之前。。。它们都是Keras张量(但一旦计算它们就应该是整数)。Tensorflow有一个按位异或,如果有办法解压位,然后求和,我可以除以最大位得到百分比是的,我预料会出现这样的问题。必须检查TF是否提供任何类似的功能。