机器学习|吴恩达机器学习之神经网络

多类分类问题

就是把多个类别细分为多个0-1类别来分析

AW3v7T.png

代码:

导入与处理数据

1.导入模块

1
2
3
4
5
6
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import loadmat
from scipy.optimize import minimize

import Sigmoid

2.导入数据

因为图像的灰度值是用.mat存储的,所以用loadmat来导入到python

1
2
3
4
5
6
# 5000个训练样本,每个样本20*20的灰度值,展开为400维向量。输出为0~9的数字
def load_data(path):
data=loadmat(path)
X=data['X']
y=data['y']
return X,y

3.可以随机显示一张图片来观察

1
2
3
4
5
6
7
8
9
def plot_an_image(X,y):
pick_one=np.random.randint(0,5000)
image=X[pick_one,:]
fig,ax=plt.subplots(figsize=(1,1))
ax.matshow(image.reshape(20,20),cmap='gray_r')
plt.xticks([])
plt.yticks([])
plt.show()
print('this should be {}'.format(y[pick_one]))

结果如图:

AWG3RJ.png

代价函数

正则化项逻辑回归,和之前的没区别

1
2
3
4
5
def cost_reg(theta,X,y,lmd):
theta_reg=theta[1:]
first=y*np.log(Sigmoid.sigmoid(X@theta))+(1-y)*np.log(1-Sigmoid.sigmoid(X@theta))
reg=(lmd/(2*len(X)))*(theta_reg@theta_reg)# 惩罚项不从第一项开始
return -np.mean(first)+reg

梯度函数

和之前的没区别,只不过这里用了np.concatenate()来拼接。

1
2
3
4
5
def gradient_reg(theta,X,y,lmd):
theta_reg=theta[1:]
first=(1/len(X))*(X.T@(Sigmoid.sigmoid(X@theta)-y))
reg=np.concatenate([np.array([0]),(lmd/len(X))*theta_reg])
return first+reg

one vs all

每次循环都求出0~9中任一数字的$\theta$值(将该数字和其他数字二分类),最后拼接成一个矩阵。

1
2
3
4
5
6
7
8
9
10
11
12
13
def one_vs_all(X,y,lmd,K):
all_theta=np.zeros((K,X.shape[1]))

for i in range(1,K+1):
theta=np.zeros(X.shape[1])
y_i=np.array([1 if label==i else 0 for label in y])

ret=minimize(fun=cost_reg,x0=theta,args=(X,y_i,lmd),method='TNC',
jac=gradient_reg,options={'disp':True})

all_theta[i-1,:]=ret.x

return all_theta

计算精确度

1
2
3
4
5
6
7
8
9
10
11
12
'''
计算精确度

返回值
h_argmax是一个存放预测数字的一维ndarray
'''
def predict_all(X, all_theta):
h = Sigmoid.sigmoid(X @ all_theta.T)
# 返回指定方向上的最大值的索引 axis=0:按列索引,axis=1:按行索引
h_argmax = np.argmax(h, axis=1)
h_argmax = h_argmax + 1
return h_argmax

main函数

1
2
3
4
5
6
7
8
def main():
X, y = load_data('ex3data1.mat')
plot_an_image(X,y)
X = np.insert(X, 0, 1, axis=1)
y = y.flatten()
all_theta = one_vs_all(X, y, 1, 10)
y_pred = predict_all(X, all_theta)
accuracy = np.mean(y_pred == y) # 精确度94.46%

神经网络

原理

模仿人类大脑的神经元:

AW01J0.md.png

进一步设计出神经网络:

AW0JQU.md.png

代码

这个实验是神经网络的正向传播过程,不涉及如何训练。

导入模块

1
2
3
4
from scipy.io import loadmat
import numpy as np
import Sigmoid
import multiClassClassification as mc

导入数据

这里的权重已经给出,导入即可

1
2
3
4
def load_weigth(path):
data=loadmat(path)
# Theta1是输入层和隐藏层之间的参数;Theta2是隐藏层和输出层之间的参数
return data['Theta1'],data['Theta2']

main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def main():
theta1, theta2 = load_weigth('ex3weights.mat')
X, y = mc.load_data('ex3data1.mat')
y = y.flatten()
X = np.insert(X, 0, values=np.ones(X.shape[0]), axis=1)

# 输入层到隐藏层
z2 = X @ theta1.T
z2 = np.insert(z2, 0, 1, axis=1)
# 隐藏层到输出层
a2 = Sigmoid.sigmoid(z2)

z3 = a2 @ theta2.T
a3 = Sigmoid.sigmoid(z3)

y_pred = np.argmax(a3, axis=1) + 1
accurcy = np.mean(y_pred == y) # 精确度97.52%

参考资料

正向传播的向量化实现

-------------End-------------
梦想总是要有的,万一有人有钱呢?