简体   繁体   English

Keras 根据阈值将中间层的输出设置为 0 或 1

[英]Keras set output of intermediate layer to 0 or 1 based on threshold

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.在执行乘法之前,我想根据阈值将分类部分的输出设置为 0 或 1。 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.我尝试使用带有自定义函数的 Lambda 层,如下所示,但是我遇到了各种错误,我对这些错误一无所知。 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 层函数?

My current Lambda layer function: (not working due to FailedPreconditionError: Attempting to use uninitialized value lstm_32/bias )我当前的 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)

Regression part:回归部分:

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'))

Classification part:分类部分:

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

Merge two parts:合并两部分:

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

In func , you cannot eval the tensors.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.如果您评估张量并尝试使用这些值,您将断开连接。

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.并且输入数据仅在您调用fitpredict和类似方法时才会存在。 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 

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 ).这意味着在此之前的权重不会在训练期间更新(您不会通过m2训练分类模型,但您仍然可以从model2训练它)。 There are some fancy workarounds for this, if you need them, please write a comment.有一些奇特的解决方法,如果您需要它们,请写评论。

Use this function in a Lambda layer:Lambda层中使用此函数:

model.add(Lambda(func, output_shape=yourOutputShapeIfUsingTheano))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM