keras 如何将图层的其中一个输出指定为0

3df52oht  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(121)

我有一个内置在keras,tensorflow 2.0中的模型,我想强制它最后一层的第一个输出为零。我该怎么做呢?
下面是我建立的模型和我对这个过程的尝试:

import tensorflow as tf
X = Input(shape=(32,))
Y = Dense(256, activation= 'relu', kernel_initializer=ini)(X)

下面是我尝试做的。我尝试创建另一个图层,它的所有值都是零,除了第一个值,这类似于图层Y的输出

def zeros_assign(Y):
    a = tf.zeros(256,)
    aa = aa[0].assign[-Y[0]]
    out = aa + Y
    return out

Y_out = Lambda(lambda x: channel(x))(Y)

但是当我运行该层时,它会给予出如下错误:TypeError:“Functional”对象不支持项赋值

des4xlb0

des4xlb01#

下面是一个解决方案,其中BlockFirstNode层传递来自上一层的所有输出,除了第一个被阻塞的节点(设置为0)。这是由Snoopy博士建议的乘以零。
代码示例:

import tensorflow as tf
import numpy as np

class BlockFirstNode(tf.keras.layers.Layer):
    def __init__(self) -> None:
        super().__init__()
    def build(self, input_shape):
        output_len = input_shape[1]
        bloc_vec_np = np.array([0]+[1]*(output_len-1)).reshape(1, output_len)
        self.block_vec = tf.convert_to_tensor(bloc_vec_np, dtype=tf.float32)
    def call(self, inputs):
        return inputs*self.block_vec

X = tf.keras.layers.Input(shape=(32,))
Y = tf.keras.layers.Dense(5, activation= 'sigmoid')(X)
block_output = BlockFirstNode()(Y)

model = tf.keras.models.Model(inputs=X, outputs=[Y, block_output])

pred_y, pred_block = model.predict(np.ones((1,32)))

print(f'Y: {np.round(pred_y,2)}') 
# Y: [[0.68 0.59 0.88 0.08 0.48]]
print(f'block_output: {np.round(pred_block,2)}')
# block_output: [[0.   0.59 0.88 0.08 0.48]]

在这里我们可以看到,除了第一个节点被强制为零之外,所有输出都与之前的层相同。

    • 编辑(2023年2月4日):**

现在按照萨贾德的要求,对任意n个阻塞进行运算。

import tensorflow as tf
import numpy as np

class BlockNFirstNode(tf.keras.layers.Layer):
    def __init__(self, n_blocking) -> None:
        super().__init__()
        self.n_blocking = n_blocking
    def build(self, input_shape):
        output_len = input_shape[1]
        if self.n_blocking>output_len:
            raise ValueError("n_blocking cannot be larger than layer size")
        bloc_vec_list = [0]*self.n_blocking+[1]*(output_len-self.n_blocking)
        bloc_vec_np = np.array(bloc_vec_list).reshape(1, output_len)
        self.block_vec = tf.convert_to_tensor(bloc_vec_np, dtype=tf.float32)
    def call(self, inputs):
        return inputs*self.block_vec

X = tf.keras.layers.Input(shape=(32,))
Y = tf.keras.layers.Dense(5, activation= 'sigmoid')(X)
block_output = BlockNFirstNode(n_blocking=2)(Y)

model = tf.keras.models.Model(inputs=X, outputs=[Y, block_output])

pred_y, pred_block = model.predict(np.ones((1,32)))

print(f'Y: {np.round(pred_y,2)}') 
# Y: [[0.68, 0.59, 0.88, 0.08, 0.48]]
print(f'block_output: {np.round(pred_block,2)}')
# block_output: [[0, 0, 0.88, 0.08, 0.48]]

相关问题