3.吴恩达机器学习--神经网络

article/2025/9/19 14:26:52

本文旨在完成吴恩达机器学习的课后作业,搭建一个简单的神经网络来实现多分类问题,以手写数字识别为例。

1. 导入所需第三方库

from sklearn.datasets import load_digits
import numpy as np
import matplotlib.pyplot as plt

2. 加载手写数字的数据集

digits = load_digits()  # 加载数据集
data = digits.data       # 手写数字数据集:1797*64target = digits.target   # 数据集的标签:1797*1plt.gray()      
plt.matshow(digits.images[15])
plt.show()

在这里插入图片描述

3. 随机选出每一类的一个样本看看长什么样子

classes = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
num_classes = len(classes)
samples_per_class = 1# enumerate():将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标
for y, num_class in enumerate(classes):# 返回扁平化后矩阵中非零元素的位置(index)idxs = np.flatnonzero(target == y)     # 标签中为y的数据的索引idxs = np.random.choice(idxs, samples_per_class, replace=False)  # replace=False表示不可取相同数字for i, idx in enumerate(idxs):         # 将图形进行展示plt_idx = i * num_classes + y + 1plt.subplot(samples_per_class, num_classes, plt_idx)plt.imshow(digits.images[idx].astype('uint8'))plt.axis('off')    # 关闭坐标轴if i == 0:plt.title(num_class)
plt.show()

在这里插入图片描述

4. 定义激活函数

# 激活函数
def sigmoid(x):return 1 / (1 + np.exp(-x))# sigmoid函数的导数函数
def dsigmoid(x):return x * (1-x)

5. 实现两层神经网络

class NeuralNetwork(object):# 随机初始化参数def __init__(self, input_size, hidden_size, output_size):self.theta1 = 0.01 * np.random.randn(input_size, hidden_size)  #input_size * hidden_sizeself.b1 = np.zeros(hidden_size)self.theta2 = 0.01 * np.random.randn(hidden_size, output_size) #hidden_size * output_sizeself.b2 = np.zeros(output_size)# 定义损失函数def loss(self, X, y, lamda=0.01):num_train, num_feature = X.shape# forward前向传播a1 = X   # input layera2 = sigmoid(a1.dot(self.theta1) + self.b1)  # hidden layera3 = sigmoid(a2.dot(self.theta2) + self.b2)  # output layerloss = -np.sum(y * np.log(a3) + (1 - y) * np.log(1 - a3)) / num_trainloss += lamda * (np.sum(self.theta1 * self.theta1) + np.sum(self.theta2 * self.theta2)) / (2 * num_train)# backward, 后向传播过程delta3 = a3 - ydtheta2 = a2.T.dot(delta3) + lamda * self.theta2db2 = np.sum(delta3, axis=0)delta2 = delta3.dot(self.theta2.T) * dsigmoid(a2)dtheta1 = a1.T.dot(delta2) + lamda * self.theta1db1 = np.sum(delta2, axis=0)dtheta1 /= num_traindtheta2 /= num_traindb1 /= num_traindb2 /= num_trainreturn loss, dtheta1, dtheta2, db1, db2

  在神经网络中,我们可以有很多输出变量,我们的 h θ ( 𝑥 ) ℎ_\theta(𝑥) hθ(x) 是一个维度为 𝐾 𝐾 K 的向量,并且我们训练集中的因变量也是同样维度的一个向量,因此我们的代价函数会比逻辑回归更加复杂一些,为: h θ ( 𝑥 ) ∈ R 𝐾 , ( h θ ( 𝑥 ) ) 𝑖 = i t h o u t p u t ℎ_\theta(𝑥) ∈ ℝ^𝐾 ,{(ℎ_\theta(𝑥))}_𝑖 =i^{th}output hθ(x)RK(hθ(x))i=ithoutput
