搭建深度神经网络(DNN)

news2024/9/21 16:41:52

利用 numpy 工具,手动搭建一个 DNN 深度神经网络。

  • 定义网络结构

  • 初始化模型参数

  • 循环计算:前向传播/计算当前损失/反向传播/权值更新

图片

1、初始化模型参数

    对于一个包含L层的隐藏层深度神经网络,我们在初始化其模型参数的时候需要更灵活一点。我们可以将网络结构作为参数传入初始化函数里面:

def initialize_parameters_deep(layer_dims):
    np.random.seed(3)
    parameters = {}    
    # number of layers in the network
    L = len(layer_dims)            

    for l in range(1, L):
        parameters['W' + str(l)] = np.random.randn(layer_dims[l], layer_dims[l-1])*0.01
        parameters['b' + str(l)] = np.zeros((layer_dims[l], 1))  
      
    assert(parameters['W' + str(l)].shape == (layer_dims[l], layer_dims[l-1]))        
    assert(parameters['b' + str(l)].shape == (layer_dims[l], 1))
    return parameters

    以上代码中,我们将参数 layer_dims 定义为一个包含网络各层维数的 list ,使用随机数和归零操作来初始化权重 W 和偏置 b

    比如说我们指定一个输入层大小为 5 ,隐藏层大小为 4 ,输出层大小为 3 的神经网络,调用上述参数初始化函数效果如下:

parameters = initialize_parameters_deep([5,4,3])
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
W1 = [[ 0.01788628  0.0043651   0.00096497 -0.01863493 -0.00277388]  [-0.00354759 -0.00082741 -0.00627001 -0.00043818 -0.00477218]  [-0.01313865  0.00884622  0.00881318  0.01709573  0.00050034]  [-0.00404677 -0.0054536  -0.01546477  0.00982367 -0.01101068]] 
b1 = [[0.]  [0.]  [0.]  [0.]] 
W2 = [[-0.01185047 -0.0020565   0.01486148  0.00236716]  [-0.01023785 -0.00712993  0.00625245 -0.00160513]  [-0.00768836 -0.00230031  0.00745056  0.01976111]] 
b2 = [[0.]  [0.]  [0.]]
2、前向传播

    前向传播的基本过程就是执行加权线性计算和对线性计算的结果进行激活函数处理的过程。除了此前常用的 sigmoid 激活函数,这里我们引入另一种激活函数 ReLU ,那么这个 ReLU 又是个什么样的激活函数呢?

图片

ReLU

ReLU 全称为线性修正单元,其函数形式表示为 y = max(0, x).
    从统计学本质上讲,ReLU 其实是一种断线回归函数,其主要功能在于能在计算反向传播时缓解梯度消失的情形。相对书面一点就是,ReLU 具有稀疏激活性的优点。关于ReLU的更多细节,这里暂且按下不表,我们继续定义深度神经网络的前向计算函数:

def linear_activation_forward(A_prev, W, b, activation):
    if activation == "sigmoid":
        Z, linear_cache = linear_forward(A_prev, W, b)
        A, activation_cache = sigmoid(Z)    
    elif activation == "relu":
        Z, linear_cache = linear_forward(A_prev, W, b)
        A, activation_cache = relu(Z)   
     
    assert (A.shape == (W.shape[0], A_prev.shape[1]))
    cache = (linear_cache, activation_cache)    
    return A, cache

    在上述代码中, 参数 A_prev 为前一步执行前向计算的结果,中间使用了一个激活函数判断,对两种不同激活函数下的结果分别进行了讨论。

    对于一个包含L层采用 ReLU 作为激活函数,最后一层采用 sigmoid 激活函数,前向计算流程如下图所示。

图片

    定义L层神经网络的前向计算函数为:

