吴恩达机器学习系列课程:https://www.bilibili.com/video/BV164411b7dx
神经元模型

一个神经元就是一个函数,根据输入节点信息以及其权重,得到一个输出信息,即: 这里 .
注意:上图省略了 这一偏置项。
也称作激活函数,一般可以采取 函数 .
神经网络

神经网络是好几层的神经元连接在一起的集合。第一层被称作输入层,最后一层被称作输出层,中间其他层被称作隐藏层
注意:上图依旧省略了 偏置项。
我们把第 层到第 层的传导单独拿出来分析:设 表示第 层的神经元数量(不包含偏置项),那么对于第 层的第 个神经元,有一个 与之对应,使得:. 这里我用 表示加上偏置项后的 . 我们可以把这写作矩阵形式: 这里的 .
其他很多地方会把偏置项对应的参数向量 单独拿出来,把上面的式子写作类似于: 的形式。这里 . 我这里依旧沿用吴恩达教授的写法习惯。
神经网络实现门电路
通过这个例子能够直观地理解神经网络中参数的作用。
考虑一个输入层有 个神经元(不包括偏置项)且取值 、输出层有 个神经元且取值 的神经网络。如果我们将其参数设置为:,那么我们有:
输入1 |
输入 2 |
输出 |
0 |
0 |
|
0 |
1 |
|
1 |
0 |
|
1 |
1 |
|
于是我们实现了一个与门的功能!
类似的,我们可以实现或门、非门,然后组合使用与、或、非门,可以用多层神经网络实现异或、同或门等其他电路功能。
实现
这一节的作业依旧是对手写数字进行识别,但是不要求我们自己寻找参数 ,而是在 ex3weights.mat
中给出了。我们只需要根据神经网络的原理进行前向传播。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import numpy as np from scipy.io import loadmat import matplotlib.pyplot as plt import matplotlib
m = 5000 n = 401
data = loadmat('ex3data1.mat') X = data['X'] X = np.hstack((np.ones((m, 1)), X)) y = data['y']
data = loadmat('ex3weights.mat') Theta1 = data['Theta1'] Theta2 = data['Theta2']
def sigmoid(z): return 1 / (1 + np.exp(-z))
def predict(x): """ x: (401, ) """ a1 = x.reshape((401, 1)) a2 = np.matmul(Theta1, a1) a2 = sigmoid(a2) a2 = np.vstack((np.ones((1, 1)), a2)) a3 = np.matmul(Theta2, a2) a3 = sigmoid(a3) return a3.argmax(axis=0)[0] + 1
Sum = np.zeros(11) Hit = np.zeros(11) Accuracy = np.zeros(11) hit = 0 for id in range(5000): Sum[y[id][0]] += 1 if predict(X[id, :].T) == y[id][0]: Hit[y[id][0]] += 1 hit += 1 for i in range(1, 11): Accuracy[i] = Hit[i] / Sum[i] print(str(i)+":", str(Accuracy[i] * 100)+"%") print("tot:", str(hit / 5000 * 100)+"%")
PYTHON
|
各数字准确率和总准确率如下:
数字 |
准确率 |
1 |
98.2% |
2 |
97.0% |
3 |
96.0% |
4 |
96.8% |
5 |
98.4% |
6 |
98.6% |
7 |
97.0% |
8 |
98.2% |
9 |
95.8% |
0 |
99.2% |
Total |
97.52% |
注:直接采用训练集进行测试其实是不严谨的做法。