BP神经网络
哈尔滨工程大学-537
一、试验数据
在试验开始前必定要先导入所需要的python库,%matplotlib inline是为了使绘制的图形能够显示在浏览器上。
import numpy as np
import matplotlib.pyplot as plt
import random
%matplotlib inline
之后我们需要产生一些难以进行线性分类的数据集,这里直接copy斯坦福CS231n课程里的螺旋数据集,代码如下:
N = 100 # number of points per class
D = 2 # dimensionality
K = 3 # number of classes
X = np.zeros((N * K, D)) # data matrix (each row = single example)
y = np.zeros(N * K, dtype='uint8') # class labels
for j in range(K):
ix = list(range(N*j, N*(j + 1)))
r = np.linspace(0.0, 1, N) # radius
t = np.linspace(j*4, (j+1)*4, N) + np.random.randn(N)*0.2 # theta
X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
y[ix] = j
plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.gist_rainbow)
plt.show()
我认为没有必要纠结于这段代码里的具体内容,不然就偏离了主题,总之就是通过一些奇奇怪怪的函数来画出这么一个布满随机点的图形。
所绘制的图形如下图所示:
图中共有300个点,每一个点代表数据集中的一个样本点,横坐标和纵坐标分别作为样本的两个特征,样本点一共分为三种类型,红色、紫色和绿色。如果用矩阵来表示的话就应该是这样的:
样本点 | 特征1 | 特征2 | 类标签 |
---|---|---|---|
1 | -0.753 | -0.745 | 红色 |
2 | -0.754 | 0.501 | 紫色 |
3 | 0.752 | 0.258 | 绿色 |
… | … | … | … |
二、softmax线性分类器
在开始神经网络之前,先训练一个softmax线性分类器。
所谓softmax,举例来说,就是有三个数字,分别为3、4、7,如果取max,那么每次都会取到7,因为7永远是三个数里最大的,但是把它们softmax一下,就映射为三个概率0.27、0.28、0.45,这样取到7的概率最大,但是也有取到其他两个数的可能。这样,我们取的就不是max值,而是softmax值,没有取max值那么硬。
而这三个数字是如何通过softmax映射为三个概率值的,即softmax函数是什么样的,接下来会提到。
而既然是线性分类器,必然离不开经典的公式y=wx+by=wx+b。所以,就先初始化一下ww和 吧,代码如下:
# initialize parameters randomly
W = 0.01 * np.random.randn(D,K)
b = np.zeros((1,K))
这里的random库下的randn()函数是生成服从标准正态分布的随机数,这不同于生成在某一区间内均匀分布的随机数。生成D行K列,即2行3列。而偏置是1行3列的零向量。
权值ww和偏置
打印出来如下:
由于这是一个线性分类器,所以只需做简单的矩阵乘法,即可得到各个类别的分数。
# compute class scores for a linear classifier
scores = np.dot(X, W) + b
这里将300行2列的矩阵与2行3列的矩阵相乘,再加上偏置,得到300行3列的矩阵。每行代表一个样本点,共300个样本点,每列代表样本点对应各个类别的分数,共三个类别。
将score矩阵部分打印出来,如下图:
接下来的一个关键因素就是损失函数,我们需要用它来计算我们的损失,即预测结果和真实情况相差多少。在这里,我们希望正确的类别应该比其他类别有更高的分数,若确实如此,则损失应该很低,否则损失应该很高。量化这种直觉的方法有很多种,但在这个例子中我们可以使用与softmax分类器相关的交叉熵损失。公式如下:
公式其实比较直观,比如对某一个样本 i 预测,正确类别的概率值 prob(i)prob(i) 越大,损失就越小,反之其值越小,损失就越大。由于概率值在0和1之间,所以保证了 loglog 函数自变量的取值范围(斯坦福CS231n上面是如此写交叉熵的,可是和别的资料都不一样)。
将每个样本的损失累加在一起再除以样本个数,得到训练样本的平均交叉熵损失:1N∑iLi1N∑iLi
而完整的softmax分类器的损失则定义为:
公式后半部分为正则化损失,比如某个点的特征为[1, 1],而此时有两组不同的权重向量 w1w1 =[1, 0], w2w2 =[0.5, 0.5],与两组不同的权重分别做内积的结果相等,都为1。可是加上正则化损失项后,很明显 0.5∗0.5+0.5∗0.5<1∗10.5∗0.5+0.5∗0.5<1∗1 ,所以选择 w2w2 作为权重整体的损失更小。起作用在于增强泛化能力,去除权重的不确定性。
由之前得到的分数矩阵score,可以计算得到每个样本对应各个类别的概率值。这里就用到了之前所说的softmax,把三个数,通过softmax函数映射为归一化的三个概率,softmax公式如下:
例如:某个样本 i 对应各个类别的分值分别为(3, 3, 8),则该样本对应各个类别的概率值为 (e3