《深度学习入门:基于Python的理论与实现》

感知机

感知机接收多个输入信号,输出一个信号。下图是一个接收两个输入信号的感知机的例子。

感知机

上述内容用数学公式表达:

式2.1

其中,w - 权重,x - 输入信号,theta - 阀值


导入权重与偏置

将theta换为 -b

式2.2

b: 偏置,调整神经元被激活的容易程度
w: 控制输入信号重要程度的参数。

(y = wx + b)


激活函数

将输入信号的总和转换为输出信号,这种函数被称为激活函数。
常用的激活函数:

  • 阶跃函数
  • sigmoid函数
  • ReLU函数(Rectified Linear Unit)

sigmoid函数

式3.6

exp(-x)表示以e为底,-x作为自变量的函数。对应的py实现:

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

ReLU函数

式3.7

对应的py实现:

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

输出层的设计

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

softmax函数

softmax函数将输入值进行正规化处理后再输出。
式3.10

exp(x) 是表示以e为底,x为变量的指数函数。a表示输入信号。

针对溢出问题改进的softmax函数

式3.11

这里的 C‘可以使用任何值,但是为了防止溢出,一般会使用输入信号中的最大值。对应的py实现:

1
2
3
4
5
6
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

损失函数

表示神经网络性能的“恶劣程度”的指标,即当前的
神经网络对监督数据在多大程度上不拟合,在多大程度上不一致。给损失函数乘上一个负值,就可以解释为“在多大程度上不坏”,
即“性能有多好”。这个损失函数可以使用任意函数,
但一般用均方误差和交叉熵误差等。

均方误差

式4.1

这里,y 是表示神经网络的输出,t 表示监督数据,k 表示数据的维数。对应的py实现:

1
2
def mean_squared_error(y, t):
return 0.5 * np.sum((y-t)**2)

将正确解标签表示为 1,其他标签表示为 0 的表示方法称为 one-hot 表示。

交叉熵误差

式4.2

这里,log 表示以 e 为底数的自然对数。当正确解标签为one-hot表示时,式(4.2)实际上只计算对应正确解标签的输出的自然对数。对应的py实现:

1
2
3
def cross_entropy_error(y, t):
delta = 1e-7
return -np.sum(t * np.log(y + delta))

梯度

由全部变量的偏导数汇总而成的向量称为**梯度(gradient)**。梯度表示的是各点处的函数值减小最多的方向。(表示损失函数的值减小的最多方向)。对应的py实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def numerical_gradient(f, x):
h = 1e-4 # 0.0001
grad = np.zeros_like(x) # 生成和 x 形状相同的数组

for idx in range(x.size):
tmp_val = x[idx]

# f(x+h) 的计算
x[idx] = tmp_val + h
fxh1 = f(x)

# f(x-h) 的计算
x[idx] = tmp_val - h
fxh2 = f(x)

grad[idx] = (fxh1 - fxh2) / (2*h)
x[idx] = tmp_val # 还原值
return grad

梯度法:断地沿梯度方向前进,逐渐减小函数值的过程。

式(4.7)是表示更新一次的式子,这个步骤会反复执行。也就是说,每
一步都按式(4.7)更新变量的值,通过反复执行此步骤,逐渐减小函数值。

用数学形式表示梯度法:

式4.7

η 表示更新量,在神经网络的学习中,称为学习率。学习率决定在一次学习中,应该学习多少,以及在多大程度上更新参数。

学习率需要事先确定为某个值,比如 0.01 或 0.001。一般而言,这个值
过大或过小,都无法抵达一个“好的位置”。在神经网络的学习中,一般会
一边改变学习率的值,一边确认学习是否正确进行了。
梯度下降法的py实现:

1
2
3
4
5
6
7
8
def gradient_descent(f, init_x, lr=0.01, step_num=100):
x = init_x

for i in range(step_num):
grad = numerical_gradient(f, x)
x -= lr * grad

return x

参数 f 是要进行最优化的函数, init_x 是初始值, lr 是学习率 learning rate, step_num 是梯度法的重复次数。 numerical_gradient(f,x) 会求函数的梯度,用该梯度乘以学习率得到的值进行更新操作,由 step_num 指定重复的次数。