J ( θ ) = − 1 m [ ∑ i = 1 m ∑ k = 1 k y k ( i ) l o g ( h θ ( x ( i ) ) ) k + ( 1 − y k ( i ) ) l o g ( 1 − h θ ( x ( i ) ) ) k ] + λ 2 m ∑ l = 1 L − 1 ∑ i = 1 s l ∑ j = 1 s l + 1 ( θ j i ( l ) ) 2 J(\theta)=-\frac{1}{m}[\displaystyle \sum^m_{i =1}\displaystyle \sum^k_{k=1}{y_k^{(i)}log(h_\theta(x^{(i)}))_k+(1-y_k^{(i)})log(1-h_\theta(x^{(i)}))_k}]+\frac{\lambda}{2m}\displaystyle \sum^{L-1}_{l=1}\displaystyle \sum^{s_l}_{i =1}\displaystyle \sum^{s_l+1}_{j=1}{(\theta_{ji}^{(l)})^2} J(θ)=m1[i=1mk=1kyk(i)log(hθ(x(i)))k+(1yk(i))log(1hθ(x(i)))k]+2mλl=1L1i=1slj=1sl+1(θji(l))2
  我们希望通过代价函数来观察算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,我们都会给出 𝐾 𝐾 K 个预测,基本上我们可以利用循环,对每一行特征都预测 𝐾 𝐾 K 个不同结果,然后在利用循环在 𝐾 𝐾 K 个预测中选择可能性最高的一个,将其与 𝑦 𝑦 y 中的实际数据进行比较。
  正则化的那一项只是排除了每一层 θ 0 \theta_0 θ0 后,每一层的 θ \theta θ 矩阵的和。最里层的循环 𝑗 𝑗 j 循环所有的行(由 𝑠 𝑙 + 1 𝑠_𝑙 +1 sl+1 层的激活单元数决定),循环 𝑖 𝑖 i 则循环所有的列,由该层( 𝑠 𝑙 𝑠_𝑙 sl 层)的激活单元数所决定即: h θ ( 𝑥 ) ℎ_\theta(𝑥) hθ(x) 与真实值之间的距离为每个样本-每个类输出的加和,对参数进行 r e g u l a r i z a t i o n regularization regularization b i a s bias bias 项处理所有参数的平方和。

前向传播算法:从前往后一层一层推导(这里的函数g()是指sigmoid函数),直到最后一层的 h θ ( x ) h_\theta(x) hθ(x)(b为偏置项,图中未画出)
在这里插入图片描述
  现在,为了计算代价函数的偏导数 ∂ ∂ θ i j l J ( θ ) \frac{\partial}{\partial \theta_{ij}^{l}}J(\theta) θijlJ(θ) ,我们需要采用一种反向传播算法,也就是首先计算最后一层的误差,然后再一层一层反向求出各层的误差,直到倒数第二层。我们从最后一层的误差开始计算,误差是激活单元的预测 a k 4 a_k^4 ak4 与实际值 y k y^k yk 之间的误差( k = 1 : k k=1:k k=1:k)
  我们用 δ \delta δ 来表示误差,则: δ ( 4 ) = a ( 4 ) − y \delta^{(4)}=a^{(4)}-y δ(4)=a(4)y
  我们利用这个误差值来计算前一层的误差: δ ( 3 ) = ( θ ( 3 ) ) δ ( 4 ) ∗ g ′ ( z ( 3 ) ) \delta^{(3)}=(\theta^{(3)})\delta^{(4)}*g'(z^{(3)}) δ(3)=(θ(3))δ(4)g(z(3))。其中, g ′ ( z ( 3 ) ) g'(z^{(3)}) g(z(3)) s i g m o i d sigmoid sigmoid函数的导数, g ′ ( z ( 3 ) ) = a ( 3 ) ∗ ( 1 − a ( 3 ) ) g'(z^{(3)})=a^{(3)}*(1-a^{(3)}) g(z(3))=a(3)(1a(3))。而 ( ( θ ( 3 ) ) T ) δ ( 4 ) {((\theta^{(3)})}^T)\delta^{(4)} ((θ(3))T)δ(4)则是权重导致的误差的和。下一步是继续计算第二层的误差: δ ( 2 ) = ( θ ( 2 ) ) δ ( 3 ) ∗ g ′ ( z ( 2 ) ) \delta^{(2)}=(\theta^{(2)})\delta^{(3)}*g'(z^{(2)}) δ(2)=(θ(2))δ(3)g(z(2))
