2015-01-07 12 views
1

Пытаясь использовать Backpropagation Neural Network для классификации многоклассов. Я нашел this code и попытаюсь его адаптировать. Он основан на лекциях Machine Learning in Coursera from Andrew Ng.Использование scipy.optimize.minimize в нейронной сети

Непонятная реализация scipy.optimize.minimize здесь. Он используется только один раз в коде. Является ли оно итерационным обновлением весов сети? Как я могу визуализировать (сюжет) его производительность, чтобы увидеть, когда он сходится?

С помощью этой функции какие параметры я могу настроить для достижения лучшей производительности? Я нашел here список общих параметров:

  • Количество нейронов в скрытом слое: это в моем коде
  • курса обучения hidden_layer_size=25: Могу ли я настроить, что использование встроенной функции минимизации?
  • Momentum: является то, что reg_lambda=0 в моем случае? Параметр регуляризации, чтобы избежать переобучения, не так ли?
  • Epoch: maxiter=500

Вот моя подготовка данных (целевой класс в последнем столбце):


65535, 3670, 65535, 3885, -0.73, 1 
65535, 3962, 65535, 3556, -0.72, 1 
65535, 3573, 65535, 3529, -0.61, 1 
3758, 3123, 4117, 3173, -0.21, 0 
3906, 3119, 4288, 3135, -0.28, 0 
3750, 3073, 4080, 3212, -0.26, 0 
65535, 3458, 65535, 3330, -0.85, 2 
65535, 3315, 65535, 3306, -0.87, 2 
65535, 3950, 65535, 3613, -0.84, 2 
65535, 32576, 65535, 19613, -0.35, 3 
65535, 16657, 65535, 16618, -0.37, 3 
65535, 16657, 65535, 16618, -0.32, 3 

Зависимости настолько очевидны, я думаю, что это должно быть так легко чтобы его классифицировать ...

Но результаты ужасные. Я получаю точность от 0,6 до 0,8. Это совершенно неуместно для моего приложения. Я знаю, что мне нужно больше данных, как правило, но я был бы уже счастлив, когда я мог бы по крайней мере соответствовать подготовки данных (без учета потенциальной переобучения)

Вот код:

import numpy as np 
from scipy import optimize 

from sklearn import cross_validation 
from sklearn.metrics import accuracy_score 
import math 

