Andrew NG机器学习 练习三Multi-class 分类 PYTHON实现

一、Multi-class Classification

可视化直接抄了大佬代码,多分类,根本上就是多个二分类逻辑回归

  ML_exe03_MultiClass.py

import numpy as np
import scipy.io as sio #加载matlab的数据
from plotData import *
from oneVsAll import *
from predictOneVsAll import *

#加载训练集数据
data = sio.loadmat('ex3data1.mat')

X=data['X']
y = data['y']

#10-0
y = y%10
#样本数量
m = X.shape[0]
#随机取图片的index可视化(low,high]
rand = np.random.randint(low=0,high=m,size=100,dtype=int)
#得到index对应的样本
sample = X[rand,:]
#可视化随机样本
displayData(sample)

#计算theta
lamd = 0.3
#label的数量
labels = 10
#计算所有的theta
thetas = oneVsAll(X,y,labels,lamd)

#预测
prediction = predictOneVsAll(thetas,X)
acRate = np.mean(prediction == y.flatten())*100
print("AC rate:",acRate,'%')

   plotData.py



import numpy as np
import matplotlib.pyplot as plt

#显示图片数据
def displayData(X):
    m = np.size(X, 0)  #X的行数,即样本数量
    n = np.size(X, 1)  #X的列数,即单个样本大小
    example_width = int(np.round(np.sqrt(n)))  #单张图片宽度
    example_height = int(np.floor(n / example_width))  #单张图片高度
    display_rows = int(np.floor(np.sqrt(m)))  #显示图中,一行多少张图
    display_cols = int(np.ceil(m / display_rows))  #显示图中,一列多少张图片
    pad = 1  #图片间的间隔
    display_array = - np.ones((pad + display_rows * (example_height + pad),
                            pad + display_cols * (example_width + pad)))  #初始化图片矩阵
    curr_ex = 0  #当前的图片计数
    #将每张小图插入图片数组中
    for j in range(0, display_rows):
        for i in range(0, display_cols):
            if curr_ex >= m:
                break
            max_val = np.max(abs(X[curr_ex, :]))
            jstart = pad + j * (example_height + pad)
            istart = pad + i * (example_width + pad)
            display_array[jstart: (jstart + example_height), istart: (istart + example_width)] = \
                np.array(X[curr_ex, :]).reshape(example_height, example_width) / max_val
            curr_ex = curr_ex + 1
        if curr_ex >= m:
            break
    display_array = display_array.T
    plt.imshow(display_array,cmap=plt.cm.gray)
    plt.axis('off')
    plt.show()

sigmoid.py

import numpy as np

def sigmoid(z):
    return 1/(1+np.exp(-z))

costFunction.py

import numpy as np
from sigmoid import *


#cost计算函数
def costFunction(theta, X, y, lamb):
    #向量成矩阵
    theta = np.array(theta).reshape((np.size(theta), 1))
    #样本数
    m = y.shape[0];
    #计算sigmod
    h = sigmoid(np.dot(X, theta))
    # 正则化项去掉theta 0
    theta2 = theta[1:, 0]
    #计算J
    J = 1/m*(-np.dot(y.T, np.log(h)) - np.dot((1-y.T), np.log(1-h)))+lamb/(2*m)*np.dot(theta2,theta2)

    #矩阵铺平成向量
    return J.flatten()

#求梯度
def gradient(theta, X, y, lamb):
    #向量成矩阵
    theta = np.array(theta).reshape((np.size(theta), 1))
    # 样本数
    m = y.shape[0];

    h = sigmoid(np.dot(X, theta))
    #  正则化项去掉theta 0
    theta[0, 0] = 0
    grad = 1/m*np.dot(X.T, h - y)+lamb/m*theta
    # 矩阵铺平成向量
    return grad.flatten()

oneVsAll.py

import numpy as np
import scipy.optimize as op
from costFunctino import *

#计算多个分类模型的theta
def oneVsAll(x,y,lables,lamd):
    #样本数量
    m = x.shape[0]
    #特征数量
    n = x.shape[1]

    #所有的theta,行数为二分类theta的数量,列数为label数量+1
    thetas = np.zeros((lables,n+1))

    #插入x0特征
    # x = np.c_[np.ones(m),x]
    x = np.insert(x, 0, values=np.ones(m), axis=1)

    #每一个label训练出一套theta
    for i in range(0,lables):
        #初始theta,加上theta0
        initial_theta = np.zeros(n+1)
        #y=(y==i)会报错,因为y一直在变,会影响下一次迭代结果
        ynew = (y==i)
        #得出最优解
        result = op.minimize(fun=costFunction,x0=initial_theta,args=(x,ynew,lamd),method='TNC',jac=gradient)
        #将该部分theta加入所有的theta中
        thetas[i,:] = result.x
    return thetas



