#python-3.x #tensorflow #conv-neural-network
#python-3.x #тензорный поток #conv-нейронная сеть
Вопрос:
Я пытаюсь найти обходной путь для исправления отдельных весов ядра в сверточной операции в TensorFlow с использованием Python 3.7. Я делаю это, создавая
- обучаемая переменная,
- идентичная необучаемая переменная и
- тензор «маски», состоящий из 1 с и 0 с той же формой, что и созданные переменные на шаге 1 и 2 выше.
1 в тензоре «маски» указывает, что я хочу исправить / заморозить этот удельный вес во время обучения, т. Е. Не Обновлять его при обратном проходе.
Теперь это обходное решение отлично работает при применении к полностью подключенному слою, но терпит неудачу при применении к сверточному слою, и я не могу понять, почему или как заставить его работать.
Похоже, что-то происходит в вызове функции tf.nn.conv2d() (см. Пример кода ниже), и, согласно документации, это то, что они делают:
Задан входной тензор формы
[batch, in_height, in_width, in_channels]
и тензор фильтра / ядра формы
[filter_height, filter_width, in_channels, out_channels]
, эта операция
выполняет следующее:
1. Сглаживает фильтр до 2-мерной матрицы с формой
[filter_height * filter_width * in_channels, output_channels]
.
2. Извлекает участки изображения из входного тензора для формирования виртуального
тензор формы[batch, out_height, out_width,<br>
.
filter_height * filter_width * in_channels]
3. Для каждого исправления перемножает матрицу фильтра и
вектор исправления изображения.
Но поскольку я использую weights_frozen, который является тензором и зависит от обучаемой переменной, необучаемой переменной и mask_weights, он должен получать градиенты с нулевым значением в позициях, где у меня есть 1 в тензоре mask_weights.
def conv(input_, layer_name...):
weights = tf.get_variable(shape=[filter_height, filter_width, in_channels, out_channels], dtype=tf.float32, initializer=tf.glorot_uniform_initializer(), trainable=True)
weights_fixed = tf.Variable(tf.identity(weights), trainable=False)
mask_weights = tf.placeholder(tf.float32, weights.shape)
weights_frozen = tf.add(tf.multiply(mask_weights, weights_fixed), tf.multiply((1 - mask_weights), weights))
out_conv = tf.nn.conv2d(input=input_, filter=weights_frozen, strides=strides_, padding='SAME')
out_add = tf.nn.bias_add(value=out_conv, bias=biases_frozen)
out = tf.nn.relu(features=out_add)
return out
Как уже упоминалось, я ожидаю получить градиенты с нулевым значением в позициях, где у меня есть 1 в тензоре mask_weights, но вместо этого они ненулевые, и поэтому эти веса обучаются, а это не то поведение, которого я пытаюсь достичь.