• 机器学习笔记(3): 神经网络初步


    神经网络应该由若干神经元组成。

    前面的每一个神经元都会给到一个参数,将传递的所有参数看作一个向量 x,那么此神经元的净输入为:

    z=xω+b

    其中 ω 称为权重向量

    这里认为 x向量,而 ω向量。

    神经元还有一个激活函数 f()

    a=f(z)

    称为函数的活性值

    一般来说,我们使用 Logistic 函数,即 σ(x)=11+exp(x) 作为激活函数。

    激活函数

    激活函数有很多很多种,一般来说要满足以下几点:

    1. 连续且可导的非线性函数。
    2. 函数本身和其导数要尽可能简单。
    3. 值域要在一个合适的区间内

    这里列举几种常见的函数。

    Sigmoid 型

    指一类两端饱和的 S 型曲线。

    饱和
    limxf(x)=0 称为左饱和,limxf(x)=0 称为右饱和。
    同时满足则称为两端饱和。

    常见的 Sigmoid 型函数有 LogisticTanh

    • Logistic 函数

    σ(x)=11+exp(x)

    其导数:

    σ(x)=exp(x)(1+exp(x))2=σ(x)(1σ(x))

    • Tanh 函数

    tanh(x)=exp(x)exp(x)exp(x)+exp(x)

    其可以看作缩放平移后的 σ,因为:

    tanh(x)=2σ(2x)1

    自然其导数:

    tanh(x)=4σ(2x)(1σ(2x))=4(exp(x)+exp(x))2

    实际上我们可以通过近似的方法去拟合这个函数,毕竟 ex 也不是那么好算的。

    • Hard-LogisticHard-Tanh 函数

    hardσ(x)={1x>2x4+12x[2,2]0x<2

    或者利用 min,max 简化:

    hardσ(x)=max(min(x4+12,1),0)

    类似的:

    hardtanh(x)=max(min(x,1),1)

    ReLU

    也就是 Rectified Linear Unit,线性修正单元,定义为:

    ReLU(x)={xx00x<0

    也就是 ReLU(x)=max(x,0)

    当然,因为可能出现 死亡 ReLU 问题,所以一般有如下变形:

    PReLU(x)={xx0γxx<0

    如果 γ=0 则退化为 ReLU 函数,如果 γ<1,那么也可以写为:

    LeakyLU(x)=max(x,γx)

    另一个变形是:

    ELU(x)={xx0γ(exp(x)1)x<0

    还有一个则是:

    Softplus(x)=log(1+exp(x))

    Swish 函数

    这是一种自控门函数:

    swish(x)=xσ(βx)

    网络结构

    网络结构分三种:

    • 前馈网络
    • 记忆网络
    • 图网络

    这里先讲述前馈网络

    这是一个前馈网络的示意图,其中第一层为输入层,最后一层为输出层。

    而中间的那些层称为隐藏层。隐藏层可以有多个,而这里只画出了一个。

    每一层有若干神经元,而两层间的神经元两两相连。

    现在我们定义一些符号:

    • L 表示总层数,注意这里输入层为第 0 层,不计入其中;输出层为第 L 层。
    • Ml 表示第 l 层的神经元数量。
    • fl() 表示第 l 层的激活函数。
    • W(l)RMl×Ml1 表示第 l1 层到第 l 层的权重矩阵(若干权重向量组成)。
    • b(l)RMl 表示第 l 层的偏置。
    • z(l)RMl 表示净输入。
    • a(l)RMl 表示输出。

    对于一组数据 (x,y),前馈神经网络通过如下算法进行传播:

    z(l)=W(l)a(l1)+b(l)a(l)=fl(z(l))

    参数学习

    参数学习可能略有点复杂,证明过程我懒得写成 LATEX,这里就省略了。

    我们利用反向传播算法进行学习,其步骤如下:

    • 选取一个数据,计算 a(l)z(l)
    • 反向传播每一层的误差 δ(l)
    • 计算每一层的偏导数,更新参数

    显然的是 δ(L)=a(L)y

    经过一番神秘的推导,我们可以得到:

    δ(l)=fl(z(l))((W(l+1))Tδ(l+1))RMl

    其中 表示元素一一相乘。

    而计算偏导数的公式也不难:

    W(l)R(W)=δ(l)(a(l1))Tb(l)R(W)=δ(l)

    也就是参数更新方式为:

    W(l)W(l)α(δ(l)(a(l1))T+λW(l))b(l)b(l)αδ(l)

    但是值得注意的是,一般我们都会将 W(l) 的第一列作为 b(l),也就是不分开,所以在代码实现上要好生注意!

    这是吴恩达机器学习 ex4 的部分代码:

    function [J grad] = nnCostFunction(nn_params, ...
                                       input_layer_size, ...
                                       hidden_layer_size, ...
                                       num_labels, ...
                                       X, y, lambda)
    
    % Theta1 25 x 401
    % Theta2 10 x 26
    
    Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ...
                     hidden_layer_size, (input_layer_size + 1));
    
    Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ...
                     num_labels, (hidden_layer_size + 1));
                     
    temp1 = Theta1;
    temp2 = Theta2;
    temp1(:, 1) = 0;
    temp2(:, 1) = 0;
    
    m = size(X, 1);
             
    J = 0;
    Theta1_grad = zeros(size(Theta1));
    Theta2_grad = zeros(size(Theta2));
    
    % forward propagation
    A2 = sigmoid([ones(m, 1) X] * Theta1'); % m x 25
    A3 = sigmoid([ones(m, 1) A2] * Theta2'); % m x 10
    
    % caculate cost
    Y = zeros(m, num_labels);
    for i = 1:m
    	Y(i, y(i)) = 1;
    end
    J -= sum(sum( log(A3) .* Y + log(1 - A3) .* (1 - Y) ));
    J += lambda / 2 * (sum(sum(temp1 .* temp1)) + sum(sum(temp2 .* temp2)));
    J /= m;
    
    % Back Propagation
    
    D1 = zeros(size(Theta1));
    D2 = zeros(size(Theta2));
    
    for i = 1:m
    	a1 = X(i, :); % 1 x 400
    	a2 = A2(i, :); % 1 x 25
    	a3 = A3(i, :); % 1 x 10
    	y = Y(i, :); % 1 x 10
    	d3 = (a3 - y)'; % 10 x 1
    	d2 = (Theta2' * d3) .* [1 a2]' .* (1 - [1 a2])'; % 26 x 1
    	d2 = d2(2:end) ; % 25 x 1
    	
    	D1 += d2 * [1 a1];
    	D2 += d3 * [1 a2];
    end
    
    Theta1_grad = (D1 + lambda * temp1) / m;
    Theta2_grad = (D2 + lambda * temp2) / m;
    
    % Unroll gradients
    grad = [Theta1_grad(:) ; Theta2_grad(:)];
    
    end
    
    
  • 相关阅读:
    R语言计算代码的运行时间:使用tictoc包计算代码的运行时间长短、将toc的结果赋值值变量、可以获取详细信息(开始时间、结束时间、tic内容等)
    神经网络数学建模怎么算,神经网络数学建模论文
    自动控制原理-2 控制系统的数学模型
    .NET 6应用程序适配国产银河麒麟V10系统随记
    将近 5 万字讲解 Python Django 框架详细知识点(更新中)
    深度学习-卷积神经网络-AlexNET
    “鼓浪屿元宇宙”,能否成为中国文旅产业的“升级样本”
    记参加Microsoft Ignite 大会和北京CSDN创作者之夜
    Pandas数据分析17——pandas数据清洗(缺失值、重复值处理)
    蓝桥等考Python组别十三级004
  • 原文地址:https://www.cnblogs.com/jeefy/p/18238472