深度学习入门——神经网络

前言

image-20240713161717914

神经网络可以帮助自动化设定权重

具体地讲,神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数

从感知机到神经网络

神经网络的例子

image-20240713162915788

中间层aka隐藏层

复习感知机

image-20240713164325276

偏置b 并没有被画出来。如果要明确地表示出b,可以像图3-3那样做

我们用一个函数来表示这种分情况的动作(超过0 则输出1,否则输出0)

y = h(b + w1x1 + w2x2)

image-20240713164410998

image-20240713164317059

激活函数登场

如h(x)函数将输入信号的综合转换为输出信号一般称为激活函数

激活函数的作用在于决定如何来激活输入信号的总和

先计算输入信号的加权总和,然后用激活函数转换这一总和,可以将y = h(b + w1x1 + w2x2)分成两个式子

image-20240713165352839

image-20240713165430718

激活函数是连接感知机和神经网络的桥梁

一般而言,“朴素感知机”是指单层网络,指的是激活函数使用了阶跃函数的模型。

(阶跃函数是指一旦输入超过阈值,就切换输出的函数)

“多层感知机”是指神经网络,即使用sigmoid函数(后述)等平滑的激活函数的多层网络。

激活函数

实际上,如果将激活函数从阶跃函数换成其他函数,就可以进入神经网络的世界了

sigmoid函数

image-20240713165954309

神经网络中经常使用的一个激活函数就是式(3.6)表示的sigmoid 函数(sigmoid function)

exp(−x)表示e^−x 的意思

阶跃函数的实现

def step_function(x):
	if x > 0:
		return 1
	else:
		return 0

这个实现简单、易于理解,但是参数x只能接受实数(浮点数)

为了便于后面的操作,我们把它修改为支持NumPy数组的实现

def step_function(x):
	y = x > 0
	return y.astype(np.int)

可以用astype()方法转换NumPy数组的类型,通过参数指定期望的类型

Python 中将布尔型转换为int型后,True会转换为1,False会转换为0

阶跃函数的图形

image-20240713172731720

如图3-6 所示,阶跃函数以0 为界,输出从0 切换为1(或者从1 切换为0)。它的值呈阶梯式变化,所以称为阶跃函数

sigmoid函数的实现

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

根据NumPy 的广播功能,如果在标量和NumPy数组之间进行运算,则标量会和NumPy数组的各个元素进行运算

sigmoid函数的图形

image-20240713173129398

sigmoid函数和阶跃函数的比较

有点类似于数字信号和模拟信号

image-20240713173208866

不同点

  • 首先注意到的是“平滑性”的不同。sigmoid 函数是一条平滑的曲线,输出随着输入发生连续性的变化。而阶跃函数以0 为界,输出发生急剧性的变化。sigmoid 函数的平滑性对神经网络的学习具有重要意义。
  • 另一个不同点是,相对于阶跃函数只能返回0 或1,sigmoid 函数可以返回0.731 . . .、0.880 . . . 等实数(这一点和刚才的平滑性有关)。也就是说,感知机中神经元之间流动的是0 或1 的二元信号,而神经网络中流动的是连续的实数值信号。

相同点

  • 两者的结构均是“输入小时,输出接近0(为0);随着输入增大,输出向1 靠近(变成1)”。也就是说,当输入信号为重要信息时,阶跃函数和sigmoid函数都会输出较大的值;当输入信号为不重要的信息时,两者都输出较小的值
  • 不管输入信号有多小,或者有多大,输出信号的值都在0 到1 之间。

非线性函数

阶跃函数和sigmoid函数均为非线性函数

神经网络的激活函数必须使用非线性函数

这里可能会产生疑惑

前面的多层感知器和神经网络之间的关系是什么?是同一个东西

也就是说异或门的实现是一个神经网络吗?是的

Q:为什么不能使用线性函数呢?

A:因为使用线性函数的话,加深神经网络的层数就没有意义了。使用线性函数时,无法发挥多层网络带来的优势。因此,为了发挥叠加层所带来的优势,激活函数必须使用非线性函数

ReLU函数

在神经网络发展的历史上,sigmoid 函数很早就开始被使用了,而最近则主要使用ReLU(Rectified Linear Unit)函数。

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

image-20240713174941407

image-20240713174952053

