吴恩达机器学习课后习题ex3(python实现)

ex3

  • 一对多
  • 神经网络
  • 参考

一对多

在本练习中,您将使用逻辑回归和神经网络来识别手写数字(从0到9)。自动手写数字识别在今天被广泛使用,从识别信封上的邮政编码到识别银行支票上的金额。本练习将向您展示如何将您所学的方法用于此分类任务。在练习的第一部分中,您将扩展先前的logistic回归实现,并将其应用于one-vs-all分类。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmat
data= loadmat("ex3data1.mat") #mat格式转换为dict字典
data

吴恩达机器学习课后习题ex3(python实现)_第1张图片

data['X'].shape
data['y'].shape

分别是(5000,400),(5000,1),其中400维“特征”是原始20 x 20图像中每个像素的灰度强度,有5000张图片。

def image(X):
    pick_one=np.random.randint(5000)  #返回一个随机整型数
    image=X[pick_one]
    
    fig,ax=plt.subplots()
    ax.imshow(image.reshape(20,20).T)
    
image(raw_X)

吴恩达机器学习课后习题ex3(python实现)_第2张图片
公式参考https://www.cnblogs.com/qkloveslife/p/9866515.html

def computecost(theta,x,y,lambd):
    A=sigmoid(x@theta)
    first=np.multiply(-y,np.log(A))
    second=np.multiply(1-y,np.log(1-A))
    inner=first-second
    reg=(lambd/(2*len(x)))*np.sum(np.power(theta[1:],2))
    return np.sum(inner)/len(x)+reg
#计算一次梯度
def gradient(theta,x,y,lambd):
    
    reg=theta[1:]*(lambd/len(x))
    reg=np.insert(reg,0,0,axis=0)
    A=sigmoid(x@theta)-y
    grad=(x.T@A)/len(x)+reg
    
    return grad

注意:这里computecost和gradient都要把theta放在第一个参数位置,因为scipy.optimize.minimize要求这样,具体参数参考https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#scipy.optimize.minimize

对于每一个类 i 训练一个逻辑回归模型的分类器h(i)θ(x),并且预测 y = i时的概率;对于一个新的输入变量x, 分别对每一个类进行预测,取概率最大的那个类作为分类结果。

def onevsall(x,y,lambd,k):
  n=x.shape[1]  #n (5000,401)
  theta_all=np.zeros((k,n))
  #10个分类器,每个分类器进行一次minimize
  for i in range(1,k+1):
    theta_i=np.zeros(n)
    res=minimize(computecost,theta_i,args=(x,y==i,lambd),method='TNC',jac=gradient)
    theta_all[i-1]=res.x
  return theta_all
raw_X=data['X']
raw_y=data['y']

X=np.insert(raw_X,0,1,axis=1)
#对y的处理是因为computecost函数进行计算的需要
y=raw_y.flatten()

lambd=1
k=10
theta_final=onevsall(X,y,lambd,k)
def predict(x,theta):
  y_pre=sigmoid(x@theta.T) #5000*10
  #返回每一行最大概率值的索引
  y_prefi=np.argmax(y_pre,axis=1)
  return y_prefi+1

y_pre=predict(X,theta_final)
acc=np.mean(y_pre==y)
print(acc)

神经网络

在本练习的前一部分中,您实现了多类逻辑回归来识别手写数字。然而,logistic回归不能形成更复杂的假设,因为它只是一个线性分类。
在练习的这一部分中,您将使用与之前相同的训练集实现一个神经网络来识别手写数字。神经网络将能够表示形成非线性假设的复杂模型。本周,你将使用我们已经训练过的神经网络的参数。你的目标是实现前馈传播算法来使用我们的权重进行预测。在下周的练习中,您将编写用于学习神经网络参数的反向传播算法。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmat
data= loadmat("ex3data1.mat") #mat格式转换为dict字典
raw_X=data['X']  #5000,401
raw_y=data['y']   #5000,1
x=np.insert(raw_X,0,1,axis=1)
weights= loadmat("ex3weights.mat") #mat格式转换为dict字典
theta1=weights['Theta1']  #(25, 401)
theta2=weights['Theta2']  #(10, 26)
#每一个权重矩阵的大小是a(j+1)*(aj+1)   中间隐藏层的激活单元数量是25个
def sigmoid(z):
    return 1/(1+np.exp(-z))
#向量计算 这里权重theta已经给了我们,不需要我们再像以前使代价函数最小化使用梯度下降来求theta的值,已经给出
def forwardpropagation(x,theta1,theta2):
    z=sigmoid(x@theta1.T)
    z=np.insert(z,0,1,axis=1)
    final=sigmoid(z@theta2.T)
    return final
theta_final=forwardpropagation(x,theta1,theta2)  #5000,10

之后计算准确率的方法和之前一样

y_prefi=np.argmax(theta_final,axis=1)+1
y=y.flatten()
acc=np.mean(y_prefi==y)

参考

1、dataframe基本操作 https://blog.csdn.net/xtfge0915/article/details/52938740
2、pandas处理mat表格文件
https://blog.csdn.net/ssswill/article/details/84958253
3、Logistic Regression(逻辑回归)模型实现二分类和多分类
https://blog.csdn.net/u011734144/article/details/79717470
4、python (n,)、(n,1)、(1,n)数组的区别
https://blog.csdn.net/qq_22592457/article/details/103474408
5、矩阵与数组相乘的问题 (非常重要,理解!!!)
https://blog.csdn.net/weixin_43069755/article/details/88209967
6、

a = np.array([2,3,4])
a.shape #a(3,)
b = np.array([[2,3,4]]) #注意这有两个括号
b.shape #b(1,3)

你可能感兴趣的:(吴恩达机器学习课后习题ex3(python实现))