吴恩达机器学习作业3(python)

git 参考(课程+代码+作业)

代码不包括画图部分

逻辑回归

import numpy as np
import matplotlib.pylab as plt
import scipy.io as sio
import math
import scipy.optimize as op
# 逻辑回归
# 分类(识别)手写数字图片

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

def costFunction(theta, x, y, lam):
    m = np.size(y)
    h = sigmoid(x@theta)
    if np.sum(1-h < 1e-10) != 0:
        return np.inf
    first = (-y@np.log(h) - (1-y)@np.log(1-h)) /m
    second = lam/2/m * theta[1:]@theta[1:]
    # theta_0不需要正则化
    return first + second

def gradFunction(theta, x, y, lam):
    m = np.size(y)
    h = sigmoid(x@theta)
    grad = x.T@(h - y)/m
    grad[1:] += lam/m * theta[1:]
    # theta_0不需要正则化
    return grad

def OneVsAll(x, y, class_num, lam):
    m, n = np.shape(x)
    theta = np.zeros((class_num, n+1))
    # n为特征数,+1是theta_0
    x = np.column_stack((np.ones(m), x))

    for i in range(class_num):
        num = 10 if i == 0 else i #如果i==0那么num=10,否则num=i
        p = (y == num) *1
        # 计算每个class时,将训练集的分类结果设置为0和1,对应的class为1,其他为0
        # (y == num)向量的元素是True和False,1*转换为数字

        init_theta = np.zeros(n+1)
        result = op.minimize(costFunction, init_theta, args=(x,p,lam), \
                method='BFGS', jac=gradFunction, options={'maxiter': 200})
        # maxiter为迭代次数
        theta[i, :] = result.x
    return theta
    
# np.set_printoptions(threshold=np.inf) # print()可以显示所有数据
data = sio.loadmat('ex3data1.mat')
# data包含两个矩阵X和y,X有5000行400列,y为5000行向量;
# X有5000个实例,每个实例是20*20像素的灰度图像,即每行都是一个手写数字图片;
# y是对应实例的对应数字1-10(10代表手写图片0)

X = data['X']
Y = data['y'][:, 0] # [:, 0]才能变成向量
# print(Y.shape)
# print(Y)
class_num = 10  # 0-9
lamb = 0.1
theta = OneVsAll(X, Y, class_num, lamb)

# 预测值函数
def predictOneVsAll(theta, x):
    m = np.size(x, 0)
    x = np.column_stack((np.ones(m), x))
    p = np.argmax(x@(theta.T), axis=1)
    # np.argmax求最大值的索引值,axis=0求列最大值,axis=1求行最大值
    # p为每个实例最大可能的分类,组成的向量
    # sigmoid(z)为增函数,比较z的大小即可
    return p

pred = predictOneVsAll(theta, X)
print('Training Set Accuracy: ', np.sum(pred == (Y % 10))/np.size(Y))

神经网络

import numpy as np
import matplotlib.pylab as plt
import scipy.io as sio
import math
import scipy.optimize as op
# 神经网络
# 分类(识别)手写数字图片
# 正向传播,已知权值

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

np.set_printoptions(threshold=np.inf) # print()可以显示所有数据
data = sio.loadmat('ex3data1.mat')
# data包含两个矩阵X和y,X有5000行400列,y为5000行向量;
# X有5000个实例,每个实例是20*20像素的灰度图像,即每行都是一个手写数字图片;
# y是对应实例的对应数字1-10(10代表手写图片0)
X = data['X']
Y = data['y'][:, 0] # [:, 0]才能变成向量

data = sio.loadmat('ex3weights.mat')
# print(data)
theta1 = data['Theta1']
theta2 = data['Theta2']

m = np.size(Y)
X = np.column_stack((np.ones(m), X))
z2 = X@(theta1.T)
a2 = sigmoid(z2)
a2 = np.column_stack((np.ones(m), a2))
z3 = a2@(theta2.T)
a3 = sigmoid(z3)

pred = np.argmax(a3, axis=1)+1 #直接比较z3也可以
# 这个训练的theta权值有点坑,是按照1-10的结果去训练的,即a3中10列的概率值对应是1234567890,所以索引要+1
print('Training Set Accuracy: ', np.sum(pred == Y)/np.size(Y))

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