градиент для fmin_tnc не работает - PullRequest
0 голосов
/ 04 июля 2018

Я тренирую мультиклассовую логистическую регрессию для распознавания рукописного ввода. Для минимизации функций я использую fmin_tnc. Я реализовал градиентную функцию следующим образом:

    def gradient(theta,*args):
        X,y,lamda = args;
        m = np.size(X,0);
        h = X.dot(theta);
        grad = (1/m) * X.T.dot(  sigmoid(h)-y );
        grad[1:np.size(grad),] = grad[1:np.size(grad),] + (lamda/
                        m)*theta[1:np.size(theta),] ;
    return grad.flatten() 
#flattened because  fmin_tnc accepts list of gradients

Это дает правильные значения градиента для небольшого набора примеров, представленного ниже:

  theta_t = np.array([[-2],[-1],[1],[2]]);
  X_t = np.array([[1,0.1,0.6,1.1],[1,0.2,0.7,1.2],[1,0.3,0.8,1.3], 
      [1,0.4,0.9,1.4],[1,0.5,1,1.5]])
  y_t = np.array([[1],[0],[1],[0],[1]])
  lamda_t = 3

Но при использовании функции checkgrad от scipy ошибка выдачи 0.6222474393497573 Я не могу отследить, почему это происходит. Из-за этого может быть fmin_tnc не выполняет никакой оптимизации и всегда дает оптимизированные параметры, равные заданным начальным параметрам.

1 Ответ

0 голосов
/ 05 июля 2018

Вызов функции fmin_tnc выглядит следующим образом:

    optimize.fmin_tnc(func=lrcostfunction, x0=initial_theta,fprime = gradient,args= 
   (X,tmp_y.flatten(),lamda))

Поскольку передаваемая y и тета имеет массив 1-й формы, имеющий размер (n,), он должен быть преобразован в массив 2-й, имеющий размер (n, 1). Это связано с тем, что в градиенте используется форма двумерного массива реализация функции. Правильная реализация выглядит следующим образом:

     def gradient(theta,*args):
         #again y and theta reshaped for same reason 
         X,y,lamda = args;
         l = np.size(X,1);
         theta = np.reshape(theta,(l,1));
         m = np.size(X,0);
         y = np.reshape(y,(m,1));
         h = sigmoid( X.dot(theta) );

         grad = (1/m) * X.T.dot( h-y );
         grad[1:np.size(grad),] = grad[1:np.size(grad),] + 
             (lamda/m)*theta[1:np.size(theta),] ;

     return grad.ravel()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...