吴恩达机器学习课后习题3

实验1:预测手写数字的识别

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.io as sio
from scipy.optimize import minimize


# 预测true flase
def predict(X, theta_final):
    h = sigmoid(X @ theta_final.T)  # 5000x401 10x401 > 5000x10
    h_argmax = np.argmax(h, axis=1)  # 沿着每一行所有列比较最大

    return h_argmax + 1  # 索引返回最大的 因为下标是0比较的数字从1开始 加1 最后10代表0

#返回最终的K个训练器的theta
def one_vs_all(X, y, lamda, K):
    n = X.shape[1]

    theta_all = np.zeros((K, n))

    for i in range(1, K + 1):
        theta_i = np.zeros(n, ) #每个分类器的theta

        res = minimize(fun=costFunction,
                       x0=theta_i,
                       args=(X, y == i, lamda),
                       method='TNC',
                       jac=gradient_reg) #
        theta_all[i - 1, :] = res.x #相当于训练完的所有分类器的最佳参数返回

    return theta_all


##显示样本中的图片
def plot_an_image(X):
    picek_one = np.random.randint(5000)

    image = X[picek_one, :]

    fig, ax = plt.subplots(figsize=(1, 1))
    ax.imshow(image.reshape(20, 20).T, cmap='gray_r')  # 翻转过来T
    plt.xticks([])  #
    plt.yticks([])  # 去掉轴的刻度
    plt.show()  ##加这个才能显示


# 随机100张图片
def plot_100_image(X):
    sample_index = np.random.choice(len(X), 100)
    images = X[sample_index, :]

    fig, ax = plt.subplots(figsize=(8, 8), ncols=10, nrows=10, sharex=True, sharey=True)  # 10行10列同时共享刻度
    for i in range(10):
        for c in range(10):
            ax[i, c].imshow(images[i * 10 + c, :].reshape(20, 20).T, cmap='gray_r')  # 翻转过来T

    # ax.imshow(image.reshape(20, 20).T, cmap='gray_r') #翻转过来T
    plt.xticks([])  #
    plt.yticks([])  # 去掉轴的刻度
    plt.show()  ##加这个才能显示


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


# 实现逻辑回归的代价函数,两个部分,-y(log(hx)和-(1-y)log(1-hx)
def costFunction(theta, X, y, lamda):  ## scipy传参要求必须换位置
    A = sigmoid(X @ theta)

    first = y * np.log(A)
    second = (1 - y) * np.log(1 - A)

    # reg = np.sum(np.power(theta[1:], 2)) * (lamda / (2 * len(X)))
    reg = theta[1:] @ theta[1:] * (lamda / (2 * len(X)))  # thete在这个里面是1维的@就行了

    return -np.sum(first + second) / len(X) + reg


# 梯度下降函数
def gradient_reg(theta, X, y, lamda):
    reg = theta[1:] * (lamda / len(X))
    reg = np.insert(reg, 0, values=0, axis=0)  ###加一行否则矩阵不匹配

    first = (X.T @ (sigmoid(X @ theta) - y)) / len(X)

    return first + reg


data = sio.loadmat('ex3data1.mat')
# print(data)
# print(data.keys())
######np.dot np.matmul a @ b 叫矩阵乘法  np.mulitply * 是对于元素乘法
raw_x = data['X']
raw_y = data['y']
print(raw_x.shape)  # 5000千个样本 400维 每个样本其实本来是20x20压缩到了400
plot_an_image(raw_x)
plot_100_image(raw_x)
X = np.insert(raw_x, 0, values=1, axis=1)  ##每一行多加第一位0 401维度了
y = raw_y.flatten()
lamda = 1
K = 10
theta_final = one_vs_all(X, y, lamda, K)  # 最终的10个分类器的theta
print(theta_final)
y_pred = predict(X, theta_final)  # 预测
acc = np.mean(y_pred == y)
print(acc)

效果图:
在这里插入图片描述
在这里插入图片描述
准确率:在这里插入图片描述
实验2 简单的前向传播过程

import numpy as np
import scipy.io as sio

# 实现sigmoid函数 激活函数
def sigmoid(z):
    return 1 / (1 + np.exp(-z))


data = sio.loadmat('ex3data1.mat')
raw_x = data['X']
raw_y = data['y']

X = np.insert(raw_x, 0, values=1, axis=1)
y = raw_y.flatten()

theta = sio.loadmat('ex3weights.mat')  # 直接拿到最佳参数
theta1 = theta["Theta1"]  # 第一层
theta2 = theta["Theta2"]  # 第二层参数
print(theta1.shape, theta2.shape)
a1 = X
z2 = X @ theta1.T  ##简单的前向传递
a2 = sigmoid(z2)
a2 = np.insert(a2, 0, values=1, axis=1) #每一层都有个 b 此默认1
z3 = a2 @ theta2.T
a3 = sigmoid(z3)
y_pred = np.argmax(a3, axis=1)
y_pred = y_pred + 1
acc = np.mean(y_pred == y)
print(acc)

效果图:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值