在这里插入图片描述

    # 训练def train(self, X, y, y_trian, X_val, y_val, learning_rate=0.01, num_iters = 10000):batch_size = 150num_train = X.shape[0]loss_list=  []accuracy_train = []accuracy_val = []for i in range(num_iters):# 每次随机的选取小样本batch set去训练batch_index = np.random.choice(num_train, batch_size, replace=True)X_batch = X[batch_index]y_batch = y[batch_index]y_train_batch = y_train[batch_index]loss, dtheta1, dtheta2, db1, db2 = self.loss(X_batch, y_batch)loss_list.append(loss)# update the weightself.theta1 += -learning_rate * dtheta1self.theta2 += -learning_rate * dtheta2self.b1 += -learning_rate * db1self.b2 += -learning_rate * db2if i % 500 == 0:print("i=%d,loss=%f" %(i,loss))#record the train accuracy and validation accuracytrain_acc = np.mean(y_train_batch==self.predict(X_batch))val_acc = np.mean(y_val==self.predict(X_val))accuracy_train.append(train_acc)accuracy_val.append(val_acc)return loss_list, accuracy_train, accuracy_val# 预测def predict(self, X_test):a2 = sigmoid(X_test.dot(self.theta1) + self.b1)a3 = sigmoid(a2.dot(self.theta2) + self.b2)y_pred = np.argmax(a3, axis=1)return y_predpass
6. 定义一下数值梯度,用于梯度检查

  当我们对一个较为复杂的模型(如神经网络)使用梯度下降法时,可能会存在一些不易察觉的错误,意味着虽然代价看上去在不断减小,但最终的结果可能并不是最优解。
  为了避免这样的问题,采用梯度的数值检验方法,其思想是:通过估计梯度值来检验我们计算的导数值是否真的是我们要求的。对梯度的估计的方法是在代价函数上沿着切线方向选择两个非常近的点,计算两个点的直线斜率来估计梯度。
在这里插入图片描述
  其代码实现为:

gradApprox = (J(theta + eps) - J(theta - eps)) / (2 * eps)

  当 θ \theta θ 是一个向量时,我们则需要对偏导数进行检验。因为代价函数的偏导数检验只针对一个参数的改变进行检验:
在这里插入图片描述
  对梯度检验的主要步骤如下:
    ①实现反向传播算法计算偏导矩阵 D i j l D_{ij}^l Dijl
    ②实现梯度检验计算近似梯度矩阵 g r a d A p p r o x gradApprox gradApprox
    ③确保它们的值相近
    ④关掉梯度检验,使用反向传播代码进行学习

from sklearn.preprocessing import LabelBinarizerdef eval_numerical_gradient(f, x, verbose=True, h=0.00001):""" a naive implementation of numerical gradient of f at x - f should be a function that takes a single argument- x is the point (numpy array) to evaluate the gradient at""" fx = f(x) # evaluate function value at original pointgrad = np.zeros_like(x)# iterate over all indexes in xit = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])while not it.finished:# evaluate function at x+hix = it.multi_indexoldval = x[ix]x[ix] = oldval + h # increment by hfxph = f(x) # evalute f(x + h)x[ix] = oldval - hfxmh = f(x) # evaluate f(x - h)x[ix] = oldval # restore# compute the partial derivative with centered formulagrad[ix] = (fxph - fxmh) / (2 * h) # the slopeif verbose:print(ix, grad[ix])it.iternext() # step to next dimensionreturn grad

