吴恩达机器学习课后作业——多元分类及前向传播

1.写在前面

吴恩达机器学习的课后作业及数据可以在coursera平台上进行下载,只要注册一下就可以添加课程了。所以这里就不写题目和数据了,有需要的小伙伴自行去下载就可以了。
作业及数据下载网址:吴恩达机器学习课程

2.多元分类

多元分类的作业是一个识别手写数字的任务,主要包含两方面的任务:对初始数据进行可视化和进行数字的识别。下面附上代码,有详细的注释,这里就不一一解释了。

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)      #可视化数据

结果展示:
初始数据可视化
吴恩达机器学习课后作业——多元分类及前向传播_第1张图片
多元分类预测准确率:
在这里插入图片描述

3.前向传播

前向传播的作业是吴恩达老师给出了拟合好的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)     #进行前向传播和预测

结果展示:
预测准确率
在这里插入图片描述

你可能感兴趣的:(吴恩达机器学习笔记,吴恩达,python,多元分类,前向传播,机器学习)