深度学习入门2—— 神经网络的组成和3层神经网络的实现

devtools/2024/9/20 7:05:41/ 标签: 深度学习, 神经网络, 人工智能

由上一章结尾,我们知道神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数。接下来会介绍神经网络的概要,然后再结合手写数字识别案例进行介绍。

1.神经网络概要

1.1从感知机到神经网

我们可以用图来表示神经网络,我们把最左边的一列称为输入层,最右边的一列称为输出层,中间的一列称为中间层(隐藏层)。

在感知机的基础上,我们添加权重为b的输入信号1。这个感知机将x1、x2、1三个信号作为神经元的输入,将其和各自的权重相乘后传送至下一个神经元。在下一个神经元中,计算这些加权信号的总和。由于偏置的输入信号一直是1, 所以为了区别于其他神经元,我们在图中把这个神经元整个涂成灰色(如下图所示)。

我们改写感知机的数学表达式,用一个函数h(x)来表示这种分情况的动作(超过0则输出1,否则输出0):

1.2激活函数(连接感知机和神经网络的桥梁。)

先来了解一下神经网络中的激活函数的概念。上面给出的h(x)函数会将输入信号的总和转换为输出信号,这种函数一般称为激活函数(activation function)。如“激活”一词所示,__激活函数的作用在于决定如何来激活输入信号的总和。__神经网络可表达为如下方式:

上述图像展示了信号的加权总和为节点a被激活函数h()转换成节点y的详细过程。在一般的神经网络图中不表达为上述形式,而是以一个圆圈表示上述的整个过程。

接下来介绍几种常用的激活函数:

sigmoid函数(水车,根据流入量决定流出量)

h(x) = \frac{1}{(1+exp(-x))} \\

exp(-x)指的是e (−x)次方 ,e为的自然常数(纳皮尔常数2.7182…)。其本质就是给定某个输入后,会返回某个输出的转换器。值得注意的是,sigmoid函数的平滑性对神经网络的学习具有重要意义。sigmoid函数的图像及代码实现如下所示。

    def sigmoid(x):return 1 / (1 + np.exp(-x))

阶跃函数(竹筒敲石,到达一定值才输出1)

    def step_function(x):if x > 0:return 1else:return 0#为支持Numpy数组的实现,我们将阶跃函数的实现改为:#对输入的NumPy数组x进行不等号运算,生成一个布尔型数组。#数组x中大于0的元素被转换为True,小于等于0的元素被转换为False。#将布尔型数组输出为阶跃函数输出的0或1。True转换为1,False转换为0。def step_function(x):return np.array(x > 0, dtype=np.int)

上面介绍的sigmoid函数和阶跃函数均为非线性函数。神经网络的激活函数必须使用非线性函数。换句话说,激活函数不能使用线性函数。为什么不能使用线性函数呢?因为使用线性函数的话,加深神经网络的层数就没有意义了。

ReLU函数(Rectified Linear Unit)

ReLU函数在输入大于0时,直接输出该值;在输入小于等于0时,输 出0。

 def relu(x):return np.maximum(0, x)
1.3 多维数组的运算

在高校实现神经网络之前,需要掌握Numpy多维数组的运算。

import numpy as np
A = np.array([1, 2, 3, 4])
print(A)  # [1 2 3 4]
np.ndim(A)  # 1 数组的维数
A.shape  # (4,) 数组的形状
A.shape[0]  # 4 第一个维度的大小,为行数,表示改数组为4行1列。A = np.array([[1,2], [3,4]])
B = np.array([[5,6], [7,8]])
np.dot(A, B)
#array([[19, 22],
#    [43, 50]])
C = np.array([[1,2], [3,4]])
np.dot(A, C) # 不能完成矩阵乘法因为A的列数不等于C的行数

2. 3层神经网络的实现

2.1 符号规定

为了便于理解如何从Numpy数组之间的运算对应到神经网络图中的信息流动过程,故对神经网络表示的符号进行说明。

现在开始推导前向传播的整个过程:

第0层到第1层的第一个数值a1(1)计算方法为:

推广到第一层的三个值:

第0层到第1层的Numpy数组实现如下:

    X = np.array([1.0, 0.5])W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]]) #0-1层的权重矩阵B1 = np.array([0.1, 0.2, 0.3]) #0-1层的偏置矩阵print(W1.shape) # (2, 3)print(X.shape) # (2,)print(B1.shape) # (3,)A1 = np.dot(X, W1) + B1Z1 = sigmoid(A1)print(A1) # [0.3, 0.7, 1.1]print(Z1) # [0.57444252, 0.66818777, 0.75026011]

同理第1层到第2层的Numpy数组实现如下:

    W2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])B2 = np.array([0.1, 0.2])print(Z1.shape) # (3,)print(W2.shape) # (3, 2)print(B2.shape) # (2,)A2 = np.dot(Z1, W2) + B2Z2 = sigmoid(A2)

第2层到第3层(输出层)的实现:

    def identity_function(x):  # 恒等函数,将输入按原样输出,仅起程序一致作用return xW3 = np.array([[0.1, 0.3], [0.2, 0.4]])B3 = np.array([0.1, 0.2])A3 = np.dot(Z2, W3) + B3Y = identity_function(A3) # 或者Y = A3

最后,我们把整个过程串起来,一个完整的实现:

    def init_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 networkdef 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) + b1z1 = sigmoid(a1)a2 = np.dot(z1, W2) + b2z2 = sigmoid(a2)a3 = np.dot(z2, W3) + b3y = identity_function(a3)return ynetwork = init_network()x = np.array([1.0, 0.5])y = forward(network, x)print(y) # [ 0.31682708 0.69627909]

3.输出层的设计

神经网络可以用在分类问题和回归问题上,不过需要根据情况改变输出 层的激活函数。一般而言,回归问题用恒等函数,分类问题用softmax函数。恒等函数会将输入按原样输出,对于输入的信息,不加以任何改动地直 接输出。

softmax函数的分子是输入信号ak的指数函数,分母是所有输入信号的指数函数的和。输出层的各个神经元都受到所有输入信号的影响。可以用下面进行表示和实现:

    def softmax(a): #a为倒数第二层的输出向量exp_a = np.exp(a)sum_exp_a = np.sum(exp_a)y = exp_a / sum_exp_areturn y

上面的softmax函数的实现虽然正确描述了上式,但在计算机的运算中有缺陷即溢出问题。softmax函数的实现中要进行指数函数运算,指数函数的值很容易变得非常大。比如,e 的100次方会变成一个后面有40多个0的超大值,e 的1000次方的结果会返回一个表示无穷大的inf。如果在这些超大值之间进行除法运算,结果会出现“不确定”的情况。为了避免溢出问题,常常使用下面的计算方法便是softmax函数。

上面的C撇可以使用任何值,但是为了防止溢出,一般会使用输入信号(倒数第二层输出向量a)中的最大值。具体实例如下:

a = np.array([1010, 1000, 990])
np.exp(a) / np.sum(np.exp(a)) # softmax函数的运算
array([ nan, nan, nan]) # 没有被正确计算c = np.max(a) # 1010
print(a - c) # array([ 0, -10, -20])
print(np.exp(a - c) / np.sum(np.exp(a - c))) 
# array([ 9.99954600e-01, 4.53978686e-05, 2.06106005e-09])
print(np.sum(np.exp(a - c) / np.sum(np.exp(a - c))))  # 1
# 和为1,故softmax函数可以作为多分类问题的激活函数(依概率输出)

改进后的softmax函数实现为:

    def softmax(a):c = np.max(a)exp_a = np.exp(a - c) # 溢出对策sum_exp_a = np.sum(exp_a)y = exp_a / sum_exp_areturn y

一般而言,神经网络只把输出值最大的神经元所对应的类别作为识别结果。 并且,即便使用softmax函数,输出值最大的神经元的位置也不会变。因此, 神经网络在进行分类时,输出层的softmax函数可以省略。在实际的问题中, 由于指数函数的运算需要一定的计算机运算量,因此输出层的softmax函数 一般会被省略。

