神经网络
对于这个练习,我们将再次处理手写数字数据集。这次使用反向传播的前馈神经网络,自动学习神经网络的参数。
数据可视化
这部分和ex3里是一样的,5000张20*20像素的手写数字数据集,以及对应的数字(1-9,0对应10)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
from scipy.io import loadmat
from sklearn.preprocessing import OneHotEncoder
data = loadmat('ex4data1.mat')
data
{'X': array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]]),
'__globals__': [],
'__header__': b'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Sun Oct 16 13:09:09 2011',
'__version__': '1.0',
'y': array([[10],
[10],
[10],
...,
[ 9],
[ 9],
[ 9]], dtype=uint8)}
X = data['X']
y = data['y']
X.shape,y.shape
((5000, 400), (5000, 1))
weight = loadmat('ex4weights.mat')
theta1,theta2 = weight['Theta1'],weight['Theta2']
theta1.shape,theta2.shape
((25, 401), (10, 26))
sample_idx = np.random.choice(np.arange(data['X'].shape[0]),100)
sample_images = data['X'][sample_idx,:]
fig,ax_array = plt.subplots(nrows = 10,ncols=10,sharex = True,sharey = True,figsize=(12,12))
for r in range(10):
for c in range(10):
ax_array[r,c].matshow(np.array(sample_images[10*r+c].reshape((20,20))).T,cmap=matplotlib.cm.binary)
plt.xticks(np.array([]))
plt.yticks(np.array([]))
前向传播和代价函数
首先,实现神经网络的代价函数和梯度函数
要求:你的代码应该适用于任何数据集,包括任意数量的输入输出单元
def sigmoid(z):
return 1/(1+np.exp(-z))
#前向传播函数
def forward_propagate(X,theta1,theta2):
m = X.shape[0]
a1 = np.insert(X,0,values=np.ones(m),axis=1)
z2 = a1*theta1.T
a2 = np.insert(sigmoid(z2),0,values = np.ones(m),axis = 1)
z3 = a2 * theta2.T
h = sigmoid(z3)
return a1,z2,a2,z3,h
#代价函数
def cost(theta1,theta2,X,y):
m = X.shape[0]
X = np.matrix(X)
y = np.matrix(y)
#前向函数计算出各个值
a1,z2,a2,z3,h = forward_propagate(X,theta1,theta2)
#计算代价
J = 0
for i in range(m):
left = np.multiply(-y[i,:],np.log(h[i,:]))
right = np.multiply(1-y[i,:],np.log(1-h[i,:]))
J += np.sum(left-right)
J /= m
return J
对y标签进行编码
一开始我们得到的y是50001维的向量,但我们要把他编码成500010的矩阵。
比如说,原始 y 0 = 2 y_0=2 y