że patrzy na kod przykład dla gradientów przetwarzania, TensorFlow posiada:Czy można zaimplementować pochylenie gradientowe, takie jak optymalizatory, za pomocą przykładu kodu z przetwarzania gradientów w TensorFlow?
# Create an optimizer.
opt = GradientDescentOptimizer(learning_rate=0.1)
# Compute the gradients for a list of variables.
grads_and_vars = opt.compute_gradients(loss, <list of variables>)
# grads_and_vars is a list of tuples (gradient, variable). Do whatever you
# need to the 'gradient' part, for example cap them, etc.
capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars]
# Ask the optimizer to apply the capped gradients.
opt.apply_gradients(capped_grads_and_vars)
Jednakże, zauważyliśmy, że funkcja apply_gradients
pochodzi od GradientDescentOptimizer
. Czy to oznacza, że używając przykładowego kodu z góry, można wdrożyć tylko reguły gradientowe, takie jak zejście (zauważmy, że możemy zmienić opt = GradientDescentOptimizer
lublub którykolwiek z pozostałych optymalizatorów)? W szczególności, co robi apply_gradients
? Zdecydowanie sprawdzam kod w tf github page, ale był to garść pytonów, które nie miały nic wspólnego z wyrażeń matematycznych, więc trudno było powiedzieć, co to było i jak się zmieniło z optymalizatora na optymalizator.
Na przykład, jeśli chciałem zaimplementować własny niestandardowy optymalizator, który mógłby wykorzystywać gradienty (lub może np. Zmienić wagi bezpośrednio z pewną regułą, być może bardziej biologicznie prawdopodobną regułą), nie jest to możliwe z powyższym przykładowym kodem?
W szczególności chciałem wdrożyć wersję gradient zniżania, który jest sztucznie ograniczony w kompaktowej domenie. W szczególności chciałem zaimplementować następujące równanie:
w := (w - mu*grad + eps) mod B
w TensorFlow. Zdałem sobie sprawę, że prawdziwe są następujące:
w := w mod B - mu*grad mod B + eps mod B
więc pomyślałem, że może po prostu wdrożyć go wykonując:
def Process_grads(g,mu_noise,stddev_noise,B):
return (g+tf.random_normal(tf.shape(g),mean=mu_noise,stddev=stddev_noise)) % B
a potem po prostu mający:
processed_grads_and_vars = [(Process_grads(gv[0]), gv[1]) for gv in grads_and_vars]
# Ask the optimizer to apply the processed gradients.
opt.apply_gradients(processed_grads_and_vars)
jednak zdałem sobie sprawę, to nie było wystarczająco dobre, ponieważ nie mam dostępu do w
, więc nie mogę wykonać:
w mod B
przynajmniej nie tak, jak próbowałem. Czy jest jakiś sposób na zrobienie tego? tj. faktycznie bezpośrednio zmienić regułę aktualizacji? Przynajmniej tak, jak próbowałem?
Znam jego rodzaj hacky reguły aktualizacji, ale moim celem jest bardziej zmienić równanie aktualizacji niż faktycznie dbając o wiele o tej zasadzie aktualizacji (więc nie dajcie się zwiesić, jeśli to trochę dziwne).
wymyśliłem rozwiązanie Super Hacky:
def manual_update_GDL(arg,learning_rate,g,mu_noise,stddev_noise):
with tf.variable_scope(arg.mdl_scope_name,reuse=True):
W_var = tf.get_variable(name='W')
eps = tf.random_normal(tf.shape(g),mean=mu_noise,stddev=stddev_noise)
#
W_new = tf.mod(W_var - learning_rate*g + eps , 20)
sess.run(W_var.assign(W_new))
def manual_GDL(arg,loss,learning_rate,mu_noise,stddev_noise,compact,B):
# Compute the gradients for a list of variables.
grads_and_vars = opt.compute_gradients(loss)
# process gradients
processed_grads_and_vars = [(manual_update_GDL(arg,learning_rate,g,mu_noise,stddev_noise), v) for g,v in grads_and_vars]
nie wiem, czy to działa, ale coś takiego powinno działać w ogóle. Chodzi o to, aby zapisać równanie, które chce się wykorzystać (w TensorFlow) dla szybkości uczenia się, a następnie zaktualizować wagi ręcznie przy użyciu sesji.
Niestety, takie rozwiązanie oznacza, że musimy zadbać o wyżarzanie (rozkładanie tempa uczenia się ręcznie, co wydaje się denerwujące). To rozwiązanie prawdopodobnie ma wiele innych problemów, możesz je wskazać (i dać rozwiązania, jeśli możesz).
Do tego bardzo prostego problemu zdałem sobie sprawę, można po prostu zrobić normalne reguły aktualizacji Optimizer, a następnie po prostu wziąć mod ciężarami i ponownie przypisać je do ich wartości:
sess.run(fetches=train_step)
if arg.compact:
# apply w := (w - mu*g + eps) mod B
W_val = W_var.eval()
W_new = tf.mod(W_var,arg.B).eval()
W_var.assign(W_new).eval()
ale w w tym przypadku jest przypadkiem, że takie proste rozwiązanie istnieje (niestety, omija cały punkt mojego pytania).
Właściwie to rozwiązanie znacznie spowalnia kod. Na razie jest najlepszy, jaki mam.
Jako odniesienie, widziałem to pytanie: How to create an optimizer in Tensorflow, ale nie znalazł on odpowiedział bezpośrednio na moje pytanie.
Co jeśli modyfikować wszystkie gradienty być 'grad = W - (w mod B - MU * Grad mod b + EPS mod B) 'i mają wskaźnik uczenia się' 1.0', z 'tf.train.GradientDescentOptimizer'? To powinno stosować gradienty jako 'w - = grad', czyli' w = w mod B - mu * grad mod B + eps mod B'. –