Возможна реализация:
import tensorflow as tf
def maxnorm_regularizer(threshold, axes=1, name="maxnorm", collection="maxnorm"):
def maxnorm(weights):
clipped = tf.clip_by_norm(weights, clip_norm=threshold, axes=axes)
clip_weights = tf.assign(weights, clipped, name=name)
tf.add_to_collection(collection, clip_weights)
return None # there is no regularization loss term
return maxnorm
Вот как вы будете использовать его:
from tensorflow.contrib.layers import fully_connected
from tensorflow.contrib.framework import arg_scope
with arg_scope(
[fully_connected],
weights_regularizer=max_norm_regularizer(1.5)):
hidden1 = fully_connected(X, 200, scope="hidden1")
hidden2 = fully_connected(hidden1, 100, scope="hidden2")
outputs = fully_connected(hidden2, 5, activation_fn=None, scope="outs")
max_norm_ops = tf.get_collection("max_norm")
[...]
with tf.Session() as sess:
sess.run(init)
for epoch in range(n_epochs):
for X_batch, y_batch in load_next_batch():
sess.run(training_op, feed_dict={X: X_batch, y: y_batch})
sess.run(max_norm_ops)
Это создает 3 слоя нейронной сети и тренирует его с максимальной нормой регуляризации на каждом слое (с порогом 1,5). Я просто попробовал, похоже, работает. Надеюсь это поможет! Предложения по улучшению приветствуются. :)
Примечания
Этот код основан на tf.clip_by_norm()
:
>>> x = tf.constant([0., 0., 3., 4., 30., 40., 300., 400.], shape=(4, 2))
>>> print(x.eval())
[[ 0. 0.]
[ 3. 4.]
[ 30. 40.]
[ 300. 400.]]
>>> clip_rows = tf.clip_by_norm(x, clip_norm=10, axes=1)
>>> print(clip_rows.eval())
[[ 0. 0. ]
[ 3. 4. ]
[ 6. 8. ] # clipped!
[ 6.00000048 8. ]] # clipped!
Вы также можете закрепить столбцы, если вам нужно:
>>> clip_cols = tf.clip_by_norm(x, clip_norm=350, axes=0)
>>> print(clip_cols.eval())
[[ 0. 0. ]
[ 3. 3.48245788]
[ 30. 34.82457733]
[ 300. 348.24578857]]
# clipped!
Спасибо за указатель! Это выглядит очень близко к тому, что я хочу, только применительно ко всей матрице, тогда как я хотел бы перенормировать каждый столбец независимо (ala Torch's renorm). Это возможно? – danvk
Возможно, заменив вызов '' reduce_sum'' (https://github.com/tensorflow/tensorflow/blob/b11337ea5719a8799f279a41c2cd5c9e75a8acf7/tensorflow/python/ops/clip_ops.py#L90-L93) в 'clip_by_norm' с чем-то, что устанавливает [ 'reduction_indices'] (https://www.tensorflow.org/versions/master/api_docs/python/math_ops.html#reduce_sum)? – danvk
Ах, из вопроса, похоже, вы хотите нормализовать всю матрицу, используя ее норму, а не столбцы отдельно. –