Tensorflow 我希望我的神经网络输出为0或1,而不是介于0和1之间的概率,在输出层使用定制的阶跃函数
我希望我的神经网络输出是0或1,而不是介于0和1之间的概率 同样,我为输出层设计了阶跃函数,我希望我的输出层只需对上一层(softmax)的输出进行舍入,即将概率转换为0和1Tensorflow 我希望我的神经网络输出为0或1,而不是介于0和1之间的概率,在输出层使用定制的阶跃函数,tensorflow,keras,neural-network,activation-function,Tensorflow,Keras,Neural Network,Activation Function,我希望我的神经网络输出是0或1,而不是介于0和1之间的概率 同样,我为输出层设计了阶跃函数,我希望我的输出层只需对上一层(softmax)的输出进行舍入,即将概率转换为0和1 我的定制功能没有提供预期的结果。 请帮忙 我的代码是: from keras.layers.core import Activation from keras.models import Sequential from keras import backend as K # Custom activation functi
我的定制功能没有提供预期的结果。 请帮忙 我的代码是:
from keras.layers.core import Activation
from keras.models import Sequential
from keras import backend as K
# Custom activation function
from keras.layers import Activation
from keras import backend as K
from keras.utils.generic_utils import get_custom_objects
@tf.custom_gradient
def custom_activation(x):
print("tensor ",x)
ones = tf.ones(tf.shape(x), dtype=x.dtype.base_dtype)
zeros = tf.zeros(tf.shape(x), dtype=x.dtype.base_dtype)
def grad(dy):
return dy
print(" INSIDE ACTOVATION FUNCTION ")
return keras.backend.switch(x > .5, ones, zeros), grad
model = keras.models.Sequential()
model.add(keras.layers.Dense(32,input_dim=a,activation='relu'))
model.add(keras.layers.Dropout(0.2))
model.add(keras.layers.Dense(64,activation="relu"))
model.add(keras.layers.Dropout(0.2))
model.add(keras.layers.Dense(2,activation='softmax'))
model.add(Activation(custom_activation, name='custom_activation'))#output layer
### Compile the model
model.compile(loss="binary_crossentropy",optimizer='adam',metrics=["accuracy"])
首先,请注意,获得类别概率总是比纯0-1分类产生更多的信息,因此您的模型几乎总是训练得更好更快 也就是说,考虑到您确实有一个限制NN的潜在原因,像您希望作为激活函数实现的一个艰难决定被称为步进函数或重行函数。该函数的主要问题是,默认情况下,该函数是不可微的(阈值中存在无限斜率,在您的情况下为0.5)。要解决此问题,您有两种选择:
tf.cond()
,它依赖于tf的AutoGrad,在运行时只执行图形的一个分支,并忽略未使用的分支类禁用(tf.keras.layers.Layer):
def uu init uu(self,num_输出,阈值=.5,**kwargs):
超级(自失活)。\uuuuu初始化(**kwargs)
self.num\u输出=num\u输出
self.threshold=阈值
def构建(自我,输入_形状):
通过
def呼叫(自我,输入):
返回tf.cond(输入>自阈值,
lambda:tf.add(tf.multiply(输入,0),1),#设置为1
lambda:tf.multiply(输入,0))#设置为0
#>……同上
添加模型(keras.layers.Dense(2,activation='softmax'))
添加(MyHeavisideActivation(2,name='custom_activation'))#输出层
我认为您可以使用模型。预测类(…)
而不是模型。预测(…)
。这将输出类而不是概率。“我的自定义函数没有给出预期的结果”,这太模糊了,您需要非常精确地了解预期和实际发生的情况。@Dr.Snoopy我希望我的自定义函数只将概率转换为二进制值(0或1)。输出层只需将softmax层的输出(概率)转换为1或0,而我的代码在案例1和案例2中得到了不同的混淆矩阵。案例1:softmax层为输出层案例2:softmax层后接自定义激活功能层(自定义层为输出层),我希望格式为1和0,即不是概率自定义层应简单地对值进行四舍五入。i、 e.0.7比1,0.3比0,87比1。等等。你确定知道你在做什么吗?你确定二进制交叉熵损失在你试图构建的(非常尴尬的)情况下会起作用吗?或者你只是决定忽略过去50年的所有ML理论,并尝试这样做,所以你需要在输出中使用硬类?我使用了你的代码,后面是我的定制激活函数(使用def grad(Div):return Div*1;as grad function,)但是获取错误tensorflow.python.framework.errors\u impl.invalidargumeinterror:第二个输入必须是标量,但它具有形状[32,2][{{{节点梯度\u磁带/顺序/模块\u包装器/自定义\u激活/cond/无状态if/switch\u pred/\u 11}]][Op:\u推理\u训练\u函数\u 884]函数调用堆栈:训练函数