Я пробую обходной путь для исправления весов отдельных ядер в сверточной операции в TensorFlow с использованием Python 3.7.Я делаю это путем создания
- обучаемой переменной,
- идентичной не обучаемой переменной и
- тензора "маски", состоящего из 1 s и 0s с той же формой, что и созданные переменные в шагах 1 и 2 выше.
A 1 в тензоре «маска» указывает, чтоЯ хочу зафиксировать / заморозить этот конкретный вес во время тренировки, то есть не обновлять его при обратном проходе.
Теперь этот обходной путь работает отлично, когда применяется к полностью связанному слою, но не работает, когда применяется к сверточному слою иЯ не могу понять, почему или как заставить это работать.
Кажется, что-то происходит в вызове функции tf.nn.conv2d () (см. Пример кода ниже) и в соответствии св документации это то, что они делают:
Учитывая входной тензор формы [batch, in_height, in_width, in_channels]
и тензор фильтра / ядра формы
[filter_height, filter_width, in_channels, out_channels]
, этот оператор
выполняет следующее:
1. Сглаживает фильтр в 2-D матрице с помощьюhape
[filter_height * filter_width * in_channels, output_channels]
.
2. Извлекает патчи изображения из входного тензора для формирования виртуального
тензора формы [batch, out_height, out_width,<br>
filter_height * filter_width * in_channels]
.
3. Для каждого патча справа- умножает матрицу фильтра и патч изображения
vector.
Но так как я использую 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 , но вместо этого они ненулевые, и поэтому эти веса обучаются, что не является поведением I 'Я пытаюсь достичь.