c – 尝试理解adadelta算法

我正在尝试将adadelta应用到我的简单前馈神经网络中

但我觉得我在理解这篇文章时遇到了一些麻烦.

http://arxiv.org/pdf/1212.5701v1.pdf

这是一篇解释/介绍adadelta算法的小文章.

只有1.5页专注于公式.

从部分开始:

Algorithm 1 Computing ADADELTA update at time t

问题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:计算更新:Δxt’

公式(14)
说如下:

∆xt = -( RMS[∆x]t−1) / RMS[g]t) * gt;

是RMS [Δx] t-1计算如下:

RMS[∆x]t−1 = sqrt( E[∆x²]t-1 + e )

从公式(9)中取出身体?

根据我的理解,我能够编写这段代码:

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
在反向传播中,更新权重就像这样

target’s gradient * source’s output * learning rate

但在adadelta算法中,我没有看到这个动作.
在调用之前,我应该将源的输出与目标的渐变混合
CalculateUpdated()函数还是应该将输出与返回值混合以获得新的权重值?

问题4
让我困惑的一部分

3.2. Idea 2: Correct Units with Hessian Approximation

我不太明白我们在这里更新的公式部分或者有哪些变化.
我们在哪里应用下面的公式?

公式(13)
Δx=(Δx/∂f)/∂x;

问题5
Δx,∂f,∂x在公式(13)中代表什么?

谢谢!

最佳答案 您需要了解的关于AdaDelta的事情是在线机器学习的一般背景.在线机器学习是一次一个地获取数据的地方(因此必须在数据进入时更新模型的参数),而不是批处理机器学习,您可以通过批处理机器学习生成机器学习模型.整个数据集一次完成.

基本上,您有一组数据点以及您尝试在表单中预测的目标

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

其中A_k是第k条训练数据,b_k是正确答案.您通常需要您的机器学习模型(例如分类器或回归器,例如神经网络或可能是线性模型)来更新其内部参数

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

因为它一次一个地读入数据点(A_k,b_k),即您希望模型在数据进入时“实时”更新x.这与批量学习相反,您的模型可以访问整个数据集D一次全部.

现在,我们通常有一个“成本”的概念—在线性回归中,我们试图最小化的成本函数是预测目标值和实际目标值之间差异的均方根(RMS).

回顾在线线性回归的定义,您有一个基于stochastic gradient descent的更新步骤,其中参数x基于模型到目前为止看到的所有数据得到更新:

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

像AdaGrad和AdaDelta这样的更新规则是提供一种“更好”的方式来执行更新 – 这可能意味着确保参数更快地收敛到最佳值,或者在AdaDelta的情况下,这意味着参数x以适当大小的步长“更接近”它们的最佳值,步长根据过去的性能而变化.

让我们一起回答你的问题,一个问题:

>问题1:

更高维度的梯度(即当x由数组表示时)定义为

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

其中f(x1,x2,…,x_n)是你试图最小化的函数;在大多数情况下,它是单个示例的成本函数,作为x的函数,即模型参数.换句话说:获取成本函数的导数,然后在当前参数xt处对其进行评估.

>问题2:

根据我的理解,delta-x的RMS定义为

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:

在某种意义上,“用Hessian近似校正单位”背后的想法来自物理直觉;也就是说,如果给每个变量赋予某种单位(长度/米,时间/秒,能量/焦耳等),那么Hessian就有适当的单位来纠正更新项,以便进行维度分析.

>问题5:

Delta-x是更新后x的差异.因此,如果更新前x_i是您的参数,更新后x_ {i 1}是您的参数,则Delta-x为(x_ {i 1} – x_i).

(∂f/∂x)是您尝试最小化的函数的导数(通常在ML中,f是成本函数).

点赞