Theano с Python2.7: SGD с множественными потерями

После того, как мне похвалили Теано, я подумал, что сделаю свои первые шаги с определенной формой SGD. У меня есть тета-вектор параметров, который я хочу оптимизировать. Моя функция потерь возвращает вектор, содержащий суммы столбцов квадратов потерь между матрицами A и B. Каждый из элементов является независимой потерей для определенного измерения с использованием широковещательной тета . Theta следует обновить, чтобы на следующей итерации потери для каждого измерения были ниже. Я выбрал это, потому что данные (X, Y) задаются таким образом.

Теперь в учебнике говорится, что T.grad() следует использовать для получения градиента для обновлений. Но T.grad не позволяет мне вычислить градиент для не скаляров. Учебное пособие (http://deeplearning.net/software/theano/tutorial/gradients.html) говорит: «Скалярные затраты могут быть непосредственно обработаны только grad. Массивы обрабатываются с помощью повторяющихся приложений». Поэтому я попытался (по общему признанию, безобразная попытка) рассчитать градиент для каждой потери. Как рассчитать градиенты для множественных потерь? И есть ли чистый, лучший способ? Это даже правильно? Что-то еще, что я должен рассмотреть?

Мартин

import numpy
from theano import tensor as T
from theano import function
from theano import shared

alpha = 0.00001
theta = shared(numpy.random.rand(10), name='theta')
X = T.dmatrix(name='X')
Y = T.dmatrix(name='Y')
losses = T.sqr(theta * X - Y).sum(axis=0)

Вот где это становится странным: поскольку T.grad(loss, theta) выдает TypeError: cost должен быть скаляром. Итак, я получил эту уродливую попытку:

d_losses = [T.grad(losses[i], theta) for i in xrange(len(theta.get_value()))] 
updates = [(theta, theta - numpy.array(alpha) * d_losses)]

Когда я хочу скомпилировать его, я получаю это:

    >>> f = function(inputs=[A], outputs=loss, updates=updates)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/lib/python2.7/dist-packages/theano/compile/function.py", line 266, in function
    profile=profile)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 489, in pfunc
    no_default_updates=no_default_updates)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 202, in rebuild_collect_shared
    update_val = store_into.type.filter_variable(update_val)
  File "/usr/local/lib/python2.7/dist-packages/theano/tensor/type.py", line 206, in filter_variable
    other = self.Constant(type=self, data=other)
  File "/usr/local/lib/python2.7/dist-packages/theano/tensor/var.py", line 732, in __init__
    Constant.__init__(self, type, data, name)
  File "/usr/local/lib/python2.7/dist-packages/theano/gof/graph.py", line 443, in __init__
    self.data = type.filter(data)
  File "/usr/local/lib/python2.7/dist-packages/theano/tensor/type.py", line 115, in filter
    up_dtype = scal.upcast(self.dtype, data.dtype)
  File "/usr/local/lib/python2.7/dist-packages/theano/scalar/basic.py", line 67, in upcast
    rval = str(z.dtype)
AttributeError: 'float' object has no attribute 'dtype'

person Martin T.    schedule 06.10.2015    source источник
comment
Зачем вам несколько потерь? Вы можете получить скалярную потерю и вывести w.r.t. каждому компоненту теты.   -  person Mikael Rousson    schedule 06.10.2015
comment
то есть вы имеете в виду d_loss = [T.grad(loss,theta[i]) for i in xrange(len(theta.get_value()))] ? Или как бы я это сделал? Первоначальная мысль заключалась в том, что у каждой функции есть свои потери, которые я хотел зафиксировать.   -  person Martin T.    schedule 06.10.2015


Ответы (1)


Как отмечает Микаэль Руссон в комментарии, для целей градиента вам, вероятно, не нужно иметь дело с отдельными потерями; просто суммируйте все компоненты потерь в скаляр, а затем вычислите частные производные по отношению к вектору параметров, получив вектор градиентов.

Так что добавь

loss = losses.sum()

или напрямую определить скалярную потерю

loss = T.sqr(theta * X - Y).sum()

затем используйте

d_losses = T.grad(loss, theta)
updates = [(theta, theta - alpha * d_losses)]

d_losses[0] равно частной производной от loss по отношению к theta[0], но единственный член в loss, который включает theta[0], является компонентом суммы по первому элементу losses, поэтому он также равен частной производной от losses[0] по отношению к theta[0], что в точности равно то, что вы хотите, я думаю.

person Daniel Renshaw    schedule 07.10.2015
comment
это имеет смысл. Благодарю вас! - person Martin T.; 08.10.2015