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

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

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.mzph.cn/diannao/32045.shtml

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

相关文章

上位机图像处理和嵌入式模块部署(mcu之静态库生成和使用)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 很多同学做了很长时间的mcu和keil开发,都认为keil工程中必须包含所有的源代码,其实这是不对的。如果有一些代码我们不希望别…

IKVM.net调用Jar包实现SM4解密

近期,我深入学习了如何使用IKVM.net来调用Jar包,这次的学习经历让我对Java与.NET之间的互操作性有了更深刻的理解。IKVM.net作为一款强大的工具,为我们打通了Java与.NET之间的桥梁,使得在.NET环境中调用Java库变得简单而高效。 在…

红队内网攻防渗透:内网渗透之内网对抗:信息收集篇自动项目本机导出外部打点域内通讯PillagerBloodHound

红队内网攻防渗透 1. 内网自动化信息收集1.1 本机凭据收集类1.1.1、HackBrowserData 快速获取浏览器的账户密码1.1.2、Searchall 快速搜索服务器中的有关敏感信息还有浏览器的账户密码1.1.3、Pillager 适用于后渗透期间的信息收集工具,可以收集目标机器上敏感信息1.2 对外打点…

密码(6)

一、[NCTF 2019]Keyboard——键盘密码 1.题目: ooo yyy ii w uuu ee uuuu yyy uuuu y w uuu i i rr w i i rr rrr uuuu rrr uuuu t ii uuuu i w u rrr ee www ee yyy eee www w tt ee 2.解题: 这些字母是26键盘上的第一行,每个字母对应上…

redis类型解析汇总

redis类型解析汇总 介绍数据类型简介主要数据类型:衍生类型: 字符串(String)底层设计原理图例设计优势字符串使用方法设置字符串值获取字符串值获取和设置部分字符串获取字符串长度追加字符串设置新值并返回旧值递增/递减同时设置…

通过 WireGuard 组建虚拟局域网 实现多个局域网全互联

本文后半部分代码框较多,欢迎点击原文链接获得更佳的阅读体验。 前言 上一篇关于 WireGuard 的文章通过 Docker 安装 wg-easy 的形式来使用 WireGuard,但 wg-easy 的功能比较有限,并不能发挥出 WireGuard 的全部功力。 如果只是想要出门在外连随时随地的连回家里的局域网,…

067、Python 高阶函数的编写:优质冒泡排序

以下写了个简单的冒泡排序函数: def bubble_sort(items: list) -> list:for i in range(1, len(items)):swapped Falsefor j in range(0, len(items) - 1):if items[j] > items[j 1]:items[j], items[j 1] items[j 1], items[j]swapped Trueif not swa…

UCOS高频面试题及参考答案(2万字长文)

目录 UCOS-II/UCOS-III的基本特点和适用场景 UCOS-II与UCOS-III的主要区别 UCOS的任务状态 OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()函数 UCOS-III任务调度过程 时间片轮转调度与UCOS-II 创建UCOS任务的步骤 使用UCOS信号量进行任务同步 信号量与互斥量的区别 UCOS中…

[数据集][目标检测]棉花叶子害虫检测数据集VOC+YOLO格式571张1类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):595 标注数量(xml文件个数):595 标注数量(txt文件个数):595 标注类别…

Linux驱动调试——使用DEVICE_ATTR实现cat、echo指令调试驱动

在平常做一些驱动调试的时候,每次都写应用去调试相对较麻烦,有一个非常便捷的操作方法就是使用device_attr,只需要执行shell指令例如echo和cat就可以看到效果,不需要再单独写一个测试demo。 看网上很多博客在这一块的使用上写的都…

FENDI CLUB精酿啤酒与小麦的不解之缘

FENDI CLUB精酿啤酒与小麦之间这种联系体现在啤酒的酿造原料、口感特色以及文化内涵等多个方面。以下是关于这两者之间关系的详细分析: 一、酿造原料的紧密联系 小麦作为关键原料:FENDI CLUB精酿啤酒在酿造过程中,小麦是不可或缺的原料之一…

Mybatis 系列全解(1)——全网免费最细最全,手把手教,学完就可做项目!

Mybatis 系列全解(1) 1. 第一个小程序2. CURD 增删改查3. 模糊查询4. 配置解析4.1 核心配置文件4.2 环境配置4.3 属性4.4 类型别名4.5 设置4.6 映射器 mappers 1. 第一个小程序 1)创建一个数据库,一个表,填入一些数据…

OpenAI项目爆改GLM——以基于llama_index的pdf阅读助手

最近在做大模型agent构建,看了许多不错的开源项目,但是clone下来就是一整个不能用,因为github上开源的项目基本都是基于openai做的。而如果想要转成国内大模型backbone,需要修改的地方挺多的。 现在以一个简单的pdf reader agent…

【Qt】QList<QVariantMap>中数据修改

1. 问题 QList<QVariantMap> 类型中&#xff0c;修改QVariantMap中的值。 2. 代码 //有效代码1QVariantMap itemMap itemList.at(0);itemMap.insert("title", "test");itemList.replace(0, itemMap);//有效代码 2itemList.operator [](0).insert(…

17岁中专生姜萍数学竞赛成绩可信吗?

数学竞赛已经消失很久&#xff0c;但是因为焦虑家长存在需求&#xff0c;”赢在赛跑起点“的认知偏见&#xff0c;以及学术象牙塔为自己存在寻求存在理由和荣誉感&#xff0c;等诸多因素&#xff0c;最近一名17岁女中专生闯入某个互联网企业举办的民间数学决赛&#xff0c;引发…

Python3简单实现与Java的Hutool库SM2的加解密互通

1、背景&#xff1a; 因业务需求&#xff0c;需要与某平台接口对接。平台是Java基于Hutool库实现的SM2加密解密&#xff0c;研究了下SM2的加解密算法&#xff0c;网上找的资料&#xff0c;都是说SM2【椭圆曲线】 公钥长【x,y分量 64字节】&#xff0c;私钥短【32字节】&#x…

华为---OSPF被动接口配置(四)

9.4 OSPF被动接口配置 9.4.1 原理概述 OSPF被动接口也称抑制接口&#xff0c;成为被动接口后&#xff0c;将不会接收和发送OSPF报文。如果要使OSPF路由信息不被某一网络中的路由器获得且使本地路由器不接收网络中其他路由器发布的路由更新信息&#xff0c;即已运行在OSPF协议…

FuTalk设计周刊-Vol.031

&#x1f525;AI漫谈 热点捕手 1、如何用自然语言 5 分钟构建个人知识库应用&#xff1f;我的 GPTs builder 尝试 开发者的想象力闸门一旦打开&#xff0c;迎接我们的必然是目不暇接的 AI 应用浪潮冲击。 链接https://sspai.com/post/84325 2、GPT-4 Turbo、功能融合&#x…

Android的OverlayFS原理与作用

标签: OverlayFS; Android;Overlay Filesystem; Android的OverlayFS原理与作用 概述 OverlayFS(Overlay Filesystem)是一种联合文件系统,允许将一个或多个文件系统叠加在一起,使它们表现为一个单一的文件系统。Android系统利用OverlayFS来实现动态文件系统的叠加和管…

Java延迟初始化Logger日志对象

开源项目SDK&#xff1a;https://github.com/mingyang66/spring-parent 个人文档&#xff1a;https://mingyang66.github.io/raccoon-docs/#/ 将日志Logger对象定义在静态内部类中是一种常见的做法&#xff0c;这样做是有它特殊的好处&#xff0c;示例如下&#xff1a; privat…