7. 定义比较函数,用于两个梯度的对比

def rel_error(x, y):return np.max(np.abs(x - y) / (np.maximum(1e-8, np.abs(x) + np.abs(y))))

8. 模拟一个小网络,进行梯度检查,这样可以判断模型正确性

input_size = 4
hidden_size = 10
output_size = 3
num_train = 5

9. 初始化模型

 def init_toy_model():np.random.seed(0)return NeuralNetwork(input_size, hidden_size, output_size)

10. 初始化数据

def init_toy_data():np.random.seed(1)XX = 10 * np.random.randn(num_train, input_size)yy = np.array([0, 1, 2, 2, 1])return XX, yy

11. 通过反向传播计算参数

net = init_toy_model()
XX, yy = init_toy_data()
yy_label = LabelBinarizer().fit_transform(yy)loss,dtheta1,dtheta2,db1,db2 = net.loss(XX,yy_label)
f = lambda theta: net.loss(XX, yy_label)[0] #f(w) = loss
dtheta1_ = eval_numerical_gradient(f,net.theta1,verbose=False)
dtheta2_ = eval_numerical_gradient(f,net.theta2,verbose=False)
db1_ = eval_numerical_gradient(f,net.b1,verbose=False)
db2_ = eval_numerical_gradient(f,net.b2,verbose=False)print('%s max relative error: %e' % ('theta1', rel_error(dtheta1, dtheta1_)))
print('%s max relative error: %e' % ('theta2', rel_error(dtheta2, dtheta2_)))
print('%s max relative error: %e' % ('b1', rel_error(db1, db1_)))
print('%s max relative error: %e' % ('b2', rel_error(db2, db2_)))

theta1 max relative error: 1.812071e-08
theta2 max relative error: 3.958839e-10
b1 max relative error: 7.817713e-08
b2 max relative error: 5.888433e-11

12. 对神经网络进行训练

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
X = data
y = target
#normalized 数据集合0均值化
X_mean = np.mean(X,axis=0)
X -= X_mean
#分隔数据集合,分为train,val,test集合
X_data,X_test,y_data,y_test = train_test_split(X,y,test_size=0.2)
#split the train and tne validation
X_train = X_data[0:1000]
y_train = y_data[0:1000]
X_val = X_data[1000:-1]
y_val = y_data[1000:-1]print(X_train.shape,X_val.shape,X_test.shape)
#进行标签二值化,1-->[0,1,0,0,0,0,0,0,0,0]   5=[0,0,0,0,0,1,0,0,0,0]
y_train_label = LabelBinarizer().fit_transform(y_train)classify = NeuralNetwork(X.shape[1],100,10)
#数据准备完毕,开始训练
print('start')loss_list,accuracy_train,accuracy_val = classify.train(X_train,y_train_label,y_train,X_val,y_val)print('end')

(1000, 64) (436, 64) (360, 64)
start
i=0,loss=7.060120
i=500,loss=2.020329
i=1000,loss=1.208715
i=1500,loss=0.711440
i=2000,loss=0.608078
i=2500,loss=0.493830
i=3000,loss=0.404080
i=3500,loss=0.328199
i=4000,loss=0.307644
i=4500,loss=0.224095
i=5000,loss=0.224976
i=5500,loss=0.211779
i=6000,loss=0.183015
i=6500,loss=0.188465
i=7000,loss=0.179562
i=7500,loss=0.165125
i=8000,loss=0.164741
i=8500,loss=0.112698
i=9000,loss=0.127080
i=9500,loss=0.113350
end

13. 可视化训练结果

#可视化一下训练结果
import matplotlib.pyplot as pltplt.subplot(211)
plt.plot(loss_list)
plt.title('train loss')
plt.xlabel('iters')
plt.ylabel('loss')plt.subplot(212)
plt.plot(accuracy_train,label = 'train_acc',color = 'red')
plt.plot(accuracy_val,label = 'val_acc', color = 'black')
plt.xlabel('iters')
plt.ylabel('accuracy')
plt.legend(loc = 'lower right')plt.show()

