吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network

文章目录

    • 题目描述
    • 数据集介绍
    • 逻辑回归(多元分类)
    • 神经网络

题目描述

在本练习中,将使用逻辑回归和神经网络来识别手写数字(从0到9)。练习的第一部分,将扩展之前的逻辑回归实现,将其应用于一对多的分类;第二部分将使用神经网络进行数字识别。

数据集介绍

该数据集共有5000个训练样本,每个样本是20*20像素的灰度图像,每个像素为一个浮点数,表示该位置的灰度强度。20×20的像素网格被展开成一个400维的向量。在数据矩阵X(5000×400)中,每个样本变成了一行,每一行代表一个手写数字图像的训练样本。
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第1张图片

逻辑回归(多元分类)

导入库

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from scipy.io import loadmat      #读入matlab格式的文件
import scipy.optimize as opt
from sklearn.metrics import classification_report  #模型分类指标

加载数据集
这里的数据为MATLAB的格式,所以要使用scipy.py的loadmat函数。

def load_data(path,transpose=True):
    data = loadmat(path)
    X = data['X']
    y = data['y']
    y = y.reshape(y.shape[0])
    #print(y.shape)
    #print(type(X))
    if transpose:
        X = np.array([im.reshape((20,20)).T.reshape(400) for im in X])
    return X,y

raw_X, raw_y = load_data('ex3data1.mat')
#看有几类标签
print(np.unique(raw_y))
print(raw_X.shape,raw_y.shape)

运行结果:
在这里插入图片描述
数据可视化
随机打印一张图片

def plot_an_image(image):
    fig,ax = plt.subplots(figsize=(1,1))
    # cmap参数是用于绘制图像的颜色映射,使用matplotlib库中的cm子库中的binary颜色映射,将导致图片被渲染成黑白两色
    ax.matshow(image.reshape((20,20)),cmap=matplotlib.cm.binary)
    #plt.xticks(ticks=None, labels=None, **kwargs)用来获取或设置当前x轴刻度位置和标签。
    #ticks:x轴刻度位置的列表,若传入空列表,即不显示x轴
    #labels:放在指定刻度位置的标签文本。当tricks参数有输入值,该参数才能传入参数
    #**kwargs:文本属性用来控制标签文本的展示,例如字体大小、样式等。
    plt.xticks(np.array([]))
    plt.yticks(np.array([]))
    plt.show()

#生成一个随机整数,作为要显示图像的索引
pick_one = np.random.randint(0,5000)    #randint()随机选择一个整数,只选一个
#显示raw_X数组中’pick_one‘行数据所表示的图像
plot_an_image(raw_X[pick_one,:])
if raw_y[pick_one] == 10:
    raw_y[pick_one] = 0
#format()用于格式化字符串。可以接受无限个参数,可以指定顺序。返回结果为字符串
print('this should be {}'.format(raw_y[pick_one]))

运行结果:
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第2张图片
在这里插入图片描述
随机选取100张图片进行展示

def plot_100_images(X):
    #choice可以随机选择很多个整数类型,lem(X)=5000,即5000里随机选100个
    sample_index = np.random.choice(len(X),100)
    images = X[sample_index,:]
    print(images.shape)
    #定义10*10的子画布
    fig,ax = plt.subplots(ncols=10,nrows=10,figsize=(8,8),sharex=True,sharey=True)
    #在每个子画布中画出一个数字
    for i in range(10):
        for j in range(10):
            ax[i, j].imshow(images[10 * i + j].reshape(20, 20), cmap='gray_r')

    #去掉坐标轴
    plt.xticks([])
    plt.yticks([])
    plt.show()

plot_100_images(raw_X)

运行结果:
在这里插入图片描述
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第3张图片
数据预处理

X = np.insert(raw_X,0,values=1,axis=1)
print(X.shape)
#将y从类标签转换为每个分类器的二进制值(要么是类i,要么不是类i)
y = []
for k in range(1,11):
    y.append([1 if i==k else 0 for i in raw_y])
#[-1]列表最后一项,[:-1]从第一项到最后一项
#将矩阵y的行重新排列,使得最后一行表示最后一个分类器(类10 vs.非类10),而其余行按顺序表示前面的分类器(类1 vs.非类1等)
y = np.array([y[-1]] + y[:-1])
print(y.shape)

在这里插入图片描述
定义损失函数

#定义sigmoid函数
def sigmoid(z):
    return 1/(1+np.exp(-z))