def L_model_forward(X, parameters):
    caches = []
    A = X    
    # number of layers in the neural network
    L = len(parameters) // 2                 

    # Implement [LINEAR -> RELU]*(L-1)
    for l in range(1, L):
        A_prev = A 
        A, cache = linear_activation_forward(A_prev, parameters["W"+str(l)], parameters["b"+str(l)], "relu")
        caches.append(cache)    
    # Implement LINEAR -> SIGMOID
    AL, cache = linear_activation_forward(A, parameters["W"+str(L)], parameters["b"+str(L)], "sigmoid")
    caches.append(cache)    
    
    assert(AL.shape == (1,X.shape[1]))    
    return AL, caches
3、计算当前损失

    有了前向传播的计算结果之后,就可以根据结果值计算当前的损失大小。定义计算损失函数为:

def compute_cost(AL, Y):
    m = Y.shape[1]    
    # Compute loss from aL and y.
    cost = -np.sum(np.multiply(Y,np.log(AL))+np.multiply(1-Y,np.log(1-AL)))/m

    cost = np.squeeze(cost)  
       
    assert(cost.shape == ())    
    return cost
4、执行反向传播

    执行反向传播的关键在于正确的写出关于权重 W 和 偏置b 的链式求导公式,对于第 l层而言,其线性计算可表示为:

图片

    响应的第l层的Wb 的梯度计算如下:

图片

    由上分析我们可定义线性反向传播函数和线性激活反向传播函数如下:

def linear_backward(dZ, cache):
    A_prev, W, b = cache
    m = A_prev.shape[1]

    dW = np.dot(dZ, A_prev.T)/m
    db = np.sum(dZ, axis=1, keepdims=True)/m
    dA_prev = np.dot(W.T, dZ)    

    assert (dA_prev.shape == A_prev.shape)    
    assert (dW.shape == W.shape)    
    assert (db.shape == b.shape)    
    
    return dA_prev, dW, db
def linear_activation_backward(dA, cache, activation):
    linear_cache, activation_cache = cache    
    if activation == "relu":
        dZ = relu_backward(dA, activation_cache)
        dA_prev, dW, db = linear_backward(dZ, linear_cache)    
    elif activation == "sigmoid":
        dZ = sigmoid_backward(dA, activation_cache)
        dA_prev, dW, db = linear_backward(dZ, linear_cache)    
    return dA_prev, dW, db

    根据以上两个反向传播函数,我们可继续定义L层网络的反向传播函数:

def L_model_backward(AL, Y, caches):
    grads = {}
    L = len(caches) 
    # the number of layers
    m = AL.shape[1]
    Y = Y.reshape(AL.shape) 
    # after this line, Y is the same shape as AL

    # Initializing the backpropagation
    dAL = - (np.divide(Y, AL) - np.divide(1 - Y, 1 - AL))    
    # Lth layer (SIGMOID -> LINEAR) gradients
    current_cache = caches[L-1]
    grads["dA" + str(L)], grads["dW" + str(L)], grads["db" + str(L)] = linear_activation_backward(dAL, current_cache, "sigmoid")    
    for l in reversed(range(L - 1)):
        current_cache = caches[l]
        dA_prev_temp, dW_temp, db_temp = linear_activation_backward(grads["dA" + str(l + 2)], current_cache, "relu")
        grads["dA" + str(l + 1)] = dA_prev_temp
        grads["dW" + str(l + 1)] = dW_temp
        grads["db" + str(l + 1)] = db_temp    
    return grads

    反向传播涉及大量的复合函数求导计算,所以这一块需要一定的微积分基础。这也是为什么数学是深度学习人工智能的基石所在。

5、权值更新

    反向传播计算完成后,即可根据反向计算结果对权值参数进行更新,定义参数更新函数如下:

def update_parameters(parameters, grads, learning_rate):
    # number of layers in the neural network
    L = len(parameters) // 2 
    # Update rule for each parameter. Use a for loop.
    for l in range(L):
        parameters["W" + str(l+1)] = parameters["W"+str(l+1)] - learning_rate*grads["dW"+str(l+1)]
        parameters["b" + str(l+1)] = parameters["b"+str(l+1)] - learning_rate*grads["db"+str(l+1)]    
    return parameters
6、封装搭建过程

    对全过程的各个函数进行统一封装,定义一个封装函数:

