《Python深度学习》读书笔记(三)

2.2 神经网络的数据表示

2.2.1 常用的数据切片

神经网络中最常用数据切片,比如在卷积神经网络时我们会用到滑动窗口进行目标检测,截取图片部分区域:

以MNIST数据集为例,假如此时已经将图片数据导入成功:

1. 截取图片右下角区域图片:
在这里插入图片描述

my_slice = train_images[:, 14:, 14:]
print(my_slice.shape)

输出结果:

# 此时输出的图片是原图右下角区域
(60000,14,14)

2. 截取图中间区域图片:
在这里插入图片描述

my_slice = train_images[:, 7:-7, 7:-7]
print(my_slice.shape)

输出结果:

# 此时输出的图片是中间区域的图片
(60000,14,14)

2.2.2 常用的数据张量形式

在这里插入图片描述

  • 向量数据有两个轴,第一个轴表示多少个样本,第二个轴表示有多少个特征变量
    在这里插入图片描述
  • 时间序列数据有三个轴,第一个轴表示多少个样本,第二个轴表示时间段,第三个轴表示多少个特征变量,可以理解成后面两个轴表示一个矩阵,举例如(10000,280,128)表示一篇推文有280个字元,每个字元对应一个ASCII码,组成一个矩阵,然后有10000个这样的推文矩阵堆叠起来的三维张量
    在这里插入图片描述
  • 图像数据有四个轴,第一个轴表示样本数列,第二、三个轴表示图片的长度和宽度,第四个轴表示通道数,如(128,256,256,3)彩色图片为RGB三原色,表示有三个256*256的矩阵堆叠起来成了一张彩色图片,这样的彩色图片有128张
  • 视频数据里frames为帧数,意味着在一分钟取了多少张彩色图片,举例(4,240,144,256,3)表示一秒钟取4张图片时,视频一分钟的帧数为240,图片是彩色的144*256像素,这里样本含有4个视频。

2.3 神经网络的“齿轮”:张量运算

2.3.1 逐元素运算

在这里插入图片描述
以上只展示乘法,对于加减乘除一样逐元素运算。

2.3.2 广播

1. 第一个例子:

在这里插入图片描述
如上图所示数据,解释一下广播的过程,思路是缺少哪一个轴就补哪一个轴,比如此处先补第一个轴,就是将①里黑色框框部分复制一份同样的内容,第二步补第二个轴,对第一个红色大框框的内容按照②复制两份同样的内容就完成广播:
在这里插入图片描述

2. 第二个例子
在这里插入图片描述
此处缺第0轴,所以自动对第0轴进行广播

扫描二维码关注公众号,回复: 10560616 查看本文章

2.3.3 矩阵和向量相乘

在这里插入图片描述
此时电脑会把这个矩阵的每一个行,和这个向量做内积得到两个数,结果还是1维的:
在这里插入图片描述

2.3.4 高级一点的

  • 四维张量乘以二维张量: 理解成有b个cd的矩阵组成如下红色框框,然后这样的红色框框有a个,与de的矩阵相乘,两个矩阵相乘的维度是c*e,但是对外围维度的描述不变
    在这里插入图片描述
  • 四维张量乘以一维张量: 理解成一个cd的矩阵与一个d1的矩阵相乘,乘出来是一个c*1的矩阵,但是具体的矩阵与向量乘的结果根据上面讲的理解来,它实际是一个横着的向量,所以最后的维度是(c,),然后前面关于维度的描述同上一个例子
    在这里插入图片描述

2.3.3 reshap操作

  • 高维度的转置: 将它轴的位置逆序即可
    在这里插入图片描述
    最后得到z的结果是:
    在这里插入图片描述
    那么具体怎么理解得到这个矩阵怎么来的呢,如下,紫色表示与y对应的矩阵位置相比,两个轴做交换对应原y矩阵里的元素填在此处:
    在这里插入图片描述
    通常我们在使用时不会做上面那种操作,会指定某些轴进行变动,此处指定第0轴不变,只是转置了两个矩阵:
    在这里插入图片描述

2.4 神经网络的“引擎”:基于梯度的优化

2.4.1 神经网络的基本结构

在这里插入图片描述
引入梯度下降来优化参数,个人感觉梯度下降是跟牛顿法类似的,其实牛顿法是求函数解的一个数值方法,具体如下,此时竖轴是y,横轴是x,我们要找到函数值等于0的点,此时随机找到一个点x0,在这个点做斜率,求出方程,然后将这条斜率延伸交于x轴于x1,令y=0就可以得到x1的坐标,继续找到x1点斜率做同样的操作,此时x点就渐渐的向函数值等于0的点靠近了:
在这里插入图片描述
然后引出它和梯度下降的关系,此时若把竖轴改成 f’(x) ,问题编程求 f’(x) 等于0的点就像是我们在求一个优化函数梯度等于0的点,所以x1的坐标公式就转化为:
在这里插入图片描述此时牛顿法做的事就变成了,给定一个x0点,由程序操作x0减去一个二阶分之一的东西乘以那一点的斜率就可以得到新的x1,然后重复,就能得到梯度等于0的点,但是在深度学习的神经网络中求参数的二阶导是不现实的,计算量太大,所以它就变换成我们梯度下降最原始概念里的学习率。

  • 学习率太大,全局最小点可能会震荡甚至发散
  • 学习率太小,找到全局最小点的速率太慢

这里就引申出来各种优化器,最简单的是我们想要离全局最小点远的时候学习速率快,离全局最小点近了学习速率就降低,以免冲过头了错过全局最小点,所以这里仅仅靠普通的迭代就不太行,它可能会卡在某个鞍点局部最小点
在这里插入图片描述
这个时候我们可以想想,不仅仅只考虑它的梯度,还能不能加上动量,如下面一种情况,球在下降的时候是具有动量的,假如不考虑动量,求可能卡在局部最小点的区间来回波动,但是如果考虑了小球的动量,这个小球就有可能冲过局部最小点,脱离平坦的位置,然后就能找到全局最小点:
在这里插入图片描述
常用的两个优化器:

  • RMSprop,考虑了梯度,它的学习速率是把过去梯度平方然后做指数加权平均,但没有考虑动量
  • Adam,动量和梯度都考虑到

详细对于各种梯度下降算法的比较(超赞的论文)

2.4.2 简单测试一下梯度下降

import numpy as np
import matplotplot.pyplot as plt

# 定义一个函数
def fn(x):
	fn = x ** 2
	return fn

# 差分法求斜率
def derivate(x):
	h = 0.001
	derivate = (fn(x+h) - fn(x-h))
	return derivate
	
eta = 0.001 #学习率
num_iterate = 2000 #迭代次数

x = 2
x_value = [x]
fn_value = [fn(x)]

for i in range(num_iterate):
	x -= eta * (derivate(x))
	x_value.append(x)
	fn_value.append(fn(x))

# 因为不确定梯度下降后,y的值会变大还是变小,所以进行下面操作
y = np.max(np.abs(x_value))
z = np.linspace(-y, y, num_iterate)

# 画图
plt.plot(x_value, fn_value, "bo")
plt.plot(z, fn(z), "r")
plt.xlabel('x')
plt.ylabel('Function Value')
plt.show()

上述程序下的学习率和迭代次数更新出来的结果如下:
在这里插入图片描述
如果学习速率修改为1时:
在这里插入图片描述
如果修改学习率为1.1,它就会发散:
在这里插入图片描述
喜欢的可以点赞吼~

发布了22 篇原创文章 · 获赞 5 · 访问量 482

猜你喜欢

转载自blog.csdn.net/RedValkyrie/article/details/105094676
今日推荐