实现

def relu(x):
	return np.maximum(0, x)

多维数组的运算

掌握了NumPy多维数组的运算,就可以高效地实现神经网络

数组的维数累哦通过 np.dim() 函数获得

数组的形状可以通过实例变量shape获得

矩阵乘法

二维数组也称为矩阵(matrix)。如图3-10 所示,数组的横向排列称为行(row),纵向排列称为列(column)。

image-20240713180103448

可以通过NumPy 的np.dot()函数计算(乘积也称为点积)

[!IMPORTANT]

盲区:当A是二维矩阵、B是一维数组时,对应维度的元素个数要保持一致的原则依然成立。

从结果来看,一维数组的转置不影响点乘的结果,但是二维矩阵和一维数组的位置会影响点乘的结果

当一维数组在右边时,不论是否转置,会默认变成p行1列的矩阵,即p1
当一维数组在左边时,不论是否转置,会默认变成1行p列的矩阵,即1
p
不管B进行.T运算与否,B被看成什么样子完全由乘法的顺序和a的形状决定

image-20240713191810691

神经网络的内积

image-20240713195131193

下面我们使用NumPy矩阵来实现神经网络。这里我们以图3-14 中的简单神经网络为对象。这个神经网络省略了偏置和激活函数,只有权重。

通过矩阵的乘积一次性完成计算的技巧,在实现的层面上可以说是非常重要的

3层神经网络的实现

image-20240713200548279

以图3-15 的3 层神经网络为对象,实现从输入到输出的(前向)处理。在代码实现方面,使用上一节介绍的NumPy多维数组

符号确认

神经网络的运算可以作为矩阵运算打包进行

image-20240713203416516

各层间信号传递的实现

任何前一层的偏置神经元“1”都只有一个

偏置权重的数量取决于后一层的神经元的数量(不包括后一层的偏置神经元“1”)

image-20240713203904754

用数学式表示

image-20240713204010125

矩阵乘法表示

image-20240713204211014

image-20240713204256031

1层计算过程

观察第1 层中激活函数的计算过程。如果把这个计算过程用图来表示的话,则如图3-18 所示。

image-20240713205041805

隐藏层的加权和(加权信号和偏置的总和)用a表示,被激活函数转换后的信号用z 表示

1->2层信号传递

通过使用NumPy数组,可以将层到层的信号传递过程简单地写出来

image-20240713205626885

第2层到输出层的信号传递

我们定义了identity_function()函数(也称为“恒等函数”),并将其作为输出层的激活函数

这里这样实现只是为了和之前的流程保持统一

另外,图3-20 中,输出层的激活函数用σ() 表示,不同于隐藏层的激活函数h()(σ读作sigma)

image-20240713210609159

输出层所用的激活函数,要根据求解问题的性质决定

[!IMPORTANT]

一般地,回归问题可以使用恒等函数,

二元分类问题可以使用sigmoid 函数,

多元分类问题可以使用softmax 函数

代码实现小结

