Keras根据阈值将中间层的输出设置为0或1 [英] Keras set output of intermediate layer to 0 or 1 based on threshold

查看:893
本文介绍了Keras根据阈值将中间层的输出设置为0或1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像零件一样具有分类"和回归"的模型.我使用乘法层合并它们.在执行乘法之前,我想基于阈值将分类部分的输出设置为0或1.我尝试将Lambda层与自定义函数配合使用,如下所示,但是我遇到了各种错误,并且对这些错误一无所知.我一步一步地解决它们并没有加深我的理解.谁能解释如何定义可修改值的自定义Lambda图层函数?

I have a model that has "classification" and "regression" like parts. I merge them using multiplication layer. Before performing multiplication I want to set outputs of classification part to 0 or 1 based on threshold. I tried to use Lambda layer with custom function as below, however I am facing various errors, and I have no clue about those errors. Resolving them one by one as I go does not add to my understanding. Can anyone explain how to define custom Lambda layer function that modifies the values?

我当前的Lambda图层功能:(由于FailedPreconditionError: Attempting to use uninitialized value lstm_32/bias而无法使用)

def func(x):    
    a = x.eval(session=tf.Session())
    a[x < 0.5] = 0
    a[x >= 0.5] = 1
    return K.variable(a)

回归部分:

input1 = Input(shape=(1, ))
model = Sequential()
model.add(Embedding(vocab_size + 1, embedding, input_length=1))
model.add(LSTM(hidden, recurrent_dropout=0.1, return_sequences=True))
model.add(LSTM(6))
model.add(Reshape((3,2)))
model.add(Activation('linear'))

分类部分:

input2 = Input(shape=(1, ))
model2 = Sequential()
model2.add(Embedding(vocab_size + 1, embedding, input_length=1))
model2.add(LSTM(hidden, recurrent_dropout=0.1, return_sequences=True))
model2.add(LSTM(1))
model2.add(Activation('sigmoid'))
model2.add(???)  # need to add 0-1 thresholding here

合并两个部分:

reg_head = model(input1)
clf_head = model2(input2)    
merge_head = multiply(inputs=[clf_head, reg_head])
m2 = Model(inputs=[input1, input2], outputs=merge_head)

推荐答案

func中,您不能eval张量.

使用张量的想法是,它们在整个模型中始终保持连接"(即他们所称的图形).此连接允许模型计算梯度.如果评估张量并尝试使用这些值,则将断开连接.

The idea of using tensors is that they keep a "connection" (a graph, as they call it) from start to end in the entire model. This connection allows the model to compute gradients. If you eval a tensor and try to use these values, you will break the connection.

此外,要获取张量的实际值,您需要输入数据.并且输入数据仅在调用fitpredict和类似方法时存在.在构建阶段,没有数据,只有表示和连接.

Also, for taking the actual values of a tensor, you need the input data. And the input data will only exist when you call fit, predict and similar methods. In the build phase there isn't data, only representations and connections.

仅使用张量的可能函数是:

A possible function using only tensors is:

def func(x):

    greater = K.greater_equal(x,0.5) #will return boolean values
    greater = K.cast(greater, dtype=K.floatx()) #will convert bool to 0 and 1    
    return greater 

但是要小心!这将是不可区分的.从现在开始,这些值将在模型中视为常量.这意味着在训练期间不会更新此点之前的权重(您不会通过m2训练分类模型,但是仍然可以从model2训练它).有一些不错的解决方法,如果您需要它们,请写评论.

But be careful! This will not be differentiable. These values will be seen as constants from now on in the model. This means that the weights coming before this point will not be updated during training (you won't train the classification model via m2, but you will still be able to train it from model2). There are some fancy workarounds for this, if you need them, please write a comment.

Lambda层中使用此功能:

model.add(Lamnda(func,output_shape=yourOtputShapeIfUsingTheano))

这篇关于Keras根据阈值将中间层的输出设置为0或1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