FunnyWii
FunnyWii
Published on 2022-11-03 / 25 Visits
0
0

深度学习 - 深度前馈网络 Deep Feedforward Networks

在机器学习中,如果想对对非线性函数进行建模,深度前馈网络能够实现非线性函数的建模。

在深度学习中,使用一个简单函数的深度链来学习输入数据。

线性函数的输入函数: \hat{y} = \theta^Tx

非线性函数的输入函数:\hat{y} = f(\phi(x);\theta)

其中,\phi(x) = h^{(m)}(...(h^{(2)}(h^{(1)}(x))))

\phi 是输入数据 x 的学习表征,h(x) 是激活函数。

深度前馈网络

在深度前馈网络的每一层(Layer),使用一个简单的线性函数 W^{l} x^{(l-1)} 和后面的激活函数 h(x)来表示网络结构。

网络的整体结构:

\hat{y} = f(W^{(M)}h(...(W^{(2)}h((W^{(1)}h(x))))

在每层中:

z^{(l)} = W^{l} x^{l-1}
x^{l} = h(z^{(l)})
x^{(0)} = x

每一层都会使用一个简单的线性函数及一个权重矩阵W

权重矩阵W.png

隐藏单元的激活函数 Activation Functions

h(.) 是激活函数

ReLU

x_j = h(z_j) = max(0,z_j)

ReLU.png

Figure 1 ReLU

LReLU

x_j = h(z_j) = \begin{cases}az_i\quad \text {if \textcolor{orange}{$z_i<0$}} \\ z_i\quad \text{if \textcolor{orange}{$z_i>=0$}} \end{cases}

Leaky ReLU.png

Figure 2 Leaky ReLU

Sigmoid

x_j = h(z_j) = \frac{1}{1+e^{-z_j}}

Sigmoid.png

Figure 3 Sigmoid

Tangent

x_j = h(z_j) =tanh(-z_j)

Tangent.png

Figure 4 Tangent

输出单元

回归问题,是线性输出

\hat{y}_j =f(z_j^{(M)}) = w_j^{(M)T}x^{(M-1)}

分类(class>2)问题,是SOFTMAX输出,softmax的输出用来预测各个分类的可能性

\hat{y}_j=P(Y=j|x^{(M-1)} ; w_j^{(M)}) = f(z_j^{(M)}) = \frac{exp(w_j^{(M)T} x^{(M-1)})}{\Sigma^K_{k=1}exp(w_k^{(M)T} x^{(M-1)})}

深度前馈网络是一个具有非线性激活函数线性函数链,有一个专门用于任务的输出层,即回归或分类。

深度前馈网络结构.png

Figure 5 深度前馈网络结构

反向传播 Back Propagation

反向传播又被称为BP,允许来自cost function的信息通过网络向后流动,以便计算梯度(Gradient)。

SGD

用下面的公式不断更新w的值:

w_{ji}^{(l)} \leftarrow w_{ji}^{(l)} -\epsilon \frac{\alpha L_n}{\alpha w_{ji}^{(l)}}

这里的L_n是一个sample的Loss

Back Propagation.png

Figure 6 Back Propagation

对于深度前馈网络,\delta_j^{(l)}x_i^{(l-1)} 可以被替换为 \frac{\partial L_n}{\partial w_{ji}^{(l)}}

推导过程如下:

首先回想起在每个单元,前馈输出 z^{(l)} = W^{(l)}x^{(l-1)}

根据链式法则,

\frac{\partial L_n}{\partial w_{ji}^{(l)}} = \frac{\partial L_n}{\partial z_j^{(l)}} \frac{\partial z_j^{(l)}}{\partial w_{ji}^{(l)}}
\frac{\partial L_n}{\partial z_j^{(l)}} = \textcolor{default}{\delta_j^{(l)}}
\frac{\partial z_j^{(l)}}{\partial w_{ji}^{(l)}} = x_i^{(l-1)}

由上面两个公式可以得到 \frac{\partial L_n}{\partial w_{ji}^{(l)}} = \delta_j^{(l)} x_i^{(l-1)}

根据上面的公式,SGD可以更新:

w_{ji}^{(l)} \leftarrow w_{ji}^{(l)} -\epsilon \delta_j^{(l)}x_i^{(l-1)}

现在只要求出\delta_j^{(l)} 就可以得到BP的完整表达式。

\textcolor{default}{\delta_j^{(l)}} = \frac{\partial L_n}{\partial z_j^{(l)}}

因此,

\textcolor{default}{\delta_j^{(l-1)}} = \frac{\partial L_n}{\partial z_j^{(l-1)}} = \Sigma_k \frac{\partial L_n}{\partial z_k^{(l)}} \frac{\partial z_k^{(l)}}{\partial z_j^{(l-1)}} = \Sigma_k \delta_k^{(l)}\frac{\partial z_k^{(l)}}{\partial z_j^{(l-1)}}

由于

z_k^{(l)}=\Sigma_j w_{kj}^{(l-1)} x_j^{(l-1)} 且 x_j^{(l-1)} = h(z_j^{(l-1)})

因此

\frac{\partial z_k^{(l)}}{z_j^{(l-1)}} =\frac{\partial z_k^{(l)}}{\partial x_j^{(l-1)}} \frac{\partial x_j^{(l-1)}}{\partial z_j^{(l-1)}} = w_{kj}^{(l)} h'(z_j^{(l-1)})

w_{kj}^{(l)} h'(z_j^{(l-1)})可以替换原本公式中的 \frac{\partial z_k^{(l)}}{\partial z_j^{(l-1)}}:

\delta_j^{(l-1)} = \Sigma_k w_{kj}^{(l)} \delta_k^{(l)}h'(z_j^{(l-1)})

因此

\delta_j^{(l)} = \Sigma_k w_{kj}^{(l+1)} \delta_k^{(l+1)}h'(z_j^{(l)})

反向传播算法

  1. 正向传播,估计 \forall l

    z_k^{(l)} = w_j^{(l)T}x_i^{(l-1)}
    x_j^{(l)} = h(z_j^{(l)})
  2. 初始化\delta^{(M)}

    \delta^{(M)} = \frac{\partial L_n}{\partial y_j}f'(z_j^{(M)})

    也就是 \hat{y}-y

  3. 反向传播

    每层都计算一次

\delta_j^{(l-1)} = \Sigma_k w_{kj}^{(l)} \delta_k^{(l)}h'(z_j^{(l-1)})
  1. 梯度

    frac{\partial L_n}{\partial w_{ji}^{(l)}} = \delta_j^{(l)}x_i^{(l-1)}

    假设 \frac{\partial L_n}{\partial w_{ji}^{(l)}}G 的话,接下来在每层, w会更新:

    w^{(l)} = w^{(l)} - \epsilon G
maxIter = m;
for epoch = 1:maxEpochs % loop over number of epochs
    loss = [];
    for iter = 1:m % loop over all data samples
        %% 1. forward propagation
        net(1).x = x(r(iter)); % extract random input
        for l = 2:M % loop over each layer
            net(l).z = net(l).W*[1; net(l-1).x]; % weight & bias
            net(l).x = max(net(l).z,0); % ReLU activation
        end
        net(M).yhat = net(M).z; % output activation
        %% 2. initialise delta
        net(M).delta = (net(M).yhat-y(r(iter)));
        %% 3. backpropagation through all network layers
        for l = M:-1:3
            net(l-1).delta = net(l).W(:,2:end)'*net(l).delta.*(1.*(net(l-1).z>0));
        end
        %% 4. define loss function gradient
        for l = 2:1:M
            net(l).grad = [net(l).delta net(l).delta*net(l-1).x']; % additional layers
        end
        %% update parameters using SGD
        for l = 2:M
            G = net(l).grad; % error gradient matrix
            net(l).W = net(l).W - epsilon.*G; % SGD update rule
        end
        %% plot results: evaluate and plot loss
        for i = 1:m % forward propagate all data
            net(1).x = x(i); % extract data input sample
            for l = 2:M % loop over network layers
                net(l).z=net(l).W*[1;net(l-1).x]; % weight and bias
                net(l).x=max(net(l).z,0); % ReLU activation
            end
            net(M).yhat=net(M).z; % output
            Yhat(i) = net(M).yhat; % store output
        end
        loss(iter) = sum((Yhat - y).^2); % evaluate loss
        figure(101);subplot(1,2,1); cla; plot(loss); xlabel('Iteration'); ylabel('Loss');
        title(['(a) Loss (Epoch: ' num2str(epoch) ')']); xlim([0 maxIter]);
        subplot(1,2,2); cla; plot(x,y,'.'); hold on; plot(x,Yhat);
        xlabel('x'); ylabel('y'); title('(b) Model Fit'); drawnow;
    end
end

Comment