class NN_1HL(object): 

    def __init__(self, reg_lambda=0, epsilon_init=0.12, hidden_layer_size=25, opti_method='TNC', maxiter=500): 
     self.reg_lambda = reg_lambda 
     self.epsilon_init = epsilon_init 
     self.hidden_layer_size = hidden_layer_size 
     self.activation_func = self.sigmoid 
     self.activation_func_prime = self.sigmoid_prime 
     self.method = opti_method 
     self.maxiter = maxiter 

    def sigmoid(self, z): 
     return 1/(1 + np.exp(-z)) 

    def sigmoid_prime(self, z): 
     sig = self.sigmoid(z) 
     return sig * (1 - sig) 

    def sumsqr(self, a): 
     return np.sum(a ** 2) 

    def rand_init(self, l_in, l_out): 
     self.epsilon_init = (math.sqrt(6))/(math.sqrt(l_in + l_out)) 
     return np.random.rand(l_out, l_in + 1) * 2 * self.epsilon_init - self.epsilon_init 

    def pack_thetas(self, t1, t2): 
     return np.concatenate((t1.reshape(-1), t2.reshape(-1))) 

    def unpack_thetas(self, thetas, input_layer_size, hidden_layer_size, num_labels): 
     t1_start = 0 
     t1_end = hidden_layer_size * (input_layer_size + 1) 
     t1 = thetas[t1_start:t1_end].reshape((hidden_layer_size, input_layer_size + 1)) 
     t2 = thetas[t1_end:].reshape((num_labels, hidden_layer_size + 1)) 
     return t1, t2 

    def _forward(self, X, t1, t2): 
     m = X.shape[0] 
     ones = None 
     if len(X.shape) == 1: 
      ones = np.array(1).reshape(1,) 
     else: 
      ones = np.ones(m).reshape(m,1) 

     # Input layer 
     a1 = np.hstack((ones, X)) 

     # Hidden Layer 
     z2 = np.dot(t1, a1.T) 
     a2 = self.activation_func(z2) 
     a2 = np.hstack((ones, a2.T)) 

     # Output layer 
     z3 = np.dot(t2, a2.T) 
     a3 = self.activation_func(z3) 
     return a1, z2, a2, z3, a3 

    def function(self, thetas, input_layer_size, hidden_layer_size, num_labels, X, y, reg_lambda): 
     t1, t2 = self.unpack_thetas(thetas, input_layer_size, hidden_layer_size, num_labels) 

     m = X.shape[0] 
     Y = np.eye(num_labels)[y] 

     _, _, _, _, h = self._forward(X, t1, t2) 
     costPositive = -Y * np.log(h).T 
     costNegative = (1 - Y) * np.log(1 - h).T 
     cost = costPositive - costNegative 
     J = np.sum(cost)/m 

     if reg_lambda != 0: 
      t1f = t1[:, 1:] 
      t2f = t2[:, 1:] 
      reg = (self.reg_lambda/(2 * m)) * (self.sumsqr(t1f) + self.sumsqr(t2f)) 
      J = J + reg 
     return J 

    def function_prime(self, thetas, input_layer_size, hidden_layer_size, num_labels, X, y, reg_lambda): 
     t1, t2 = self.unpack_thetas(thetas, input_layer_size, hidden_layer_size, num_labels) 

     m = X.shape[0] 
     t1f = t1[:, 1:] 
     t2f = t2[:, 1:] 
     Y = np.eye(num_labels)[y] 

     Delta1, Delta2 = 0, 0 
     for i, row in enumerate(X): 
      a1, z2, a2, z3, a3 = self._forward(row, t1, t2) 

      # Backprop 
      d3 = a3 - Y[i, :].T 
      d2 = np.dot(t2f.T, d3) * self.activation_func_prime(z2) 

      Delta2 += np.dot(d3[np.newaxis].T, a2[np.newaxis]) 
      Delta1 += np.dot(d2[np.newaxis].T, a1[np.newaxis]) 

     Theta1_grad = (1/m) * Delta1 
     Theta2_grad = (1/m) * Delta2 

     if reg_lambda != 0: 
      Theta1_grad[:, 1:] = Theta1_grad[:, 1:] + (reg_lambda/m) * t1f 
      Theta2_grad[:, 1:] = Theta2_grad[:, 1:] + (reg_lambda/m) * t2f 

     return self.pack_thetas(Theta1_grad, Theta2_grad) 

    def fit(self, X, y): 
     num_features = X.shape[0] 
     input_layer_size = X.shape[1] 
     num_labels = len(set(y)) 

     theta1_0 = self.rand_init(input_layer_size, self.hidden_layer_size) 
     theta2_0 = self.rand_init(self.hidden_layer_size, num_labels) 
     thetas0 = self.pack_thetas(theta1_0, theta2_0) 

     options = {'maxiter': self.maxiter} 
     _res = optimize.minimize(self.function, thetas0, jac=self.function_prime, method=self.method, 
           args=(input_layer_size, self.hidden_layer_size, num_labels, X, y, 0), options=options) 

     self.t1, self.t2 = self.unpack_thetas(_res.x, input_layer_size, self.hidden_layer_size, num_labels) 

     np.savetxt("weights_t1.txt", self.t1, newline="\n") 
     np.savetxt("weights_t2.txt", self.t2, newline="\n") 

    def predict(self, X): 
     return self.predict_proba(X).argmax(0) 

    def predict_proba(self, X): 
     _, _, _, _, h = self._forward(X, self.t1, self.t2) 
     return h 


################## 
# IR data  # 
################## 
values = np.loadtxt('infrared_data.txt', delimiter=', ', usecols=[0,1,2,3,4]) 

targets = np.loadtxt('infrared_data.txt', delimiter=', ', dtype=(int), usecols=[5]) 

X_train, X_test, y_train, y_test = cross_validation.train_test_split(values, targets, test_size=0.4) 
nn = NN_1HL() 
nn.fit(values, targets) 
print("Accuracy of classification: "+str(accuracy_score(y_test, nn.predict(X_test)))) 

ответ

0

В данное код scipy.optimize.minimize итерационно минимизирует функцию, учитывая ее производную (матрица Якоби). Согласно документации, использование может указывать аргумент callback функции, которая будет вызываться после каждой итерации - это позволит вам измерять производительность, хотя я не уверен, что это позволит вам остановить процесс оптимизации.

Все параметры, которые вы перечислили гиперпараметры, это трудно, чтобы оптимизировать их непосредственно:

Количество нейронов в скрытом слое является дискретным значных параметров, и, таким образом, не оптимизируемых с помощью методов градиента. Более того, это влияет на архитектуру NeuralNet, поэтому вы не можете ее оптимизировать во время обучения сети. Однако вы можете использовать некоторую процедуру более высокого уровня для поиска возможных параметров, таких как полный поиск сетки с перекрестной проверкой (например, посмотрите на GridSearchCV) или другие инструменты для поиска гиперпараметра (hyperopt, spearmint, MOE и т. Д.).

Уровень обучения, по-видимому, не может быть настроен для большинства доступных методов оптимизации. Но, на самом деле, скорость обучения в градиентном спуске - это всего лишь метод Ньютона с «приближенным» гессианством на 1/eta I - диагональная матрица с перевернутыми скоростями обучения по большой диагонали.Таким образом, вы можете попробовать методы на основе hessian с этой эвристикой.

Momentum полностью не связан с регуляризацией. Это метод оптимизации, и, поскольку вы используете scipy для оптимизации, он недоступен для вас.

Смежные вопросы