def L_layer_model(X, Y, layers_dims, learning_rate = 0.0075, num_iterations = 3000, print_cost=False):
    np.random.seed(1)
    costs = []    

    # Parameters initialization.
    parameters = initialize_parameters_deep(layers_dims)    
    # Loop (gradient descent)
    for i in range(0, num_iterations):        
        # Forward propagation: 
        # [LINEAR -> RELU]*(L-1) -> LINEAR -> SIGMOID
        AL, caches = L_model_forward(X, parameters)        
        # Compute cost.
        cost = compute_cost(AL, Y)        
        # Backward propagation.
        grads = L_model_backward(AL, Y, caches)        
        # Update parameters.
        parameters = update_parameters(parameters, grads, learning_rate)        
        # Print the cost every 100 training example
        if print_cost and i % 100 == 0:            
            print ("Cost after iteration %i: %f" %(i, cost))        if print_cost and i % 100 == 0:
            costs.append(cost)    
    # plot the cost
    plt.plot(np.squeeze(costs))
    plt.ylabel('cost')
    plt.xlabel('iterations (per tens)')
    plt.title("Learning rate =" + str(learning_rate))
    plt.show()    
    
    return parameters

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2075193.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

触想强固型工业显示器加速海上油气勘探开发

石油作为现代工业发展的主要能源,已成为国际间政治、经济博弈的重要工具。 一、行业发展背景 过去百年间,人类对陆地油气资源的勘探开发逐渐趋于饱和,而面对持续增长的全球能源需求,海洋勘探已成为当今油气能源角逐的主要“战场”…

Linux文件IO缓存

一、缓冲区大小对 I/O 系统调用性能的影响 总之,如果与文件发生大量的数据传输,通过采用大块空间缓冲数据,以及执行更少的 系统调用,可以极大地提高 I / O 性能 二、stdio 库的缓冲 当操作磁盘文件时,缓冲大块数据以…

合宙LuatOS产品规格书——Air700EAQ

Luat Air700EAQ是合宙的LTE Cat.1bis通信模块,采用移芯EC716E平台,支持LTE 3GPP Rel.13技术。 该模块专为满足小型化、低成本需求而设计,具备超小封装和极致成本优势。 Air700EAQ支持移动双模,内置丰富的网络协议,集…

Qt第二十章 数据库操作

文章目录 Qt操作数据库QSqlDataBaseQSqlQuery执行SQL语句 QSqlRecordQSqlField数据库模型QSqlQueryModelQSqlTableModelQSqlRelationalTableModel 编译MySql驱动msvc版本MySql客户端程序部署 Qt操作数据库 需要在cmakelist加上Sql模块 QSqlDataBase 可以通过静态成员查看支持的…

北京青蓝智慧科技:2024(第九届)世界物联网大会将于11月在京举行

2024年11月,北京将迎来第九届世界物联网大会的盛大启幕。 这一年度盛会由世界物联网大会、中国移动通信联合会、外交理事会携手举办,得到了世界绿色设计组织、世界物联网基金会等机构的大力支持。 大会的宗旨在于推动全球智能联网数字经济的创新进展&a…

Golang | Leetcode Golang题解之第373题查找和最小的K对数字

