• 深度学习基础--神经网络(2)



    本文为学习笔记整理

    参考书籍:《深度学习入门 : 基于Python的理论与实现 》/ (日) 斋藤康毅著 ; 陆宇杰译. – 北京 : 人民邮电出版社, 2018.7(2019.5重印)、

    文章中带编号的图片(如:图3-14)均来自书籍内容。

    神经网络的内积

    使用NumPy矩阵实现神经网络需要注意输入值 x x x和权重 w w w的维数需要对应,其中:

    x x x:存储输入信号的一维数组(向量)

    w w w:存储权重参数的多维数组(矩阵)
    在这里插入图片描述

    3层神经网络的实现

    在这里插入图片描述

    输入到输出的前向传播

    在这里插入图片描述

    联系激活函数的内容:

    激活函数:
    a = b + w 1 x 1 + w 2 x 2 (3.4) a = b + w_1x_1 + w_2x_2 \tag{3.4} a=b+w1x1+w2x2(3.4)

    y = h ( a ) (3.5) y=h(a) \tag{3.5} y=h(a)(3.5)

    第一层的神经元 a 1 ( 1 ) a_1^{(1)} a1(1)
    a 1 ( 1 ) = w 11 ( 1 ) x 1 + w 12 ( 1 ) x 2 + b 1 ( 1 ) (3.8) a_1^{(1)}=w_{11}^{(1)}x_1+w_{12}^{(1)}x_2+b_1^{(1)} \tag{3.8} a1(1)=w11(1)x1+w12(1)x2+b1(1)(3.8)
    使用矩阵的乘法运算,将第一层的加权和表示成:
    A ( 1 ) = X W ( 1 ) + B ( 1 ) (3.9) A^{(1)}=XW^{(1)}+B^{(1)} \tag{3.9} A(1)=XW(1)+B(1)(3.9)
    A ( 1 ) = ( a 1 ( 1 ) , a 2 ( 1 ) , a 3 ( 1 ) ) A^{(1)}=(a_1^{(1)},a_2^{(1)},a_3^{(1)}) A(1)=(a1(1),a2(1),a3(1))

    X = ( x 1 , x 2 ) X=(x_1,x_2) X=(x1,x2)

    B ( 1 ) = ( b 1 ( 1 ) , b 2 ( 1 ) , b 3 ( 1 ) ) B^{(1)}=(b_1^{(1)},b_2^{(1)},b_3^{(1)}) B(1)=(b1(1),b2(1),b3(1))

    W ( 1 ) = [ w 11 ( 1 ) w 21 ( 1 ) w 31 ( 1 ) w 12 ( 1 ) w 22 ( 1 ) w 32 ( 1 ) ] W^{(1)} = \left[ {

    w11(1)w21(1)w31(1)w12(1)w22(1)w32(1)" role="presentation">w11(1)w21(1)w31(1)w12(1)w22(1)w32(1)
    } \right] W(1)=[w11(1)w12(1)w21(1)w22(1)w31(1)w32(1)]
    其实就是线型代数中方程组的矩阵表示
    在这里插入图片描述

    代码实现3层神经网络:

    import numpy as np
    
    
    def sigmoid_function(x):
        """sigmoid激活函数"""
        return 1 / (1 + np.exp(-x))
    
    
    def identity_function(x):
        """恒等函数"""
        return x
    
    
    # 输入信号,x1 = 1.0, x2 = 0.5
    X = np.array([1.0, 0.5])
    
    """第一层的前向传播"""
    # 第一层的权重参数W1
    W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
    # 第一层的偏置参数B1
    B1 = np.array([0.1, 0.2, 0.3])
    # 计算a
    A1 = np.dot(X, W1) + B1
    # 激活函数
    Z1 = sigmoid_function(A1)
    
    """第二层的前向传播"""
    W2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
    B2 = np.array([0.1, 0.2])
    A2 = np.dot(Z1, W2) + B2
    Z2 = sigmoid_function(A2)
    
    """第三层的前向传播,输出层"""
    W3 = np.array([[0.1, 0.3], [0.2, 0.4]])
    B3 = np.array([0.1, 0.2])
    A3 = np.dot(Z2, W3) + B3
    Z3 = identity_function(A3)  # 输出层所用的激活函数,此处为恒等函数
    
    print(Z3)  # [0.31682708 0.69627909]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    神经网络比较标准的代码格式,由书中作者提供:

    import numpy as np
    
    
    def sigmoid_function(x):
        """sigmoid激活函数"""
        return 1 / (1 + np.exp(-x))
    
    
    def identity_function(x):
        """恒等函数"""
        return x
    
    
    def init_network():
        """进行权重和偏置的初始化"""
        network = {}  # 创建一个network字典,保存了每一层所需的权重参数和偏置参数
        """字典赋值,权重和偏置赋值"""
        network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
        network['b1'] = np.array([0.1, 0.2, 0.3])
        network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
        network['b2'] = np.array([0.1, 0.2])
        network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])
        network['b3'] = np.array([0.1, 0.2])
        return network
    
    
    def forward(network, x):
        """前向传播,从输入到输出的传递"""
        W1, W2, W3 = network['W1'], network['W2'], network['W3']
        b1, b2, b3 = network['b1'], network['b2'], network['b3']
        a1 = np.dot(x, W1) + b1
        z1 = sigmoid_function(a1)
        a2 = np.dot(z1, W2) + b2
        z2 = sigmoid_function(a2)
        a3 = np.dot(z2, W3) + b3
        y = identity_function(a3)  # 输出层的激活函数选择了恒等函数
        return y
    
    
    network = init_network()
    x = np.array([1.0, 0.5])
    y = forward(network, x)
    print(y)  # [0.31682708 0.69627909]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    输出层的设计

    机器学习的问题大致分为两类:

    1. 分类问题,数据属于哪一个类别的问题,一般使用softmax函数
    2. 回归问题,根据某个输入预测一个连续的数值的问题,一般使用恒等函数

    恒等函数和softmax函数

    恒等函数:输入信号会原封不动地被输出,主要用于回归问题

    softmax函数:
    y k = e x p ( a k ) ∑ i = 1 n e x p ( a i ) (3.10) y_k=\frac{exp(a_k)}{\sum_{i=1}^nexp(a_i)} \tag{3.10} yk=i=1nexp(ai)exp(ak)(3.10)
    e x p ( x ) exp(x) exp(x)= e x e^x ex

    y k y_k yk: 第k个神经元的输出 y k y_k yk

    softmax函数的分子是输入信号 a k a_k ak的指数函数,分母是所有输入信号的指数函数的和。

    在这里插入图片描述

    softmax函数的代码实现:

    import numpy as np
    
    
    def softmax_function(x):
        return np.exp(x) / np.sum(np.exp(x))
    
    
    a = np.array([0.3, 2.9, 4.0])
    y = softmax_function(a)
    print(y)  # [0.01821127 0.24519181 0.73659691]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    softmax函数的实现中要进行指数函数的运算,但是指数函数的值很容易变得非常大,要注意溢出问题

    改进函数:

    在这里插入图片描述

    改进函数代码实现:

    import numpy as np
    
    
    def softmax(x):
        """防止溢出的方法"""
        c = np.max(x)
        return np.exp(x - c) / np.sum(np.exp(x - c))
    
    
    a = np.array([1010, 1000, 990])
    y = softmax(a)
    print(y)  # [9.99954600e-01 4.53978686e-05 2.06106005e-09]
    print(np.sum(y))  # 1.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    softmax函数的性质:

    1. softmax函数的输出是0.0到1.0之间的实数
    2. softmax函数的输出值总和为1
    3. 使用softmax函数后,各个元素之间的大小关系不会改变

    因为性质2,所以可以将函数的输出解释为“概率”

    import numpy as np
    
    
    def softmax(x):
        c = np.max(x)
        return np.exp(x - c) / np.sum(np.exp(x - c))
    
    
    a = np.array([0.3, 2.9, 4.0])
    y = softmax(a)
    print(y)  # [0.01821127 0.24519181 0.73659691]
    print(np.sum(y))  # 1.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    y中的值视为概率,可以看到最后一个元素的“概率”最高,所以答案就是第三个类别

    一般神经网络只把输出值最大的神经元所对应的类别作为识别结果

    机器学习问题的步骤为:学习和推理

    在推理阶段用学到的模型对未知的数据进行推理,因为softmax函数的性质3,各个元素的大小关系不变,所以在推理时一般会省略输出层的softmax函数

    输出层的神经元数量

    对于分类问题,输出层的神经元数量一般设定为类别的数量

    比如手写数字识别,有0到9一共十个数字,所以输出层的神经元数量设定为10.

    在这里插入图片描述

  • 相关阅读:
    SAP角色描述-只能在Logon语言中修改问题解决 .
    去除尾部和头部空格及换行符
    安全进阶:SSH实验配置指导
    Semantic Kernel 入门系列:💬Semantic Function
    【深度学习】Transformer
    【Java SE】程序逻辑控制
    EasyExcel导入导出
    DDR3 MIG IP核解决方案
    canvas实现百度AI图片多主体识别效果
    韩语学习|韩语零基础|柯桥韩语学校,每日一词
  • 原文地址:https://blog.csdn.net/hanxiaochuan1/article/details/127874451