《深度学习入门:基于Python的理论与实现》第三章笔记

在这里插入图片描述

1、 神经网络的引入

1.1 神经网络与感知机的联系

 最简单的例子:左边一列为输入层,第二层为中间层(由于中间层是外部不可视的,因此也可以称为隐藏层),最右边则为输出层。在这本书中,作者把含有权重的层数来表示网络的层数(下图所示则为2层网络)。
在这里插入图片描述
 在这里,作者以第二章中的感知机为例子,写出朴素感知机处理的数学表达式如下:
在这里插入图片描述
 根据等式,可以将式子变得更为简单,这也引出了激活函数的概念。
在这里插入图片描述
在这里插入图片描述

1.2 激活函数的引入

 上述的h(x)函数会将输入信号的总和转换为输出信号,这种函数一般称为激活函数。具体而言,其作用在于决定如何来激活输入信号的总和。
 公式3.2 可以转换为如图所示的过程。
在这里插入图片描述

2、激活函数的介绍

 先提一个点,激活函数是连接感知机和神经网络的桥梁,在这里为了后续的区分引入书中的一小段话。
在这里插入图片描述

2.1 阶跃函数

2.1.1 阶跃函数的定义

式(3.3)表示的激活函数以阈值为界,一旦输入超过阈值,就切换输出,这样的函数称为“阶跃函数”。

2.1.2 阶跃函数的实现

实现其实也比较简单,就是超过某个阈值就改变输出即可。

import numpy as np
import matplotlib.pylab as plt

# 阶跃函数:超过某个阈值就改变输出
def step_function(x):
    y = x > 0
    return y.astype(np.int)

x = np.arange(-5.0,5.0,0.1)
y = step_function(x)
plt.plot(x,y)
plt.ylim(-0.1,1.1)
plt.show()

在这里插入图片描述

2.2 sigmoid函数

2.2.1 sigmoid函数的定义

 sigmoid函数是深度学习常用的函数,公式如下所示:
在这里插入图片描述

2.2.2 sigmoid函数的实现

 实现其实也比较简单,就是超过某个阈值就改变输出即可。

def sigmoid(x):
    return 1 / (1 + np.exp(-x))
x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1) # 指定y轴的范围
plt.show()

在这里插入图片描述

2.3 sigmoid函数和阶跃函数的异同

2.3.1 平滑性上的区别

 sigmoid函数是一条平滑的曲线,输出随着输入发生连续性的变化。而阶跃函数以0为界,输出发生急剧性的变化。sigmoid函数的平滑性对神经网络的学习具有重要意义。
在这里插入图片描述

2.3.2 输出信号上的区别

 另一个不同点是,相对于阶跃函数只能返回0或1,sigmoid函数可以返回0.731 …、0.880 …等实数(这一点和刚才的平滑性有关)。也就是说,感知机中神经元之间流动的是0或1的二元信号,而神经网络中流动的是连续的实数值信号。

2.3.3 两者之间的共同点

 当输入信号为重要信息时,阶跃函数和sigmoid函数都会输出较大的值;当输入信号为不重要的信息时,两者都输出较小的值。还有一个共同点是,不管输入信号有多小,或者有多大,输出信号的值都在0到1之间。

2.4 ReLU函数

2.4.1 ReLU函数的定义

 ReLU函数在输入大于0的时候直接输出该值,在输出小于等于0的时候输出0,可以写成如下所示的公式:
在这里插入图片描述

2.4.2 ReLU函数的实现

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

在这里插入图片描述

3、3层神经网络的实现

3.1 目标展示及前置条件

 书中以下图为例的例子,并以此为基础展开后续的实现
在这里插入图片描述
在这里插入图片描述

3.2 各层之间信号的传递

在这里插入图片描述

3.2.1 输入层到第一层之间的传递

 输入层到第一层之间的传递的传递过程如下所示:
在这里插入图片描述
 可以写成数学式如下:
在这里插入图片描述
 可以转换成矩阵计算如下:
在这里插入图片描述
 在计算出矩阵运算的结果后,还要进行一次激活函数的处理
在这里插入图片描述

 代码如下:

# 输入层到第1层的传递
X = np.array([1.0, 0.5])
W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
B1 = np.array([0.1, 0.2, 0.3])
A1 = np.dot(X,W1) + B1
Z1 = sigmoid(A1)

3.2.2 第一层到第二层之间的传递

 其实也就是把输入换成了z1,其他的都大同小异。
在这里插入图片描述

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(A2)
Z2

3.2.3 第二层到输出层之间的传递

在这里插入图片描述
 其实跟上述一样,最后书中的例子是使用了恒等函数,即直接输出结果,由于要保持步骤的一致,所以特地加上了定义函数这一步。

def identity_function(x):
 return x
W3 = np.array([[0.1, 0.3], [0.2, 0.4]])
B3 = np.array([0.1, 0.2])
A3 = np.dot(Z2, W3) + B3
Y = identity_function(A3) # 或者Y = A3

3.3 代码实现的整理

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]

3.4 关于输出层的设计

3.4.1 激活函数使用的条件

在这里插入图片描述
 神经网络可以用在分类问题和回归问题上,不过需要根据情况改变输出层的激活函数。一般而言,回归问题用恒等函数,分类问题用softmax函数。
在这里插入图片描述

3.4.2 实现 softmax函数时的注意事项

 由于计算机在处理计算会出现溢出的问题,所以需要对softmax函数进行改进
在这里插入图片描述
 根据式子,可以发现C’的值无论取什么,都是可以满足计算的条件的,因此,可以通过减去输入信号中的最大值,让计算机在运算时不会出现值的溢出。

# softmax函数
def softmax(a):
    c = np.max(a)
    exp_a = np.exp(a - c)
    exp_sum_a = np.sum(exp_a)
    y = exp_a / exp_sum_a
    return y

 以0.3,2.9,4.0为例,可以计算得到如下的结果:
在这里插入图片描述

 softmax函数的输出是0.0到1.0之间的实数。并且,softmax函数的输出值的总和是1。输出总和为1是softmax函数的一个重要性质。正因为有了这个性质,我们可以把softmax函数的输出解释为“概率”。

 比如,上面的例子可以解释成y[0]的概率是0.018(1.8 %),y[1]的概率是0.245(24.5 %),y[2]的概率是0.737(73.7 %)。从概率的结果来看,可以说“因为第2个元素的概率最高,所以答案是第2个类别”。

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

3.4.3 输出层神经元的数量的设计

 输出层的神经元数量需要根据待解决的问题来决定。对于分类问题,输出层的神经元数量一般设定为类别的数量。比如,对于某个输入图像,预测是图中的数字0到9中的哪一个的问题(10类别分类问题),可以像图3-23这样,将输出层的神经元设定为10个。
在这里插入图片描述

4、其他的小结

4.1 训练中的概念

在这里插入图片描述
在这里插入图片描述

4.2 批处理的作用

 单个数据的处理如下:
在这里插入图片描述
 而多个数据如果同时的处理,公式会如下所示:

在这里插入图片描述
 因此,批处理可以大幅缩短数据的处理时间。

4.3 小结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值