题目: 题解: func kSmallestPairs(nums1, nums2 []int, k int) (ans [][]int) {m, n : len(nums1), len(nums2)// 二分查找第 k 小的数对和left, right : nums1[0]nums2[0], nums1[m-1]nums2[n-1]1pairSum : left sort.Search(right-left, func(sum in…

Notion 使用详解——基础教程

《Notion 使用详解——基础教程》 一、Notion简介 Notion是一款集笔记、任务、数据库、wiki、知识库等功能于一体的生产力工具,其强大的模块化设计和高度自定义能力,使其成为个人和团队提高工作效率的理想选择。 二、基础操作 1. 创建页面:…

几个很棒的AI问题和精彩回答

这里有几个很棒的与AI相关的问题和精彩的回答,分享给大家 2024,怎么以10倍的速度设计AI产品? 回答嘉宾:Tidyread作者 根据产品定位,对整体风格进行定调 Tidyread 希望人们能从中建立资讯阅读的秩序感,所以…

阿里云对象存储OSS的前端直传-demo

原由 在项目里有时候会碰到比如上传文件相关的,一般都是后端提供个接口,然后我们上传的时候后端再传到阿里OSS或者其他服务商的对象存储,然后把最终的url拿到存起来或者返回给前端,这种方式其实在上传图片的频率不高的业务场景中…

电商数据接口助力电商数据分析||电商运营每日必看5个底层数据

数据分析充电站——深入探索中小企业数字化转型,专注提供各行业数据分析干货、分析技巧、工具推荐以及各类超实用分析模板,为钻研于数据分析的朋友们加油充电。 电商运营店铺涉及大量数据,包括用户行为、交易记录、库存信息等,如何…

Python测试之测试覆盖率统计

本篇承接上一篇 Python测试框架之—— pytest介绍与示例,在此基础上介绍如何基于pytest进行测试的覆盖率统计。 要在使用 pytest 进行测试时检测代码覆盖率,可以使用 pytest-cov 插件。这个插件是基于 coverage.py,它能帮助你了解哪些代码部…

【PySide6-QML】2. 添加菜单栏

文章目录 前言实现添加菜单栏添加菜单添加子菜单点击动作添加快捷键 前章回顾:【PySide6-QML】1. 创建新项目 前言 本文使用 MenuBar 添加工具菜单栏,Action 添加子菜单,并添加快捷键和动作回调。 实现 添加菜单栏 import QtQuick.Contr…

centos mongodb安装+开机启动

1.mongodb安装 Centos系统中mongodb的安装详解_centos安装mongodb-CSDN博客 步骤1-下载 下载地址:Download MongoDB Community Server | MongoDB 步骤2-安装-修改配置 Centos系统中mongodb的安装详解_centos安装mongodb-CSDN博客 下载包到 /usr/local/ 解压 tar…

新一代RK3576芯片,3588平替吗?

瑞芯微RK3576是一款高性能、低功耗的SoC(系统级芯片)处理器,适用于基于ARM的PC、边缘计算设备、个人移动互联网设备等多种应用场景。它采用Arm架构的八核心CPU,集成了GPU、MCU、NPU、VPU等多种计算核心,并具有丰富的外…

基于深度学习的交通标志检测识别系统(含UI界面、yolov5、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下: 算法模型:     yolov5、yolov5 SE注意力机制,两个模型都已训练好,可直接使用。 数据集:     网上下载的数据集,格式都已转好,可…

K8S对接Ceph分部署存储

文章目录 一、Ceph理论知识1、Ceph简介2、Ceph分布式存储的优点3、Ceph核心组件 二、部署Ceph高可用集群1、服务器环境信息2、部署前环境准备工作3、部署Ceph监控服务Monitor4、激活Ceph存储服务OSD 三、K8S对接Ceph存储1、K8S对接Ceph RBD实现数据持久化2、基于Ceph RBD生成PV…

【精选】基于数据可视化的智慧社区内网平台(程序员阿龙出品精品)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

游戏出海,燃动全球,“安全”如何通关?

泼天的富贵落在了游戏圈,用事实打脸了男人消费不如狗的谬论。 这几天,无论是游戏圈内人还是圈外人,无人不知晓《黑神话:悟空》。这部头顶「3A国产游戏之光」的作品自6月8日预售以来,全平台销量超过800万份,…

基于R语言的统计分析基础:数据结构

R语言是一种用于统计分析和图形表示的编程语言和软件环境,它提供了多种数据结构以存储和操作数据。这些数据结构包括向量、矩阵、数组、数据框、列表、因子、Tibble、环境、公式、调用以及表达式。 向量(Vector) 向量是R中最基本的数据结构…

InstantID: Zero-shot Identity-Preserving Generation in Seconds

https://arxiv.org/pdf/2401.07519#page9.73https://github.com/instantX-research/InstantID?tabreadme-ov-filehttps://github.com/instantX-research/InstantID/pull/89/files 问题引入 目标是生成和reference图片相符合的图片,特别是人脸;现在基于…