上图表示了手写数字的识别(10分类问题),输出值越大,颜色越“灰”。由于有softmax函数,最终的输出值均在0~1之间,且所有输出值的和为1。因此,输出之中的最大值可以作为该神经网络预测该图片中的数字为2的概率。


http://www.ppmy.cn/devtools/55606.html

相关文章

[C#] opencvsharp对Mat数据进行序列化或者反序列化以及格式化输出

【简要介绍】 在OpenCVSharp中,FileStorage类用于将数据(包括OpenCV的Mat类型数据)序列化为XML或YAML格式的文件,以及从这些文件中反序列化数据。以下是关于FileStorage类用法的详细说明: 写入数据(序列化…

【Docker】容器

目录 1. 容器启动 2. 容器启动/重启/停止 3. 进入容器 4. 容器查询 5. docker 镜像的构建 方式一:docker 容器 commit 方式二:Dockerfile 定制镜像 1. 容器启动 docker run –it/-d –p/P –name imageID/name 2. 容器启动/重启/停止 docker sta…

fc-list命令使用指南

fc-list命令使用指南 一、什么是fc-list? fc-list是FontConfig库的一部分,最初为Linux和其他Unix-like系统开发。我们可以用这个命令行快速查询和列出系统中安装的字体。 现在,Windows用户也集成了这个工具,所以我们来讲解一下用法。 二、…

算力服务先锋!和鲸科技入选《2024中国智算产业生态图谱》

2024 年 6 月 18 日,由科智咨询发起的《2024中国智算产业生态图谱》正式发布,依托 ModelWhale 构建的智算算力资源服务,以及深耕多年的 ModelWhale 数据科学协同平台优势,和鲸科技成功入选。 “智算时代”技术不断进步&#xff0c…

SpringCloudAlibaba组件之间的版本兼容问题

我之前的SpringCloud项目以及使用的组件的版本是这些 但是我不知道具体的版本兼容问题,以及各种组件之间对应的版本 想要使用我们的springcloud和springcloudAlibaba组件,我们就要版本对应,不然就是一堆依赖报错,要不就是缺了这个…

UE5近战对抗系统Tutorial

文章目录 BP_Character 组合攻击Notify State 检测攻击BP_Character 攻击反馈BP_Character 生命系统BP_Character 死亡效果BP_Character 武器系统BP_Enemy 初始化和行为树 BP_Character 组合攻击 首先我们获取攻击动画,在这里使用的是 Easy Combo Buffering 的攻击…

leetcode34:在排序数组中查找元素的第一个和最后一个位置

题目链接&#xff1a;34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:vector<int> searchRange(vector<int>& nums, int target) {if(nums.empty()) {return {-1, -1};}vector<int> R…

哈夫曼编码

一.哈夫曼树 哈夫曼树&#xff08;Huffman Tree&#xff09;是一种用于数据压缩的二叉树。它基于字符出现的频率构建&#xff0c;使得高频字符使用较短的编码&#xff0c;低频字符使用较长的编码&#xff0c;从而实现数据压缩。哈夫曼树也被称为最优二叉树或哈夫曼编码树。 哈夫…

Kafka精要

Apach Kafka 是一款分布式流处理框架&#xff0c;用于实时构建流处理应用。它有一个核心 的功能广为人知&#xff0c;即 作为企业级的消息引擎被广泛使用 kafka设计 Kafka 将消息以 topic 为单位进行归纳 将向 Kafka topic 发布消息的程序成为 producers. 将预订 topics 并消…

HTML(9)——字体修饰

常用的字体修饰属性 属性描述font-size字体大小 单位&#xff1a;数字pxfont-weight字体粗细 单位&#xff1a;数字font-style 字体倾斜 line-height行高 单位&#xff1a;数字px/数字(当前size的倍数&#xff09;font-family字体族…

Mac(M1芯片)安装多个jdk,Mac卸载jdk

1.jdk下载 oracle官方链接&#xff1a;oracle官方下载链接 2.安装 直接下一步&#xff0c;下一步就行 3.查看是否安装成功 出现下图内容表示安装成功。 4.配置环境变量 open -e .bash_profile 路径建议复制过去 #刷新环境变量 source ~/.bash_profile 5.切换方法 6.jdk…

Vue78-缓存路由组件

一、需求 路由切走的时候&#xff0c;组件会被销毁&#xff0c;路由切回来&#xff0c;组件被挂载&#xff01; 需要&#xff1a;路由切走的时候&#xff0c;组件不会被销毁。 二、代码实现 若是不加include属性&#xff0c;则在<router-view>里面展示的路由&#xff0c…

深入JVM:详解JIT即时编译器

文章目录 深入JVM&#xff1a;详解JIT即时编译器一、序言二、基础概念1、何为JIT即时编译2、热点代码 三、HotSpot内置的即时编译器1、C1编译器2、C2编译器3、分层编译3.1 协作流程 四、常见JIT优化技术1、方法内联2、逃逸分析&#xff08;1&#xff09;同步锁消除&#xff08;…

关于jupyter notebook的使用经验

jupyter notebook 第一点&#xff0c;调整每次打开jupyter notebook的时候的位置第二点&#xff0c;如何设置jupyter notebook可以使用本地anaconda创建的虚拟环境呢&#xff1f;第三点&#xff0c;使用jupyter notebook的技巧 以下三点都是独立的&#xff0c;可以根据自己的需…

jsonpath_解析例子代码

# _*_ coding : utf-8 _*_ # Time : 2023-11-05 13:23 # Author : haowen # File : jsonpath_解析_淘票票 # Project : py练习 import urllib.request url https://dianying.taobao.com/cityAction.json?activityId&_ksTS1699161894273_112&jsoncallbackjsonp113&…

2024年软考架构设计师终于PASS啦

文章目录 系统架构设计师是什么考试要求考试科目个人心得综合知识上午案例下午论文 系统架构设计师是什么 系统架构设计师&#xff0c;属于计算机技术与软件&#xff08;高级&#xff09;专业技术资格。考试合格人员能够根据系统需求规格说明书&#xff0c;结合应用领域和技术…

React Hooks使用规则:为什么不在条件语句和循环中使用它们

React Hooks为函数组件引入了状态和生命周期特性&#xff0c;极大地增强了其功能。然而&#xff0c;正确使用Hooks是确保组件稳定性和性能的关键。本文将探讨React Hooks的基本规则&#xff0c;以及为什么我们不应该在条件语句和循环中使用它们。 Hooks的基本规则 React团队为…

74. UE5 RPG 搭建场景设置光照和纹理流送

前面&#xff0c;我们对角色和敌人进行了一些完善。在这一篇文章里面&#xff0c;我们将进行对场景进行搭建&#xff0c;并对场景的光照和场景的后处理进行设置。 创建新场景 选择新建关卡 接着选择将关卡另存为 选择一个合理的位置 我们将场景内的网格地面删除掉&#xf…

微信小程序中的地图的使用

微信小程序中的地图组件 是一个用于展示地图的组件&#xff0c;提供了丰富的功能和配置选项&#xff0c;可以实现定位、标记、路线规划等多种地图相关的交互。下面是对这个组件的详细介绍&#xff0c;包括属性、事件以及示例代码。 组件属性 基础属性 longitude: 地图中心的经…

AcWing算法基础课笔记——状态压缩DP:蒙德里安的梦想

状态压缩DP 状态是整数&#xff0c;但把它看成二进制数&#xff0c;二进制中每一位是0或1表示不同的情况。 蒙德里安的梦想 291. 蒙德里安的梦想 - AcWing题库 题目 求把 NM&#x1d441;&#x1d440; 的棋盘分割成若干个 1212 的长方形&#xff0c;有多少种方案。 例如…