吴恩达机器学习的课后作业及数据可以在coursera平台上进行下载,只要注册一下就可以添加课程了。所以这里就不写题目和数据了,有需要的小伙伴自行去下载就可以了。
作业及数据下载网址:吴恩达机器学习课程
多元分类的作业是一个识别手写数字的任务,主要包含两方面的任务:对初始数据进行可视化和进行数字的识别。下面附上代码,有详细的注释,这里就不一一解释了。
import scipy.io as scio #用于导入mat文件的库
from scipy.optimize import minimize #导入优化和拟合库中的最小优化
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
#用于导入数据的函数
def inputData():
dataFile='MachineLearning\\machine-learning-ex3\\machine-learning-ex3\\ex3\\ex3data1.mat'
#导入mat文件数据
data=scio.loadmat(dataFile)
X=data['X']
y=data['y']
return X,y
#对数据进行可视化的函数
def visualizeData(X):
#画布上定义10*10的子图
fig,ax = plt.subplots(10,10)
for i in range(0,10):
for j in range(0,10):
magicNum=np.random.randint(5000) #在0~5000之中生成随机整数
#注意下面需要进行reshape,从1*400重构会20*20的像素点,gray_r代表是白底黑字
ax[i][j].imshow(X[magicNum,:].reshape(20,20),cmap='gray_r') #进行图片绘制
#消除坐标轴,主要为了美观
ax[i][j].set_xticks([])
ax[i][j].set_yticks([])
plt.show()
#定义sigmoid函数
def sigmoid(z):
return 1/(1+np.exp(-z))
#计算代价值的函数
def getCosts(theta,X,y,lamda):
m=X.shape[0]
#根据代价函数的公式进行计算
costsJ= np.sum((-y*np.log(sigmoid(X@theta))-(1-y)*np.log(1-sigmoid(X@theta))))/m
return costsJ
#计算梯度的函数
def computeGradient(theta,X,y,lamda):
m=X.shape[0]
cy=sigmoid(X@theta)
#单独计算偏置单元的值,因为偏置单元不需要进行正则化
temp=(X.T[0,:]@(cy-y))/m
#对全部数值进行正则化
gradient = (X.T@(cy-y))/m+lamda*theta/m
#修改偏置单元的梯度数值
gradient[0] = temp
return gradient
#进行分类器构建的函数
def oneVsAllClassification(X,y,lamda,K):
#要加上偏置单元的列,也就是加上一列全1
X=np.insert(X,0,values=np.ones(X.shape[0]),axis=1)
#初始化最优总的theta数组,维度是分类数K*(特征数+1)
answerTheta = np.zeros((K,X.shape[1]))
#遍历每一种分类器
for i in range(1,K+1):
#因为在进行二元分类时,真实值只可能为0和1
#多元分类中,采用的是一对多的思想
#因此下面这行就是除了当前分类,其他y值全部设置为0
ys=np.array([1 if num==i else 0 for num in y])
#初始化当前分类器的theta数组
tempTheta = np.zeros((X.shape[1],1))
#调用最小化函数。注意这里的参数位置,theta要放在最前面,其他参数也要和args对应
res = minimize(fun=getCosts,x0=tempTheta,args=(X,ys,lamda),method='TNC',jac=computeGradient)
#将当前分类器的theta数组整合到总的theta数组中
#通过res.x可以获得对应的theta
answerTheta[i-1,:]=res.x
return answerTheta
#进行预测的函数
def prediction(X,y,theta,K):
#插入偏置单元,也就是全为1的列
X=np.insert(X,0,values=np.ones(X.shape[0]),axis=1)
#计算数据在每种分类器下的数值,得到answer1是一个5000*K的数据,也就是在每种分类器下预测的概率
answer1 = X@theta.T
#argmax求出在每种分类器下预测概率最高的下标。(本题中要对应位置,所以要+1)
answer2 = np.argmax(answer1,axis=1)+1
#将一个行向量变成一个列向量
answer2 = answer2.reshape((answer2.shape[0],1))
#和真实的分类进行比较
finalAnswer = (answer2==y)
#输出准确率
print('accuary:',np.mean(finalAnswer)*100,'%')
K=10 #定义分类数
lamda=1 #定义lamda
X,y = inputData() #导入数据
answerTheta = oneVsAllClassification(X,y,lamda,K) #构建分类器
prediction(X,y,answerTheta,K) #进行预测
visualizeData(X) #可视化数据
前向传播的作业是吴恩达老师给出了拟合好的thea数组,我们只需要进行计算并进行预测即可。下面附上代码,有详细的注释,这里就不一一解释了。
from matplotlib.pyplot import axis
import pandas as pd
import numpy as np
import scipy.io as scio
#用于导入数据的函数
def inputData():
#导入训练集的路径
dataFile1='MachineLearning\\machine-learning-ex3\\machine-learning-ex3\\ex3\\ex3data1.mat'
#导入权重的路径
dataFile2='MachineLearning\\machine-learning-ex3\\machine-learning-ex3\\ex3\\ex3weights.mat'
#导入训练集
data1=scio.loadmat(dataFile1)
X=data1['X']
y=data1['y']
#插入一列全1作为偏置单元
X = np.insert(X,0,values=np.ones(X.shape[0]),axis=1)
#导入权重
data2=scio.loadmat(dataFile2)
theta1=data2['Theta1']
theta2=data2['Theta2']
return X,y,theta1,theta2
#定义sigmoid函数
def sigmoid(z):
return 1/(1+np.exp(-z))
#用于进行前向传播和预测的函数
def forwardPropagationAndPrediction(X,y,theta1,theta2):
#将输入的数据作为a1
a1=X
#进行第一层传播,得到一个25*5000的a2
a2=sigmoid(theta1@a1.T)
#为a2添加偏置单元
a2=np.insert(a2,0,values=1,axis=0)
#进行第二层传播,得到一个10*5000的a3输出层
a3=sigmoid(theta2@a2)
#因为是多元分类,因此这里需要选择每一个样本在训练集中的最大的分类器
prediction=np.argmax(a3,axis=0)+1
#将真值y从2维数据缩减成1维数据,方便比较
y=y.flatten()
#输出精确度
print('accuary',np.mean(y==prediction)*100,'%')
X,y,theta1,theta2 = inputData() #导入数据
forwardPropagationAndPrediction(X,y,theta1,theta2) #进行前向传播和预测