Как разделить веса с помощью tf.layers.conv2d

Я построил автоэнкодер, используя слои tf.layers.conv2d, и хотел бы обучать его поэтапно. То есть сначала тренировать внешние слои, затем средние слои, а затем внутренние. Я понимаю, что это возможно с помощью tf.nn.conv2d, потому что веса объявляются с помощью tf.get_variable, но я думаю, что это также должно быть возможно с помощью tf.layers.conv2d.

Если я ввожу новую область переменных, отличную от исходного графика, чтобы изменить входные данные для сверточных слоев (т.е. пропустить внутренние слои на этапе 1), я не смогу повторно использовать веса. Если я не войду в новую область переменных, я не смогу заморозить веса, которые я не хочу тренировать на этом этапе.

В основном я пытаюсь использовать метод обучения от Орельена Жерона здесь https://github.com/ageron/handson-ml/blob/master/15_autoencoders.ipynb

За исключением того, что я хотел бы использовать cnn вместо плотных слоев. Как это сделать?


person user3687879    schedule 25.04.2018    source источник


Ответы (2)


Нет необходимости создавать переменные вручную. Это работает так же хорошо:

import tensorflow as tf

inputs_1 = tf.placeholder(tf.float32, (None, 512, 512, 3), name='inputs_1')
inputs_2 = tf.placeholder(tf.float32, (None, 512, 512, 3), name='inputs_2')

with tf.variable_scope('conv'):
    out_1 = tf.layers.conv2d(inputs_1, 32, [3, 3], name='conv_1')

with tf.variable_scope('conv', reuse=True):
    out_2 = tf.layers.conv2d(inputs_2, 32, [3, 3], name='conv_1')

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    print(tf.trainable_variables())

Если вы дадите tf.layers.conv2d такое же имя, он будет использовать те же веса (при условии, что reuse=True, иначе будет ValueError).

В Tesorflow 2.0: tf.layers были заменены слоями keras, где переменные повторно используются с использованием одного и того же объекта слоя:

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           input_shape=(512, 512, 3)), 
])

@tf.function 
def f1(x):
    return model(x)

@tf.function 
def f2(x):
    return model(x)

И f1, и f2 будут использовать слой с одинаковыми переменными.

person BlueSun    schedule 26.04.2018
comment
Да, я согласен с вами, что это тоже работает, и я надеюсь, что решил бы сделать это, если бы писал код. Я просто имел в виду, что если вы относительно новичок в тензорном потоке, создание всех весов вручную может дать более четкое представление о том, что именно происходит — это убирает некоторые элементы черного ящика. - person ness_boy; 27.04.2018
comment
Вместо того, чтобы повторять tf.variable_scope(...) с тем же именем, вы можете просто позвонить scope.reuse_variables(). - person Zsolt Safrany; 01.05.2019
comment
Не могли бы вы обновить этот ответ до Tensorflow 2.0? Спасибо! - person becko; 09.01.2020
comment
@becko Tensorflow 2.0 не имеет tf.layers, но я добавил аналогичный пример. - person BlueSun; 09.01.2020

Я бы порекомендовал настроить его немного по-другому. Вместо использования tf.layers.conv2d я бы явно задавал веса с помощью вызовов tf.get_variable(), а затем использовал эти веса с вызовами tf.nn.conv2d(). Таким образом, вы не блокируете создание переменных и можете легко ссылаться на них. Это также хороший способ точно узнать, что происходит в вашей сети, поскольку вы написали формы для каждого набора весов вручную!

Пример (непроверенный) код:

inputs = tf.placeholder(tf.float32, (batch_size, 512, 512, 3), name='inputs')
weights = tf.get_variable(name='weights', shape=[5, 5, 3, 16], dtype=tf.float32)

with tf.variable_scope("convs"):
    hidden_layer_1 = tf.nn.conv2d(input=inputs, filter=weights, stride=[1, 1, 1, 1], padding="SAME")
with tf.variable_scope("convs", reuse=True):
    hidden_layer_2 = tf.nn.conv2d(input=hidden_layer_1, filter=weights,stride=[1, 1, 1, 1], padding="SAME"

Это создает сверточные веса и дважды применяет их к вашему вводу. Я не тестировал этот код, поэтому могут быть ошибки, но речь идет о том, как он должен выглядеть. Ссылки здесь для обмена переменными и здесь для tf.nn.conv2d.

Надеюсь, это поможет! Я был бы более тщательным, но я понятия не имею, как выглядит ваш код.

person ness_boy    schedule 25.04.2018
comment
Не могли бы вы обновить этот ответ до Tensorflow 2.0? Спасибо! - person becko; 09.01.2020