在这里插入图片描述

14. 预测,并查看正确率

y_pred = classify.predict(X_test)
accuracy = np.mean(y_pred == y_test)
print("the accuracy is ",accuracy)

the accuracy is 0.9666666666666667

15. 随机挑选样本,查看预测结果

m,n = data.shape
example_size = 10
example_index = np.random.choice(m,example_size)
print(example_index)
for i, idx in enumerate(example_index):print("%d example is number %d,we predict it as %d"%(i,target[idx],classify.predict(X[idx,:].reshape(1,-1))))

[ 879 1544 1654 1692 1209 1647 1723 831 207 928]
0 example is number 3,we predict it as 3
1 example is number 8,we predict it as 8
2 example is number 2,we predict it as 2
3 example is number 5,we predict it as 5
4 example is number 7,we predict it as 7
5 example is number 6,we predict it as 6
6 example is number 1,we predict it as 1
7 example is number 0,we predict it as 0
8 example is number 2,we predict it as 2
9 example is number 3,we predict it as 3


http://chatgpt.dhexx.cn/article/64nt4o6p.shtml

相关文章

【机器学习】python实现吴恩达机器学习作业合集(含数据集)

学习感言: 从3.7第一天开始,到今天4.4,一个多月的时间,陆续完成了听课,代码实现和总结博客,过程些许艰难,作为一个刚入门的学习者,收获了很多。总结一下这一段时间的学习过程吧。后…

机器学习(吴恩达)简要总结

机器学习知识简要总结 这里写目录标题 机器学习知识简要总结梯度下降法矩阵和向量多元线性回归:正规方程Normal equationlogistic回归过拟合问题正则化卷积神经网络模型选择和训练、验证、测试集评价指标无监督学习主成分分析 监督学习:给算法一个数据集…

吴恩达机器学习--线性回归

文章目录 前言一、单变量线性回归1.导入必要的库2.读取数据3.绘制散点图4.划分数据5.定义模型函数6.定义损失函数7.求权重向量w7.1 梯度下降函数7.2 最小二乘法 8.训练模型9.绘制预测曲线10.试试正则化11.绘制预测曲线12.试试sklearn库 二、多变量线性回归1.导入库2.读取数据3.…

吴恩达《机器学习》笔记

引言:个人当前研究倾向是智慧医疗,旨在通过信息科技的数据处理手段,解决当前医学界的问题。 学习初步思路:在师兄的指导下,初步的学习计划为理论与竞赛并行,即一方面补充基础知识,另一方面竞赛实…

吴恩达机器学习课程笔记一

吴恩达机器学习课程笔记 前言监督学习---Supervised learning无监督学习---Unsupervised learning聚类异常检测降维 增强学习---Reinforcement learning Linear regression一些机器学习的名词参考博客损失函数参考博客梯度下降的实现学习率alpha的选择学习率过小学习率过大 线性…

吴恩达机器学习--学习笔记

