2016-07-19 3 views
4

Я пытаюсь внедрить adadelta в мою простую прямую нервную сеть , но я думаю, что у меня проблемы с пониманием статьи. http://arxiv.org/pdf/1212.5701v1.pdf
Это небольшая статья, объясняющая/вводя алгоритм adadelta. Только 1 с половиной страниц сосредоточены на формулах.Попытка понять алгоритм adadelta

Начиная от части:

обновление

Алгоритм 1 вычисления ADADELTA в момент времени т


Вопрос 1 часть: '3: Вычислить градиент: GT'

Как я могу рассчитать градиент здесь? ли мой путь правильный:

/* calculating gradient value for neuron what is inside the hidden layer 
gradient = sum of (outcoming connection target's gradient * outcoming connection's weight) * derivative function */ 
double CalculatHiddenGradient() { 
    double sum = 0.0; 
    for (int i = 0; i < OutcomingConnections.size(); i++) { 
     sum += OutcomingConnections[i]->weight * OutcomingConnections[i]->target->gradient; 
    } 
    return (1.0 - output * output) * sum; // tanh's derivative function 
} 

// calculating gradient value for output neurons where we know the desired output value 
double CalculatGradient(double TargetOutput) { 
    return (TargetOutput - output) * (1.0 - output * output); 
} 

Вопрос 2 часть: '5: Compute Обновление: Δxt'

формула (14) говорит следующее:

Δxt = - (RMS [Δx] t-1)/RMS [г] t) *.

является RMS [? X] T-1 вычисления, как следующие:

RMS [? X] трет-1 = SQRT (Е [Δx²] трет-1 + е)

принимая тело из формулы (9)?


Основываясь на том, что я corrently понимаю, я был в состоянии написать этот кусок кода:

class AdaDelta { 
private: 
    vector<double> Eg; // E[g²] 
    vector<double> Ex; // E[∆x²] 
    vector<double> g; // gradient 
    int windowsize; 
    double p; // Decay rate ρ 
    double e; // Constant e, epsilon? 

public: 
    AdaDelta(int WindowSize = 32, double DecayRate = 0.95, double ConstantE = 0.001) { // initalizing variables 
     Eg.reserve(WindowSize + 1); 
     Ex.reserve(WindowSize + 1); 

     Eg.push_back(0.0); // E[g²]t 
     Ex.push_back(0.0); // E[∆x²]t 
     g.push_back(0.0); // (gradient)t 

     windowsize = WindowSize; // common value:? 

     p = DecayRate; // common value:0.95 
     e = ConstantE; // common value:0.001 
    } 

    // Does it return weight update value? 
    double CalculateUpdated(double gradient) { 
     double dx; // ∆xt 
     int t; 

     // for t = 1 : T do %% Loop over # of updates 
     for (t = 1; t < Eg.size(); t++) { 

      // Accumulate Gradient 
      Eg[t] = (p * Eg[t - 1] + (1.0 - p) * (g[t] * g[t])); 

      // Compute Update 
      dx = -(sqrt(Ex[t - 1] + e)/sqrt(Eg[t] + e)) * g[t]; 

      // Accumulate Updates 
      Ex[t] = Ex[t - 1] + (1.0 - p) * (dx * dx); 
     } 

     /* calculate new update 
     =================================== */ 
     t = g.size(); 
     g.push_back(gradient); 

     // Accumulate Gradient 
     Eg.push_back((p * Eg[t - 1] + (1.0 - p) * (g[t] * g[t]))); 

     // Compute Update 
     dx = -(sqrt(Ex[t - 1] + e)/sqrt(Eg[t] + e)) * g[t]; 

     // Accumulate Updates 
     Ex.push_back(Ex[t - 1] + (1.0 - p) * (dx * dx)); 

     // Deleting adadelta update when window has grown bigger than we allow 
     if (g.size() >= windowsize) { 
      Eg[1] = 0.0; 
      Ex[1] = 0.0; 
      Eg.erase(Eg.begin()); 
      Ex.erase(Ex.begin()); 
      g.erase(g.begin()); 

     } 
     return dx; 
    } 
}; 

Вопрос 3
В обратном распространении, обновления веса идет как этот

целевой градиент * выход источника * lear ning rate

но в алгоритме adadelta я не вижу этого действия. Должен ли я смешивать выходной сигнал источника с градиентом цели перед вызовом функции CalculateUpdated() или мне нужно смешать вывод с возвращаемым значением, чтобы получить новое значение веса?


Вопрос 4
Часть того, что заставило меня путать весь путь

3,2. Идея 2: Правильные единицы с приближением Гессиана

Я не совсем понимаю, какую формулу мы обновляем здесь или какие изменения. Где мы применяем приведенную ниже формулу?

формула (13) Δx = (Δx/∂f)/∂x;


