#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_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]
Но модель.слои и сводка имеют только:
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-Layer отображался с именем? Кроме того, что, если я действительно хочу, чтобы все подслои были похожи на self.layernorm1 каждого EncoderLayer, который будет показан в модели.слои?
Комментарии:
1. старайтесь использовать не пользовательские слои классов, а простые функции, в которых вы комбинируете слои так, как хотите
2. Я думаю, что речь идет о функции сборки, инициализации и вызова, которую я читал несколько раз назад? Нужна ли мне функция сборки в классе layer? Почему это не отображается? Что мне нужно сделать, чтобы это отображалось, если я хотел бы использовать класс слоев?
3. Эй, извините, что я настаиваю, но как бы вы это сделали, если хотите использовать пользовательские слои?
4. ваш это просто набор существующих слоев… нет необходимости использовать пользовательский класс… используйте функцию
5. Не могли бы вы привести пример? Потому что это пользовательские слои для архитектуры transformer, и было бы неплохо вызвать слой transformer. Пожалуйста, объясните, что мне нужно сделать, потому что для пользовательских слоев вы можете найти много вещей, почему это не показано в сводке.