我们按照神经网络的实现惯例,只把权重记为大写字母W1,其他的(偏置或中间结果等)都用小写字母表示

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 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(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(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]

init_network()函数会进行权重和偏置的初始化,并将它们保存在字典变量network中

forward()函数中则封装了将输入信号转换为输出信号的处理过程。

forward(前向)一词,它表示的是从输入到输出方向的传递处理

后面在进行神经网络的训练时,我们将介绍后向(backward,从输出到输入方向)的处理。

输出层的设计

神经网络可以用在分类问题和回归问题上,不过需要根据情况改变输出层的激活函数

机器学习的问题大致可以分为分类问题回归问题。分类问题是数据属于哪一个类别的问题。比如,区分图像中的人是男性还是女性的问题就是分类问题。而回归问题是根据某个输入预测一个(连续的)数值的问题

恒等函数和softmax函数

image-20240714105054534

image-20240714105212891

输出层的各个神经元都受到所有输入信号的影响

image-20240714105333875

#虽然正确描述了式(3.10),但在计算机的运算上有溢出问题
def softmax(a):
    exp_a = np.exp(a)
    sum_exp_a = np.sum(exp_a)
    y = exp_a / sum_exp_a
    return y

实现softmax函数时的注意事项

softmax函数中要进行指数函数的运算,但是此时指数函数的值很容易变得非常大,在这些超大值之间进行除法运算,结果会出现“不确定”的情况

[!NOTE]

计算机可以表示的数值范围是有限的(32位或64位),会出现超大值无法表示的问题,这个问题称为溢出

image-20240714110252522

式(3.11)说明,在进行softmax 的指数函数的运算时,加上(或者减去)某个常数并不会改变运算的结果.

这里的C’可以使用任何值,但是为了防止溢出,一般会使用输入信号中的最大值

improved 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_a
    return y

softmax 函数的特征

  1. softmax 函数的输出是0.0 到1.0之间的实数
  2. softmax 函数的输出值的总和是1
  3. softmax函数的输出可以解释为“概率”
  4. 各个元素之间的大小关系不会改变

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

即便使用softmax 函数,输出值最大的神经元的位置也不会变,神经网络在进行分类时,输出层的softmax 函数可以省略

在实际的问题中,由于指数函数的运算需要一定的计算机运算量,因此输出层的softmax 函数一般会被省略

[!IMPORTANT]

求解机器学习问题的步骤可以分为“学习” 和“推理”两个阶段。首先,在学习阶段进行模型的学习,然后,在推理阶段,用学到的模型对未知的数据进行推理(分类)

推理阶段一般会省略输出层的softmax 函数。在输出层使用softmax 函数是因为它和神经网络的学习有关系

输出层的神经元数量

输出层的神经元数量需要根据待解决的问题来决定

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

手写数字识别

假设学习已经全部结束,我们使用学习到的参数,先实现神经网络的“推理处理”。这个推理处理也称为神经网络的前向传播(forward propagation)

MNIST数据集

MNIST的图像数据是28 像素× 28 像素的灰度图像(1 通道),各个像素的取值在0 到255 之间

神经网络的推理过程

在手写数字识别中,神经网络的输入层有784个神经元,输出层有10个神经元

def get_data():
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
    return x_test, t_test

def init_network():
    with open("sample_weight.pkl", 'rb') as f:
        network = pickle.load(f)
    return network

def predict(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(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = softmax(a3)
    return y

x, t = get_data()
network = init_network()
accuracy_cnt = 0
for i in range(len(x)):
    y = predict(network, x[i])
    p= np.argmax(y) # 获取概率最高的元素的索引
    if p == t[i]:
        accuracy_cnt += 1
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))

可以用np.argmax(x)函数取出数组中的最大值的索引(np.argmax(x)将获取被赋给参数x的数组中的最大值元素的索引)

将normalize设置成True后,函数内部会进行转换,将图像的各个像素值除以255,使得数据的值在0.0~1.0 的范围内。像这样把数据限定到某个范围内的处理称为正规化(normalization)

对神经网络的输入数据进行某种既定的转换称为预处理(pre-processing)

[!IMPORTANT]

预处理在神经网络(深度学习)中非常实用,其有效性已在提高识别性能和学习的效率等众多实验中得到证明。

实际上,很多预处理都会考虑到数据的整体分布。比如,利用数据整体的均值或标准差,移动数据,使数据整体以0 为中心分布,或者进行正规化,把数据的延展控制在一定范围内。除此之外,还有将数据整体的分布形状均匀化的方法,即数据白化(whitening)等。

批处理

image-20240714145413687

image-20240714145421964

打包式的输入数据称为批(batch),批有“捆”的意思,图像就如同纸币一样扎成一捆。

[!IMPORTANT]

批处理对计算机的运算大有利处,可以大幅缩短每张图像的处理时间。

大多数处理数值计算的库都进行了能够高效处理大型数组运算的最优化。并且,在神经网络的运算中,当数据传送成为瓶颈时,批处理可以减轻数据总线的负荷(严格地讲,相对于数据读入,可以将更多的时间用在计算上)。也就是说,批处理一次性计算大型数组要比分开逐步计算各个小型数组速度更快

x, t = get_data()
network = init_network()
batch_size = 100 # 批数量
accuracy_cnt = 0
for i in range(0, len(x), batch_size):
    x_batch = x[i:i+batch_size]
    y_batch = predict(network, x_batch)
    p = np.argmax(y_batch, axis=1)
    accuracy_cnt += np.sum(p == t[i:i+batch_size])
    print("Accuracy:" + str(float(accuracy_cnt) / len(x)))

像range(start, end, step)这样指定3 个整数,则生成的列表中的下一个元素会增加step指定的值。

通过argmax()获取值最大的元素的索引。不过这里需要注意的是,我们给定了参数axis=1。这指定了在100 × 10 的数组中,沿着第1 维方向(以第1 维为轴)找到值最大的元素的索引(第0 维对应第1 个维度)

矩阵的第0 维是列方向,第1 维是行方向

使用批处理,可以实现高速且高效的运算

回顾总结

  • 神经网络中的激活函数使用平滑变化的sigmoid 函数或ReLU函数。
  • 通过巧妙地使用NumPy多维数组,可以高效地实现神经网络。
  • 机器学习的问题大体上可以分为回归问题和分类问题。
  • 关于输出层的激活函数,回归问题中一般用恒等函数,分类问题中一般用softmax 函数。
  • 分类问题中,输出层的神经元的数量设置为要分类的类别数。
  • 输入数据的集合称为批。通过以批为单位进行推理处理,能够实现高速的运算。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

redis基本类型和订阅

redis-cli -h <host> -p <port> -a <password> 其中&#xff0c;< host>是Redis服务器的主机名或IP地址&#xff0c;< port>是Redis服务器的端口号&#xff0c;< password>是Redis服务器的密码&#xff08;如果有的话&#xff09;。 set …

多模态大模型--音频文本

音频信息 声学 音频编解码技术的目标是&#xff0c;通过减少音频文件的大小来节省存储空间或减轻网络传输的负担。理想的情况下&#xff0c;即使音频被压缩&#xff0c;我们听到的声音与原版也应该没有任何区别。 Opus是一个多才多艺的音频编解码器&#xff0c;它适用于各种应…

Linux系统之快速部署小游戏合集网站(二)

Linux系统之快速部署小游戏合集网站(二) 一、项目介绍1.1 项目简介1.2 项目预览二、本次实践介绍2.1 本地环境规划2.2 本次实践介绍三、检查本地环境3.1 检查系统版本3.2 检查系统内核版本3.3 检查软件源四、安装Apache24.1 安装Apache2软件4.2 启动apache2服务4.3 查看apach…

FPGA-Verilog

这里写目录标题 累加累乘器 累加累乘器 timescale 1ns/10psmodule inout_test(); parameter ratio 2; reg [15:0]num ; reg [31:0]save_add_v; reg [31:0]save_multi_v;initialbeginsave_add_v 100;save_multi_v 100;forever beginsave_add_v save_add_v ratio;save_mul…

基于视觉工具箱和背景差法的行人检测,行走轨迹跟踪,人员行走习惯统计matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 在三维图中&#xff0c;幅度越大&#xff0c;则表示人员更习惯的行走路线。 2.算法运行软件版本 matlab2022a 3.部分核…

[笔记]Fluke3563 振动分析仪

参考文档&#xff1a;Fluke 3563 Analysis Vibration Sensor system | Fluke 1.四大机械故障损伤原因 2.振动特征 福禄克做的示意图很棒&#xff1a; 不平衡对应转动轴的一倍频&#xff0c;不对中是2倍频&#xff0c;然后3~6倍频会有未紧固故障&#xff0c;更高频的位置是齿轮…

新版网页无插件H.265播放器EasyPlayer.js如何测试demo视频?

H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff1b;支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#xff0…

解决 Vscode不支持c++11的语法

问题&#xff1a; 解决方案&#xff1a; 1、按 CtrlShiftP 调出命令面板&#xff0c;输入 C/C: Edit Configurations (UI) 并选择它。这将打开 C/C 配置界面 2、打开 c_cpp_properties.json 文件 3、编辑 c_cpp_properties.json 4、保存 c_cpp_properties.json 文件。 关闭并…

ollama + fastgpt 搭建免费本地知识库

目录 1、ollama ollama的一些操作命令: 使用的方式: 2、fastgpt 快速部署: 修改配置: config.json: docker-compose.yml: 运行fastgpt: 访问OneApi: 添加令牌和渠道: 登陆fastgpt,创建知识库和应用 3、总结: 附录: 1. 11434是ollama的端口: 2. m3e 测…

设计模式-概述*

1.代码的质量的评判 可维护性&#xff1a;不破坏原有代码设计以及不引入新的bug的前提下&#xff0c;能够快速修改或新增代码&#xff1b;可读性&#xff1a;人类能理解的代码&#xff08;编程规范-命名、函数是否冗长、类是否过大等&#xff09;&#xff1b;可扩展性&#xff…

【Java】:浅克隆和深克隆

克隆 克隆和赋值 克隆的结果是有多个相同的实体&#xff0c;各个对象指向不同的实体而多个不同对象指向一个相同的实体不是克隆&#xff0c;而是赋值 克隆的过程 首先实例化一个 student1 对象 在堆里开辟了一块内存用来存储 age 10 这个数据 调用 clone 方法 在堆中又开辟了一…

数字化转型“破局”:低代码开发平台如何缩短开发交付周期,提升效率

日新月异的数字时代&#xff0c;各行业正经历着前所未有的变革与转型。随着大数据、云计算、人工智能等技术的不断成熟与融合&#xff0c;数字化转型的步伐愈发坚定而迅速&#xff0c;成为企业转型升级、实现可持续发展的必由之路。然而&#xff0c;传统的软件开发模式受限于高…

Hadoop3:HDFS-存储优化之纠删码

一、集群环境 集群一共5个节点&#xff0c;102/103/104/105/106 二、纠删码原理 1、简介 HDFS默认情况下&#xff0c;一个文件有3个副本&#xff0c;这样提高了数据的可靠性&#xff0c;但也带来了2倍的冗余开销。Hadoop3.x引入了纠删码&#xff0c;采用计算的方式&#x…

【学习】美国虚拟信用卡申请流程

WildCard 官方网址&#xff1a;https://bewildcard.com/i/PEACEFUL &#xff08;使用邀请码“PEACEFUL”可以享受开卡88 折优惠&#xff0c;注册时提示填写邀请码就可以填写&#xff09;

Window中 Redis下载安装

Redis7.2.3连接&#xff1a; 我用夸克网盘分享了「redis-windows-7.2.3.zip」&#xff0c;点击链接即可保存。打开「夸克APP」&#xff0c;无需下载在线播放视频&#xff0c;畅享原画5倍速&#xff0c;支持电视投屏。 链接&#xff1a;https://pan.quark.cn/s/4dfb0497707a 在安…

驱动框架——CMSIS第一部分 RTE驱动框架介绍

一、介绍CMISIS 什么是CMSIS&#xff08;cortex microcontrol software interface standard一种软件标准接口&#xff09;&#xff0c;官网地址&#xff1a;https://arm-software.github.io/CMSIS_6/latest/General/index.html 包含的core、driver、RTOS、dsp、nn等部分&…

蓝桥 双周赛算法赛【小白场】

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;IT竞赛 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 蓝桥第14场小白入门赛T1/T2/T3 题目&#xff1a; T1照常还是送分题无需多…

cesium 实现地图环境功能 - 雨,雪,雾特效

需求背景解决效果Codeindex.vuefogEffect.tsrain.glslsnow.glslfog.glsl 需求背景 需要实现天气模拟&#xff0c;日照模拟功能&#xff0c;提高三维实景效果 解决效果 Code 注意&#xff1a;我以下glsl文件时基于 webgl1.0&#xff0c;即cesium&#xff0c;创建球的时候&…

基于单片机STC89C52和GSM实现的远程拨号开锁设计(含文档、源码与proteus仿真,以及系统详细介绍)

本篇文章论述的是基于单片机STC89C52和GSM实现的远程拨号开锁设计的详情介绍&#xff0c;如果对您有帮助的话&#xff0c;还请关注一下哦&#xff0c;如果有资源方面的需要可以联系我。 目录 摘要 仿真图 单片机系统流程图 实物图 代码 系统论文 资源下载 摘要 本文介…

在 Windows 上开发.NET MAUI 应用_2.生成你的第一个应用

先决条件 Visual Studio 2022 17.8 或更高版本&#xff0c;并安装了 .NET Multi-platform App UI 工作负载。 可参考上一篇文章&#xff1a;http://t.csdnimg.cn/n38Yy 创建应用 1.启动 Visual Studio 2022。 在开始窗口中&#xff0c;单击“创建新项目”以创建新项目&#…