#定义损失函数
def cost(theta,X,y):
    first = y * np.log(sigmoid(X @ theta.T))
    second = (1-y) * np.log(1 - sigmoid(X @ theta.T))
    return -np.mean(first + second)

#正则化损失函数
def regularized_cost(theta,X,y,l):
    reg = l / (2 * len(X)) * (theta[1:]**2).sum()
    return cost(theta,X,y) + reg

定义梯度

def gradient(theta,X,y,l):
    error = sigmoid(X@theta.T) - y
    grad = X.T @ error / len(X)
    reg = theta * l / len(X)
    reg[0] = 0
    return grad + reg

逻辑回归

#逻辑回归
def logistic_regression(X,y,l=1):
    theta = np.zeros(X.shape[1])
    # fun:损失函数(定义时,theta必须是第一个参数且是一维数组)
    # x0:初始化的theta,必须是一维数组  args:计算损失函数时用到的其他参数,以元组的形式传入
    # method:采用的算法 Newton-CG 牛顿共轭梯度算法  jac:计算梯度的函数(第一个参数必须是theta且为一维数组)
    res = opt.minimize(fun = regularized_cost,x0=theta,args=(X,y,l),method='TNC',jac=gradient,options={'disp':True})
    return res.x

预测分析

def predict(theta,X):
    prob = sigmoid(X @ theta)
    return [1 if i >= 0.5 else 0 for i in prob]

训练1维

theta_0 = logistic_regression(X,y[0])
print(theta_0.shape)
print(theta_0[0])

y_pred = predict(theta_0,X)
print('Accurary = {}'.format(np.mean(y[0] == y_pred)))

运行结果:
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第4张图片
训练k维

theta_k = np.array([logistic_regression(X,y[k]) for k in range(10)])
print(theta_k.shape)

prob_matrix = sigmoid(X @ theta_k.T)
#将数组科学计数法转化为浮点数
np.set_printoptions(suppress=True)
print(prob_matrix)
#返回每行最大的列索引
y_pred = np.argmax(prob_matrix,axis=1)
y_pred = np.array([10 if i==0 else i for i in y_pred])
print(y_pred)

运行结果:
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第5张图片
模型分类指标

print(classification_report(raw_y,y_pred))

运行结果:
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第6张图片

神经网络

逻辑回归作为一个线性分类器,不能形成复杂的假设,而神经网络在学习复杂的非线性假设上被证明是一种好得多的算法,即使特征数很多。这里使用的神经网络结构如下图所示。
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第7张图片
导入包

import numpy as np
from scipy.io import loadmat      
from sklearn.metrics import classification_report  

加载数据集与模型参数

def load_data(path,transpose=True):
    data = loadmat(path)
    X = data['X']
    y = data['y']
    print(y.shape)
    #将y转化为1维数组
    y = y.reshape(y.shape[0])
    print(y.shape)
    print(type(X))
    #如果transpose参数设置为True,则函数会将X数组的每个图像转置,并将其重新排列为一维数组
    if transpose:
        X = np.array([im.reshape((20,20)).T.reshape(400) for im in X])
    return X,y

def load_weight(path):
    data = loadmat(path)
    return data['Theta1'],data['Theta2']

theta1,theta2 = load_weight('ex3weights.mat')
print(theta1.shape,theta2.shape)

X,y = load_data('ex3data1.mat',transpose=False)
X = np.insert(X,0,np.ones(X.shape[0]),axis=1)
print(X.shape,y.shape)

运行结果:
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第8张图片
前向传播

a1 = X
z2 = a1 @ theta1.T
print(z2.shape)      #(5000,25)
a2 = sigmoid(z2)
print(a2.shape)      #(5000,25)
a2 = np.insert(a2,0,np.zeros(a2.shape[0]),axis=1)
print(a2.shape)        #(5000,26)
z3 = a2 @ theta2.T
print(z3.shape)         ##(5000,10)
a3 = sigmoid(z3)
print(a3.shape)         #(5000,10)
print(a3)

运行结果:
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第9张图片
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第10张图片
在这里插入图片描述
模型分类指标

print(classification_report(y,y_pred))
accuracy = np.mean(y_pred == y)
print ('accuracy = {0}%'.format(accuracy * 100)) 

运行结果:
吴恩达机器学习课后作业Python实现 03 Multi-class Classification & Neural Network_第11张图片
在这里插入图片描述

你可能感兴趣的:(机器学习,python,机器学习)