Вопрос 5
что делает? X, ∂f, ∂x стоять в формуле (13)?


Спасибо!

+0

Будет также полезно указать топологию вашей сети. Сколько слоев и сколько нейронов на каждом слое? –

+0

Я пойду с простой сетью, предназначенной для решения проблемы xor, поэтому позже один я мог бы понять, как создавать более сложные сети. Один скрытый слой, два входа, два скрытых нейрона и один выход. Входной и скрытый слой с одним нейронным смещением. –

+0

Дэвид Миллер сделал то же самое, поэтому, возможно, вам стоит взглянуть на его [** Учебник **] (https://vimeo.com/19569529) –

ответ

2

Что вам нужно знать об AdaDelta - это общий контекст онлайн-обучения. Online машинное обучение - это то, где вы получаете свои данные по одному (и, следовательно, вам нужно обновлять параметры вашей модели по мере поступления данных), в отличие от batch машинное обучение, в котором вы можете сгенерировать свою модель обучения в машине с доступом ко всему набору данных все сразу.

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

D = {(A_1,b_1), (A_2,b_2), (A_3,b_3), ...} 

где A_k является к-й части обучающих данных и b_k правильного ответа. Как правило, вы хотите, чтобы ваша модель обучения машины (например, классификатор или регрессор, например, нейронные сети или, возможно, линейная модель), чтобы обновить его внутреннего параметр

x = (x_1, x_2, ..., x_n) 

, как он читает в точках данных (a_k, b_k) один в то время как вы хотите, чтобы модель обновляла x в «реальном времени», когда поступают данные. Это в отличие от того, что такое пакетное обучение, когда ваша модель имеет доступ ко всему набору данных D одновременно.

Теперь мы обычно имеем понятие «стоимость» --- в линейной регрессии, функция стоимости, которую мы пытаемся свести к минимуму, - это среднеквадратичная (RMS) разность между прогнозируемым целевым значением и фактическое целевое значение.

Вспоминая определение онлайн линейной регрессии, то есть на основе этапа обновления stochastic gradient descent где параметры х обновляется на основе всех данных, эта модель до сих пор видела:

x_new <- x_old - gradient(RMS[predicted-actual]) 

правил Каких обновлений, как AdaGrad и AdaDelta do - обеспечить «лучший» способ выполнения обновлений - это может означать такие вещи, как уверенность в том, что параметры сходятся к их оптимальному значению быстрее, или в случае AdaDelta, это означает, что параметры x «приближаются» к их оптимальные значения в шагах соответствующего размера с изменением размера шага в зависимости от прошлой работы.

Давайте пройдемся вопросы, один вопрос за один раз:

  • Вопрос 1:

Градиент в более высоких измерениях (т.е. когда х представляет массив) определяется как

gt = (∂f/∂x_1, ∂f/∂x_2, ..., ∂f/∂x_n) (xt) 

где f (x1, x2, ..., x_n) - это функция, которую вы пытаетесь свести к минимуму; в большинстве случаев это функция стоимости в одном примере как функция x, параметры модели. Другими словами: возьмите производные от функции стоимости и затем оцените ее при текущих параметрах xt.

  • Вопрос 2:

Основываясь на моем понимании, СУР дельта-х определяется как

RMS[\Delta x]_{t-1} = \sqrt{ E[\Delta x^2]_{t-1} + \epsilon }, 

где

E[\Delta x^2]_t = \rho E[\Delta x^2]_{t-1} + (1-\rho) g^2_T, 

инициализируется

E[\Delta x^2]_0 = 0. 
  • Вопрос 3:

AdaDelta является чисто правило обновления. Общая структура является чем-то вроде этого:

(new_weights @ T) := (old_weights @ T-1) - [adaptive_learning_rate] * (gradient @ T) 

где

adaptive_learning_rate := -(RMS[Delta-x] @ T-1)/(RMS[gradient] @ T) 

потому что точка AdaDelta, чтобы сделать скорость обучения в динамическое значение, а не заставляя нас выбирать произвольное значение для него в начало.

  • Вопрос 4:

Идея "исправляющие единицы с Гессе приближения" происходит от физической интуиции, в каком-то смысле; то есть, если вы даете каждой переменной какую-то единицу (длина/метры, время/секунды, энергия/джоуль и т. д.), то у гессиана есть соответствующие единицы, чтобы исправить срок обновления, чтобы выработать анализ размеров.

  • Вопрос 5:

Дельта-й разница в й после обновления. Поэтому, если x_i является вашим параметром перед обновлением, а x_ {i + 1} является вашим параметром после обновления, тогда Delta-x является (x_ {i + 1} - x_i).

(∂f/∂x) - это производная от функции, которую вы пытаетесь свести к минимуму (обычно в ML, f - функция стоимости).

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