Tensorflow keras中的自定义嵌套层-如何获取每个层的输出值并为摘要设置名称?

Tensorflow keras中的自定义嵌套层-如何获取每个层的输出值并为摘要设置名称?,tensorflow,keras,Tensorflow,Keras,我有自定义图层,希望为输入数据获得一个特定图层的输出。另外,我想在模型摘要中查看一些或所有自定义层的名称。但它只显示主层,而不是所有单个子层 这里是一个抽象的例子 class EncoderLayer(tf.keras.layers.Layer): def __init__(self, d_model, num_heads, dff, rate=0.1): super(EncoderLayer, self).__init__() self.ffn = point_wise_

我有自定义图层,希望为输入数据获得一个特定图层的输出。另外,我想在模型摘要中查看一些或所有自定义层的名称。但它只显示主层,而不是所有单个子层

这里是一个抽象的例子

class EncoderLayer(tf.keras.layers.Layer):
  def __init__(self, d_model, num_heads, dff, rate=0.1):
    super(EncoderLayer, self).__init__()

    self.ffn = point_wise_feed_forward_network(d_model, dff)

    self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6)
    self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6)

    self.dropout1 = tf.keras.layers.Dropout(rate)
    self.dropout2 = tf.keras.layers.Dropout(rate)

  def call(self, x, training, mask):


    attn_output = self.dropout1(x, training=training)
    out1 = self.layernorm1(x + attn_output)  # (batch_size, input_seq_len, d_model)

    ffn_output = self.ffn(out1)  # (batch_size, input_seq_len, d_model)
    ffn_output = self.dropout2(ffn_output, training=training)
    out2 = self.layernorm2(out1 + ffn_output)  # (batch_size, input_seq_len, d_model)

    return out2


class Encoder(tf.keras.layers.Layer):
  def __init__(self,embedding_layer, num_layers, d_model, num_heads, dff, input_vocab_size,
               maximum_position_encoding, rate=0.1):
    super(Encoder, self).__init__()

    self.d_model = d_model
    self.num_layers = num_layers

    self.embedding = tf.keras.layers.Embedding(input_vocab_size, d_model)



    self.enc_layers = [EncoderLayer(d_model, num_heads, dff, rate)
                       for _ in range(num_layers)]

    self.dropout = tf.keras.layers.Dropout(rate)
    
  def call(self, x, training, mask):

    seq_len = tf.shape(x)[1]

    x = self.embedding(x) 

    x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))

    x = self.dropout(self.x_fast, training=training)

    for i in range(self.num_layers):
      x = self.enc_layers[i](x, training, mask)

    return x  # (batch_size, input_seq_len, d_model)




def Model(nb_words=50000,MAX_SEQUENCE_LENGTH=12,d_model=300,act='relu',embedding_matrix=None):


    input_q1 = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='int32')
    input_q2 = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='int32')


    Encoder_Layer= Encoder(num_layers=1, d_model=d_model, num_heads=1,
                             dff=64, input_vocab_size=MAX_NB_WORDS,
                             maximum_position_encoding=10000)


    x1 = Encoder_Layer(input_q1, training=False, mask=None)
    x2 = Encoder_Layer(input_q2, training=False, mask=None)


    x = concatenate([x1,x2],1)

    x = GlobalAveragePooling1D()(x)

    merged = Dropout(0.3)(x)
    merged = BatchNormalization()(merged)

    merged = Dense(64, activation=act)(merged)
    merged = Dropout(0.3)(merged)
    x = BatchNormalization()(merged)

    x = Dense(64,activation=act)(x)

    preds = Dense(1,activation='sigmoid')(x)


    model = Model(inputs=[input_q1,input_q2],outputs=preds)
    model.compile(loss='binary_crossentropy',
            optimizer='adam',
            metrics=['accuracy'])
    print(model.summary())

    return model
现在,我想从编码器层获得第一次嵌入的输出:

x = self.embedding(x) 
我通过

model = build_model() 
# lstm_67 is the second layer.
lstm = K.function([model.layers[0].input], [model.layers[1].output])
lstm_output = lstm([test_x])[0]
但是model.layers和summary只有:

Layer (type)                    Output Shape         Param #     Connected to
==================================================================================================
input_1 (InputLayer)            [(None, 12)]         0
__________________________________________________________________________________________________
input_2 (InputLayer)            [(None, 12)]         0
__________________________________________________________________________________________________
encoder (Encoder)               (None, 12, 300)      580264      input_1[0][0]
                                                                 input_2[0][0]
__________________________________________________________________________________________________
concatenate (Concatenate)       (None, 48, 300)      0           encoder[0][0]
                                                                 encoder[1][0]
                                                                 subtract[0][0]
                                                                 add[0][0]
__________________________________________________________________________________________________
dropout_5 (Dropout)             (None, 48, 300)      0           concatenate[0][0]
__________________________________________________________________________________________________
batch_normalization (BatchNorma (None, 48, 300)      1200        dropout_5[0][0]
__________________________________________________________________________________________________
dense_16 (Dense)                (None, 48, 64)       19264       batch_normalization[0][0]
__________________________________________________________________________________________________
dropout_6 (Dropout)             (None, 48, 64)       0           dense_16[0][0]
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 48, 64)       256         dropout_6[0][0]
__________________________________________________________________________________________________
dense_17 (Dense)                (None, 48, 64)       4160        batch_normalization_1[0][0]
__________________________________________________________________________________________________
dense_18 (Dense)                (None, 48, 1)        65          dense_17[0][0]
==================================================================================================
Total params: 605,209
Trainable params: 604,481
Non-trainable params: 728
_____________________________
但是由于子层和这个嵌入层不在层和概要中,我想我必须首先把它们放在那里


所以它只显示编码器层。但是如果我想让每个单独的EncoderLayer层都显示名称呢?另外,如果我真的希望每个编码器层的所有子层(如self.layernorm1)都显示在model.layers中,该怎么办?

尽量不要使用自定义类层,而是使用简单的函数,在这里,您可以按照您想要的方式组合层,我认为这是关于构建、初始化和调用函数的,我以前读过几次?我需要层类中的构建函数吗?为什么不显示?如果我想使用图层类,我需要做什么?嘿,对不起,我灌输了,但如果你想使用自定义图层,你会怎么做?你的it只是现有图层的叠加。。。不需要使用自定义类。。。你能举个例子吗?因为这些是transformer架构的自定义层,所以最好调用transformer层。请说明我需要做什么,因为对于自定义层,您可以找到很多东西,说明为什么没有在摘要中显示。