predictOneVsAll.py

import numpy as np
from sigmoid import *
#计算准确率
def predictOneVsAll(thetas,x):
    #测试集数量
    m = x.shape[0]
    #labels的数量
    labels = thetas.shape[0]

    #存储测试集在各个二分类模型中的结果
    result_all = np.zeros((m,labels))
    #存储最后的结果
    result = np.zeros((m,1))
    #测试集插入x0
    x = np.insert(x, 0, values=np.ones(m), axis=1)
    for label in range(0,labels):
        result_all[:,label] = sigmoid(np.dot(x,thetas[label,:].T))
    #统计函数,得到每行的最大值
    result = result_all.argmax(axis=1)
    #将矩阵展开成向量
    return result.flatten()

二、Neural Networks

已知神经网络参数,只是模拟正向传播而已

  •   ML_exe03_NN.py  主运行程序,load数据,预测,可视化
  •   nnPlotData.py 可视化
  •   predict.py  预测
  •   sigmoid.py  激活函数

  ML_exe03_NN.py

import scipy.io as scio
import numpy as np
from predict import *
from nnPlotData import *

#加载训练数据
data = scio.loadmat('ex3data1.mat')

X = data['X']
y = data['y']

#样本数量
m = y.shape[0]

#加载神经网络theta数据
theta = scio.loadmat('ex3Weights.mat')
#第一层的网络参数
theta1 = theta['Theta1']
#第二层的网络参数
theta2 = theta['Theta2']

#预测
result = predict(theta1,theta2,X)
print('AC Rate:',np.mean(result==y.flatten())*100,'%')


#识别单张图片
for i in range(0, m):
    #随机挑选一张样本下标
    it = np.random.randint(0, m, 1)
    #可视化该图片
    plotData(X[it[0]:it[0]+1, :])
    #预测结果
    result = predict(theta1, theta2, X[it[0]:it[0]+1, :])
    print('Neural Network Prediction:', result)
    print('input q to exit:')
    c = input()
    if c == 'q':
        break

  nnPlotData.py

import matplotlib.pyplot as plt
import numpy as np

#显示图片数据
def plotData(X):
    m = np.size(X, 0)  #X的行数,即样本数量
    n = np.size(X, 1)  #X的列数,即单个样本大小
    example_width = int(np.round(np.sqrt(n)))  #单张图片宽度
    example_height = int(np.floor(n / example_width))  #单张图片高度
    display_rows = int(np.floor(np.sqrt(m)))  #显示图中,一行多少张图
    display_cols = int(np.ceil(m / display_rows))  #显示图中,一列多少张图片
    pad = 1  #图片间的间隔
    display_array = - np.ones((pad + display_rows * (example_height + pad),
                            pad + display_cols * (example_width + pad)))  #初始化图片矩阵
    curr_ex = 0  #当前的图片计数
    #将每张小图插入图片数组中
    for j in range(0, display_rows):
        for i in range(0, display_cols):
            if curr_ex >= m:
                break
            max_val = np.max(abs(X[curr_ex, :]))
            jstart = pad + j * (example_height + pad)
            istart = pad + i * (example_width + pad)
            display_array[jstart: (jstart + example_height), istart: (istart + example_width)] = \
                np.array(X[curr_ex, :]).reshape(example_height, example_width) / max_val
            curr_ex = curr_ex + 1
        if curr_ex >= m:
            break
    display_array = display_array.T
    plt.imshow(display_array,cmap=plt.cm.gray)
    plt.axis('off')
    plt.show()

  predict.py

from sigmoid import *
import numpy as np

#预测
def predict(theta1,theta2,X):
    #样本数量
    m = X.shape[0];

    #第二层计算,插入一列X0
    X = np.insert(X,0,np.ones(m),axis=1)
    #计算隐藏层unit,sigmoid作为激活函数
    a2 = sigmoid(np.dot(X,theta1.T))

    #第三层计算,插入偏移单元
    a2 = np.insert(a2,0,np.ones(a2.shape[0]),axis=1)
    #计算输出层unit,sigmoid作为激活函数
    a3 = sigmoid(np.dot(a2,theta2.T))
    # 0~9====1~10
    p = a3.argmax(axis=1) +1
    #矩阵展开成向量
    return p.flatten()



  sigmoid.py

import numpy as np

def sigmoid(z):
    return 1/(1+np.exp(-z))

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值