1. Introduction 1.1 Welcome 如今机器学习被大规模应用于: 数据挖掘(网站点击,医学记录,生物学,工程)一些无法通过编程实现的功能(自动驾驶,手写识别,NLP&#xff0c…

【吴恩达机器学习2022学习笔记】课程1 -- 机器学习基础

吴恩达大佬又重新录了机器学习视频,借此机会重温并做笔记简单记录一下。课程共分成三门,首先是机器学习基础。 课程链接:https://www.bilibili.com/video/BV19B4y1W76i/?spm_id_from333.788.recommend_more_video.1&vd_source337295bc6e…

机器学习(吴恩达)

定义:计算机程序从经验E中学习,解决某一任务T,进行某一性能度量P,通过P测定在T上的表现因经验E而提高,以跳棋游戏为例,经验E就是程序与自己下几万次跳棋,任务T就是玩跳棋,性能度量P就…

【机器学习】吴恩达机器学习Deeplearning.ai

机器学习已经强大到可以独立成为人工智能的一个子领域。 可以通过对机器编程实现比如执行网络搜索、理解人类语言、通过x光诊断疾病,或制造自动驾驶汽车。 机器学习定义 一般来说,给一个算法学习的机会越多,它的表现就越好。 机器学习的两种…

吴恩达机器学习(一)—— 简介

机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科,专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的…

吴恩达机器学习课后作业

目录 01-linear regression线性回归预备知识单变量线性回归( 一个特征值)单变量线性回归( 多个特征值)单变量线性回归( 正规方程) 01-linear regression 线性回归预备知识 假设函数与损失函数&#xff1a…

【吴恩达机器学习笔记】七、神经网络

✍个人博客:https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 📣专栏定位:为学习吴恩达机器学习视频的同学提供的随堂笔记。 📚专栏简介:在这个专栏,我将整理吴恩达机器学习视频的所有内容的笔记&…

吴恩达机器学习 2022新版

2022吴恩达机器学习 第一周 一. 机器学习的定义二. 机器学习的分类2.1. 监督学习【回归算法】【分类算法】 三. loss function3.1.损失函数公式 四. 梯度下降4.1.梯度下降算法4.2.理解梯度下降4.3.学习率的选择4.5.如何计算导数项? 一. 机器学习的定义 Arthur Samu…

【经典】吴恩达《机器学习》课程

如果要推荐《机器学习》的学习课程,那必然首选吴恩达的《机器学习》课程,无论是国内还是国外,这是最火的机器学习入门课程,没有之一。吴恩达老师用易于理解、逻辑清晰的语言对机器学习算法进行介绍,无数新手正是通过这…

吴恩达机器学习系列课程笔记——第一章:什么是机器学习(Machine Learning)

1.1 欢迎 https://www.bilibili.com/video/BV164411b7dx?p1 第一节主要讲了什么是机器学习,机器学习能做些什么事情。 机器学习是目前信息技术中最激动人心的方向之一。在这门课中,你将学习到这门技术的前沿,并可以自己实现学习机器学习的…

机器学习——吴恩达

机器学习——吴恩达 inductionSupervised learningUnsupervised learning modelexamplehow to workdefine cost functiongradient descent for minimizing the cost functionGradient descent for linear regression Matrix and Vector定义运算multiple feature linear regress…

吴恩达—机器学习的六个核心算法

吴恩达,华裔美国人,是斯坦福大学计算机科学系和电子工程系副教授,人工智能实验室主任。吴恩达是人工智能和机器学习领域国际上最权威的学者之一。他是百度的前副总裁兼首席科学家,最受欢迎的机器学习在线课程之一的创建者&#xf…

【机器学习】机器学习笔记(吴恩达)

文章目录 中文笔记地址视频地址第1章 引言1.1 欢迎1.2 机器学习是什么1.3 监督学习1.4 无监督学习 第2章2.1 模型展示单变量线性回归 2.2 代价函数2.3-2.4 代价函数理解2.5-2.6 梯度下降算法,梯度下降算法理解 第3章第4章4.2 多元(多变量)梯度…

python编码无法使用turtle库_使用Turtle库教Python

Python是一种流行的基于文本的编程语言,程序员每天都在使用它。使用Turtle库(Turtle Library)教Python可以激发对STEM的兴趣。 Turtle库是用于控制机器人Turtle的功能的集合。这些命令可以与Python结合使用,以构建精美作品和原创游戏的程序。The Turtle …

turtle库的介绍

一、turtle库概述: turtle(海龟)库是turtle绘图体系python的实现; turtle绘图体系:1969年诞生,主要用于程序设计入门; turtle库是python的标准库之一;属于入门级的图形绘制函数库…