Замораживание подслоев в тензорном потоке 2 - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть модель, которая состоит из пользовательских слоев. Каждый пользовательский слой содержит много файлов tf.keras.layers. Проблема в том, что если я хочу заморозить эти слои после определения моей модели, цикл:

for i, layer in enumerate(model.layers):
    print(i, layer.name)

печатает только «внешние» пользовательские слои, а не те, которые существуют внутри. Есть ли способ получить доступ к внутренним слоям, чтобы я мог их заморозить?

пример пользовательского слоя из официальных документов tf :

class MLPBlock(layers.Layer):

  def __init__(self):
    super(MLPBlock, self).__init__()
    self.linear_1 = Linear(32)
    self.linear_2 = Linear(32)
    self.linear_3 = Linear(1)

  def call(self, inputs):
    x = self.linear_1(inputs)
    x = tf.nn.relu(x)
    x = self.linear_2(x)
    x = tf.nn.relu(x)
    return self.linear_3(x)

Ответы [ 2 ]

1 голос
/ 06 ноября 2019

Что вы делаете в своей функции обновления, это замените первый Dense() слой другим Dense() слоем, на этот раз установив trainable = false.

Пока это работает, я бы обновил 'update'функция следующим образом:

 def updt(self):
     self.dense1.trainable = False
0 голосов
/ 06 ноября 2019

Хорошо, я придумала решение. Функция «обновления» должна быть реализована внутри пользовательского слоя, который обновляет внутренние слои, чтобы они стали не обучаемыми. Вот пример кода:

import tensorflow as tf
import numpy as np

layers = tf.keras.layers

seq_model = tf.keras.models.Sequential


class MDBlock(layers.Layer):

    def __init__(self):
        super(MDBlock, self).__init__()
        self.dense1 = layers.Dense(784, name="first")
        self.dense2 = layers.Dense(32, name="second")
        self.dense3 = layers.Dense(32, name="third")
        self.dense4 = layers.Dense(1, activation='sigmoid', name="outp")

    def call(self, inputs):
        x = self.dense1(inputs)
        x = tf.nn.relu(x)
        x = self.dense2(x)
        x = tf.nn.relu(x)
        x = self.dense3(x)
        x = tf.nn.relu(x)
        x = self.dense4(x)
        return x

    def updt(self):
        self.dense1.trainable = False

    def __str__(self):
        return "\nd1:{0}\nd2:{1}\nd3:{2}\nd4:{3}".format(self.dense1.trainable, self.dense2.trainable,
                                                         self.dense3.trainable, self.dense4.trainable)


# define layer block
layer = MDBlock()

model = seq_model()
model.add(layers.Input(shape=(784,)))
model.add(layer)

# Use updt function to make layers non-trainable
for i, layer in enumerate(model.layers):
    layer.updt()

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# Generate dummy data
data = np.random.random((1000, 784))
labels = np.random.randint(2, size=(1000, 1))

# Train the model, iterating on the data in batches of 32 samples
model.fit(data, labels, epochs=10, batch_size=32)

# print block's layers state
for i, layer in enumerate(model.layers):
    print(i, layer)


...