初探神经网络(深度学习入门)

参考资料:吴恩达机器学习视频、吴恩达深度学习视频及作业、百度百科。

一、神经网络概述

1.什么是神经网络?

    这里所说的神经网络并不是生物学上的神经网络,这里特指的是机器学习中的人工神经网络,它是一种模仿生物神经网络的结构和功能的数学模型或计算模型。它是指按照一定的规则将多个神经元连接起来的网络。

2.什么是神经元?

    神经网络是一种运算模型,由大量的节点(或称神经元)之间相互联接构成。每个节点代表一种特定的输出函数,称为激励函数。

 

                                             

                                                                                          图1.1 神经元

 

二、最简单的神经网络——逻辑回归

1.搭建简单的神经网络的步骤

    1.1  输入模型结构

    1.2  初始化模型参数

    1.3  循环:①计算当前损失(正向传播)→②计算当前梯度(反向传播)→③更新参数

2.逻辑回归的公式定义

     逻辑回归公式: 其中 , (我们暂定为这个激活函数)

     损失函数:

    代价函数:     

    损失函数与代价函数的区别在于,损失函数只适用于单个训练样本,而代价函数是参数的总代价。 

3.正向传播与反向传播(单样本)

 输入wx1   w2   x2    b →   →    → L(a,y)

                                    

                                                                                        图2.1逻辑回归 

3.1正向传播

 

3.2反向传播

4.正向传播和反向传播(m个样本)

 4.1正向传播

 4.2反向传播:

4.3正向传播与反向传播的代码实现

def propagate(w, b, X, Y):
    """
    实现前向和后向传播的成本函数及其梯度。
    参数:
        w  - 权重,大小不等的数组(num_px * num_px * 3,1)
        b  - 偏差,一个标量
        X  - 矩阵类型为(num_px * num_px * 3,训练数量)
        Y  - 真正的“标签”矢量

    返回:
        cost- 逻辑回归的负对数似然成本
        dw  - 相对于w的损失梯度,因此与w相同的形状
        db  - 相对于b的损失梯度,因此与b的形状相同
    """
    m = X.shape[1]

    # 正向传播
    A = sigmoid(np.dot(w.T, X) + b) 
    cost= (-1/m) * np.sum(Y * np.log(A) + (1-Y)*(np.log(1 - A))) 

    # 反向传播
    dw = (1 / m) * np.dot(X, (A - Y).T) 
    db = (1 / m) * np.sum(A - Y)  # 请参考视频中的偏导公式。

    # 使用断言确保我的数据是正确的
    assert (dw.shape == w.shape)
    assert (db.dtype == float)
    cost = np.squeeze(cost)
    assert (cost.shape == ())

    # 创建一个字典,把dw和db保存起来。
    grads = {
                "dw": dw,
                "db": db
             }
    return (grads, cost)

三、浅层神经网络

1.浅层神经网络概述

    我们这里介绍使用一个隐含层和一个输出层的二层神经网络(当我们在计算网络的层数时,我们是不计算输入层的)。其实两层的神经网络就是把两个单个神经网络有机的结合起来,就搭建好了。再多层的神经网络也可依次类推。搭建的神经网络如图所示:

                                   

                                                                  图3.1两层神经网络 

2.权重的初始化

    当我们训练神经网络的时候,初试化W【l】和b【l】是非常重要的。

    首先,我们必须要明确W【l】和b【l】的维度,在神经网络中,W的维度是(下一层的神经元个数,前一层的神经元个数),b的维度是(下一层的神经元个数,1)。在如图3.1所示的神经网络中,W【l】和b【l】的维度如下所示:W【1】=(4,2),W【2】=(1,4),b[1]=(4,1),b[1]=(1,1)

    其次,W【l】和b【l】的初始化中,b[l]可以初始化为0,但是W[l]不能初始化为0。因为如果我们把权重或者参数都初始化为0的话,那么梯度下降将无法起作用。 

  初始化代码如下:

def initialize_parameters(n_x, n_h, n_y):
    """
    参数:
        n_x - 输入层节点的数量
        n_h - 隐藏层节点的数量
        n_y - 输出层节点的数量
    返回:
        parameters - 包含参数的字典:
            W1 - 权重矩阵,维度为(n_h,n_x)
            b1 - 偏向量,维度为(n_h,1)
            W2 - 权重矩阵,维度为(n_y,n_h)
            b2 - 偏向量,维度为(n_y,1)
    """
    np.random.seed(2) 
    W1 = np.random.randn(n_h, n_x) * 0.01
    b1 = np.zeros(shape=(n_h, 1))
    W2 = np.random.randn(n_y, n_h) * 0.01
    b2 = np.zeros(shape=(n_y, 1))

    # 使用断言确保我的数据格式是正确的
    assert (W1.shape == (n_h, n_x))
    assert (b1.shape == (n_h, 1))
    assert (W2.shape == (n_y, n_h))
    assert (b2.shape == (n_y, 1))

    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}

    return parameters

3.几种常见的激活函数介绍

3.1 激活函数有许多中,使用哪种激活函数取决于具体的情况,比如是隐函数还是输出层,是二分类问题还是其他问题。

    sigmoid函数:  

    导数:

                                               

                                                                                       图3.2 sigmoid函数

    tanh函数: 

    导数::

                                                        

                                                                               图3.3 tanh函数      

    ReLU函数: 

     导数:

    Leaky ReLU函数: (这里可以不是0.01) 

    导数: 

                              

                                                                图3.4 ReLU函数和Leaky ReLU函数 

3.2不同激活函数的结论

    sigmoid激活函数:除了输出层是一个二分类问题基本不会用它。

    tanh激活函数:tanh是非常优秀的,几乎适合所有场合。

    ReLu激活函数:最常用的默认函数,如果不确定用哪个激活函数,就使用ReLu或者Leaky ReLu。

4.正向传播和反向传播(m个样本)

(注明,这里输出层使用的是sigmoid函数)

4.1正向传播

4.2正向传播代码

def forward_propagation(X, parameters):
    """
    参数:
         X - 维度为(n_x,m)的输入数据。
         parameters - 初始化函数(initialize_parameters)的输出
    返回:
         A2 - 使用sigmoid()函数计算的第二次激活后的数值
         cache - 包含“Z1”,“A1”,“Z2”和“A2”的字典类型变量
     """
    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]
    # 前向传播计算A2
    Z1 = np.dot(W1, X) + b1
    A1 = np.tanh(Z1)
    Z2 = np.dot(W2, A1) + b2
    A2 = sigmoid(Z2)
    # 使用断言确保我的数据格式是正确的
    assert (A2.shape == (1, X.shape[1]))
    cache = {"Z1": Z1,
             "A1": A1,
             "Z2": Z2,
             "A2": A2}

    return (A2, cache)

 4.3反向传播

4.4反向传播代码实现:

def backward_propagation(parameters, cache, X, Y):
    """
    搭建反向传播函数。
    参数:
     parameters - 包含我们的参数的一个字典类型的变量。
     cache - 包含“Z1”,“A1”,“Z2”和“A2”的字典类型的变量。
     X - 输入数据,维度为(2,数量)
     Y - “True”标签,维度为(1,数量)
    返回:
     grads - 包含W和b的导数一个字典类型的变量。
    """
    m = X.shape[1]

    W1 = parameters["W1"]
    W2 = parameters["W2"]

    A1 = cache["A1"]
    A2 = cache["A2"]

    dZ2 = A2 - Y
    dW2 = (1 / m) * np.dot(dZ2, A1.T)
    db2 = (1 / m) * np.sum(dZ2, axis=1, keepdims=True)
    dZ1 = np.multiply(np.dot(W2.T, dZ2), 1 - np.power(A1, 2))
    dW1 = (1 / m) * np.dot(dZ1, X.T)
    db1 = (1 / m) * np.sum(dZ1, axis=1, keepdims=True)
    grads = {"dW1": dW1,
             "db1": db1,
             "dW2": dW2,
             "db2": db2}

    return grads

 4.5更新参数

 4.6更新参数代码实现:

def update_parameters(parameters, grads, learning_rate=1.2):
    """
    更新参数
    参数:
     parameters - 包含参数的字典类型的变量。
     grads - 包含导数值的字典类型的变量。
     learning_rate - 学习速率
    返回:
     parameters - 包含更新参数的字典类型的变量。
    """
    W1, W2 = parameters["W1"], parameters["W2"]
    b1, b2 = parameters["b1"], parameters["b2"]

    dW1, dW2 = grads["dW1"], grads["dW2"]
    db1, db2 = grads["db1"], grads["db2"]

    W1 = W1 - learning_rate * dW1
    b1 = b1 - learning_rate * db1
    W2 = W2 - learning_rate * dW2
    b2 = b2 - learning_rate * db2

    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}

    return parameters

 

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值