卷积神经网络(Convolutional Neural Network)

CNN与之前介绍的神经网络一样,不过新出现了卷积层(Convolution层)和池化层(Pooling层)。CNN的一个例子,如下图所示。

图7-2

卷积运算

卷积层进行的处理就是卷积运算。卷积运算相当于图像处理中的“滤波器运算”。

图7-3

假设用(height,width)表示数据和滤波器的形状,则在本例中,输入大小是(4,4),滤波器大小是(3,3),输出大小是(2,2)。

图7-4展示了卷积运算的计算顺序。对于输入数据,卷积运算以一定间隔滑动滤波器的窗口并应用。这里所说的窗口是指图7-4中灰色的3x3的部分。如图7-4所示,将各个位置上滤波器的元素和输入的对应元素相乘,然后再求和(有时将其称为乘积累加运算)。然后,将这个结果保存到输出的对应位置。将这个过程在所有位置都进行一遍,就可以得到卷积运算的输出。

图7-4 卷积的运算顺序

在全连接的神经网络中,除了权重参数,还存在偏置。CNN中,滤波器的参数就对应之前的权重。并且,CNN中也存在偏置。图7-3的卷积运算的例子一直展示到了应用滤波器的阶段。包含偏置的卷积运算的处理流程如图7-5所示。

图7-5 卷积运算的偏置,这个值会被加到应用了滤波器的所有元素上。

填充

在进行卷积层的处理之前,有时要向输入数据的周围填入固定的数据(比如0等),这称为填充(padding),是卷积运算中经常会用到的处理。比如,在图7-6的例子中,对大小(4,4)的输入数据应用了幅度为1的填充。“幅度为1的填充”是指用幅度为1像素的0填充周围。

图7-6 卷积运算的的填充处理的输出数据。使用填充主要是为了调整输出的大小。

步幅

应用滤波器的位置间隔称为步幅(stride)。上例的步幅为1,如果将步幅设为2,则如图7-7所示,应用滤波器的窗口的间隔变为2个元素。

图7-7 步幅为2的卷积运算的例子。像这样,步幅可以指定应用滤波器的间隔。

综上,增大步幅后,输出大小会变小。而增大填充后,输出大小会变大。

这里,假设输入大小为(H,W),滤波器大小为(FH,FW),输出大小为(OH,OW),填充为P,步幅为S。此时,输出大小可通过式(7.1)进行计算。

式7-1分别可以除尽。当输出大小无法除尽时,需要采取报错等对策。

3维数据的卷积运算

之前的卷积运算的例子都是以有高、长方向的2维形状为对象的。但是,图像是3维数据,除了高、长方向之外,还需要处理通道方向。这里,我们按照与之前相同的顺序,看一下对加上了通道方向的3维数据进行卷积运算的例子,图7-8所示,计算顺序如图7-9所示。

图7-8 3维卷积运算

图7-9 3维卷积运算的顺序

需要注意的是,在3维数据的卷积运算中,输入数据和滤波器的通道数要设为相同的值。滤波器大小可以设定为任意值(不过,每个通道的滤波器大小要全部相同)。

池化层

池化是缩小高、长方向上的空间的运算。比如,如图7-14所示,进行将2x2的区域集约成1个元素的处理,缩小空间大小。

图7-14 3维卷积运算的顺序
图7-14的例子是按步幅2进行2x2的Max池化时的处理顺序。“Max池化”是获取最大值的运算,“2x2”表示目标区域的大小。

池化层的特征

  • 没有要学习的参数。池化只是从目标区域中取最大值或平均值。
  • 通道数不发生变化。经过池化运算,输入数据和输出数据的通道数不会发生变化。
  • 对微小的位置变化具有鲁棒性。数据发生微小的偏差时,池化仍会返回相同的结果。

《深度学习入门:基于Python的理论与实现》

http://example.com/2019/05/13/deepLearningNoteBasePy/

作者

bd160jbgm

发布于

2019-05-13

更新于

2021-05-08

许可协议