Используйте значение тензора для изменения другого тензора во время выполнения
В TensorFlow я хотел бы применить одну из "поддельных" функций квантования к одному из моих тензоров. Конкретно я заинтересован в использовании этой функции:
fake_quant_with_min_max_args(
inputs,
min=-6,
max=6,
num_bits=8,
narrow_range=False,
name=None
)
Он работает просто отлично из коробки. В идеале я хотел бы настроить min
а также max
аргументы в зависимости от входного тензора. Конкретно, я хочу использовать правило 99,7% для определения этого диапазона. Другими словами, я хочу использовать диапазон значений, который, если представлять входной тензор в качестве одномерного вектора, 99,7% его элементов будет лежать в диапазоне [mean-3*std, mean + 3*std].
Для этого я делаю следующее:
def smartFakeQuantization(tensor):
# Convert the input tensor to a 1-d tensor
t_1d_data = tf.reshape(tensor,[tf.size(tensor), 1])
# get the moments of that tensor. Now mean and var have shape (1,)
mean, var = tf.nn.moments(t_1d_data, axes=[0])
# get a tensor containing the std
std = tf.sqrt(var)
< some code to get the values of those tensors at run-time>
clip_range = np.round([mean_val - 3*std_val, mean_val + 3*stdstd_val], decimals=3)
return tf.fake_quant_with_min_max_args(tensor, min=clip_range[0], max=clip_range[1])
Я знаю, что могу оценить любой тензор в графе, выполнив: myTensor.eval()
или же mySession.run(myTensor)
но если я добавлю такие линии в мою функцию выше, это приведет к сбою при выполнении графика. Я получу ошибку в форме:
тензор <...> помечен как недоступный для извлечения.
Вероятно, шаги, которые я выполняю, не являются правильными для "графика" природы TensorFlow. Есть идеи, как это можно сделать? Подводя итог, я хочу использовать значение тензора во время выполнения, чтобы изменить другой тензор. Я бы сказал, что эта проблема сложнее, чем то, что можно сделать с tf.cond()
,
2 ответа
Я не думаю, что есть простой способ сделать то, что вы хотите. min
а также max
аргументы fake_quant_with_min_max_args
преобразуются в атрибуты операций и используются в базовой конструкции ядра. Они не могут быть изменены во время выполнения. Есть несколько (казалось бы, не часть публичного API) операций (см. LastValueQuantize
а также MovingAvgQuantize
), которые корректируют свои интервалы в зависимости от данных, которые они видят, но они делают не совсем то, что вы хотите.
Вы можете написать свой собственный вариант или, если вы считаете, что это вообще что-то ценное, подать запрос на добавление функций на github
Вы можете использовать tf.fake_quant_with_min_max_vars, который принимает тензоры в качестве аргументов min/max:
return tf.fake_quant_with_min_max_vars(tensor, min=mean-3*std, max=mean+3*std)