Python 3.7
所用数据集链接:前馈神经网络所用数据及权重(ex3data1.mat,ex3weights.mat),提取码:c3yy
Feedforward neural network
题目:仍然是上次手写数字识别的主题,这次用神经网络实现是为了展示神经网络相对于传统机器学习算法的强大,本次代码会非常简短(因为权重已经训练好了),在下一节中,我们将开始反向传播网络的设计,届时会从零开始书写。
1.0 Package
先导入相应包:
import numpy as np
# 矩阵处理
from scipy.io import loadmat
# 加载矩阵文件
1.1 Load data
下面读取数据,本次的数据和上次相同:
def load_data(path):
# 定义函数
data=loadmat(path)
# 读取path指向的矩阵文件
x=data['X']
y=data['y']
# 根据索引区分x,y
return data,x,y
data,x,y=load_data('ex3data1.mat')
print(x.shape) #(5000,400)
print(y.shape) #(5000,10)
# 此时x,y均为二维数组
1.2 Data preprocess
下面进行数据的预处理:
def data_preprocess(x,y):
# 定义函数,传入参数
x=np.insert(x,0,1,axis=1)
# 在x第一列加一列1,以便后续向量化
y=y.flatten()
# 将y展开成一维数组(后面会看到原因)
return x,y
x,y=data_preprocess(x,y)
print(x.shape) #(5000,401)
print(y.shape) # (5000,)
1.3 Load weights
下面加载权重,也就是训练好的 θ \theta θ 矩阵:
def load_weight(path):
# 定义函数,传入参数
data2=loadmat(path)
# 读取矩阵文件
theta1=data2['Theta1']
theta2=data2['Theta2']
# 根据索引区分theta1,theta2
# theta1就是第一层网络到第二层网络的参数矩阵
# theta2就是第二层网络到第三层网络的参数矩阵
return data2,theta1,theta2
data2,theta1,theta2=load_weight('ex3weights.mat')
print(theta1.shape) # (25,401)
print(theta2.shape) # (10,26)
1.4 Sigmoid fucntion
定义sigmoid函数:
def sigmoid(z):
return 1/(1+np.exp(-z))
1.5 Model predict
神经网络大概是上图的样子。其中a就是每一个神经元的激活值。
下面利用准备好的模型进行样本预测:
def model_computation(x,y,theta1,theta2):
# 定义函数,传入参数
a1=x
z2=x@theta1.T
a2=sigmoid(z2)
a2=np.insert(a2,0,1,axis=1)
z3=a2@theta2.T
g=sigmoid(z3)
return a1,z2,a2,z3,g
# 具体公式请看上图,每计算下一次z的时候,都需要在当前层的a加一列1,这是为了向量化,同时也是保证维数正确
a1,z2,a2,z3,g=model_computation(x,y,theta1,theta2)
1.6 Evalute model
下面看看模型的精度怎么样:
def evalute_model(y):
# 定义函数,传入参数
y_pred=np.argmax(g,axis=1)+1
# 选取g(也就是网络输出)中每一行最大的值对应的列数作为模型预测结果
# g是一个矩阵,5000行,10列,每一行是一个样本属于各个类的概率,选取最大的哪一个作为最终模型预测类型
accuracy=[1 if i==j else 0 for (i,j) in zip(y_pred,y)]
# 返回一个列表,列表中的元素1表示预测标签和真实标签相同,0表示不同
accuracy=sum(accuracy)/len(y)
# 精度
print('The accuracy of the model is:{}{}'.format(accuracy*100,'%'))
evalute_model(y)
输出如下:
事实上这么高的准确率,又没有防止过拟合的措施,我倒是认为这是过拟合了。
1.7 All
下面给出完整代码:
import numpy as np
from scipy.io import loadmat
def load_data(path):
data=loadmat(path)
x=data['X']
y=data['y']
return data,x,y
data,x,y=load_data('ex3data1.mat')
print(x.shape)
print(y.shape)
def data_preprocess(x,y):
x=np.insert(x,0,1,axis=1)
y=y.flatten()
return x,y
x,y=data_preprocess(x,y)
print(x.shape)
print(y.shape)
def load_weight(path):
data2=loadmat(path)
theta1=data2['Theta1']
theta2=data2['Theta2']
return data2,theta1,theta2
data2,theta1,theta2=load_weight('ex3weights.mat')
print(theta1.shape)
print(theta2.shape)
def sigmoid(z):
return 1/(1+np.exp(-z))
def model_computation(x,y,theta1,theta2):
a1=x
z2=x@theta1.T
a2=sigmoid(z2)
a2=np.insert(a2,0,1,axis=1)
z3=a2@theta2.T
g=sigmoid(z3)
return a1,z2,a2,z3,g
a1,z2,a2,z3,g=model_computation(x,y,theta1,theta2)
def evalute_model(y):
y_pred=np.argmax(g,axis=1)+1
accuracy=[1 if i==j else 0 for (i,j) in zip(y_pred,y)]
accuracy=sum(accuracy)/len(y)
print('The accuracy of the model is:{}{}'.format(accuracy*100,'%'))
evalute_model(y)