吴恩达《机器学习》学习笔记十一——神经网络代码

  • 数据准备
  • 神经网络结构与代价函数·
  • 初始化设置
  • 反向传播算法
  • 训练网络与验证

课程链接:https://www.bilibili.com/video/BV164411b7dx?from=search&seid=5329376196520099118

数据集链接:https://pan.baidu.com/s/1ZkB_RW9ehEV_w6ryZT64Ag
提取码:8utg

这次笔记,我们将再次处理手写数字数据集,第八次笔记是使用的多分类逻辑回归算法,这次使用反向传播的前馈神经网络。 我们将通过反向传播算法实现神经网络成本函数和梯度计算的非正则化和正则化版本。 我们还将实现随机权重初始化和使用网络进行预测的方法。

由于使用的数据集和上次代码练习是相同的,我们将重新使用代码来加载数据。

数据准备

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmat
data = loadmat('ex4data1.mat')
data


由于我们以后需要这些(并将经常使用它们),我们先来创建一些有用的变量。

X = data['X']
y = data['y']X.shape, y.shape #看下维度


我们也需要对我们的y标签进行一次one-hot 编码。 one-hot 编码将类标签n(k类)转换为长度为k的向量,其中索引n为“hot”(1),而其余为0。 Scikitlearn有一个内置的实用程序,我们可以使用这个。

from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(sparse=False)
y_onehot = encoder.fit_transform(y)
y_onehot.shape


one-hot编码后的y会变成如下图这种形式:

对应的类别位置设置为1,其余位置全部是0。

看一下变换前后的标签尺寸:

y[0], y_onehot[0,:]

神经网络结构与代价函数·

我们要为此练习构建的神经网络具有与我们的实例数据**(400 +偏置单元)大小匹配的输入层,25个单位的隐藏层(带有偏置单元的26个),以及一个输出层, 10个单位对应我们的一个one-hot编码类标签**。 其网络结构如下图所示,其中输入层有400+1个神经元,隐藏层有25+1个神经元,输出层有10个神经元:

我们需要实现的第一件是评估一组给定的网络参数的损失的代价函数。神经网络的代价函数若不带正则项就是如下所示的表达式:

带正则项的话表达式就会变成:

先定义一下sigmoid函数:

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

如果要计算代价函数则需要前向传播来计算预测结果h(x),所以要先定义前向传播的函数:

def forward_propagate(X, theta1, theta2):# INPUT:参数值theta,数据X# OUTPUT:当前参数值下前项传播结果# TODO:根据参数和输入的数据计算前项传播结果# STEP1:获取样本个数m = X.shape[0]# STEP2:实现神经网络正向传播 a1 =np.insert(X, 0, values=np.ones(m), axis=1) #给X矩阵插入一行1元素z2 =a1 * theta1.Ta2 =np.insert(sigmoid(z2), 0, values=np.ones(m), axis=1)  #注意插入1元素z3 = a2 * theta2.Th = sigmoid(z3)return a1, z2, a2, z3, h
def cost(params, input_size, hidden_size, num_labels, X, y, lamda):# INPUT:神经网络参数,输入层维度,隐藏层维度,训练数据及标签,正则化参数# OUTPUT:当前参数值下的代价函数# TODO:根据上面的公式计算代价函数# STEP1:获取样本个数m = X.shape[0]# STEP2:将矩阵X,y转换为numpy型矩阵X =np.matrix(X)y =np.matrix(y)# STEP3:从params中获取神经网络参数,并按照输入层维度和隐藏层维度重新定义参数的维度theta1 = np.matrix(np.reshape(params[:hidden_size * (input_size + 1)], (hidden_size, (input_size + 1))))theta2 = np.matrix(np.reshape(params[hidden_size * (input_size + 1):], (num_labels, (hidden_size + 1))))# STEP4:调用前面写好的前项传播函数a1, z2, a2, z3, h = forward_propagate(X, theta1, theta2)# STEP5:初始化代价函数J = 0# STEP6:根据公式计算代价函数for i in range(m):  #遍历每个样本first_term =np.multiply(-y[i,:], np.log(h[i,:]))second_term = np.multiply((1 - y[i,:]), np.log(1 - h[i,:]))J += np.sum(first_term - second_term)J = J / m# STEP7:计算代价函数的正则化部分J += (float(lamda) / (2 * m)) * (np.sum(np.power(theta1[:,1:], 2)) + np.sum(np.power(theta2[:,1:], 2)))return J

初始化设置

将网络的层数、神经元数目、正则化系数、参数等一些变量进行初始化设置。

# 初始化设置
input_size = 400
hidden_size = 25
num_labels = 10
lamda = 1# 随机初始化完整网络参数大小的参数数组
params = (np.random.random(size=hidden_size * (input_size + 1) + num_labels * (hidden_size + 1)) - 0.5) * 0.25m = X.shape[0]
X = np.matrix(X)
y = np.matrix(y)# 将参数数组解开为每个层的参数矩阵
theta1 = np.matrix(np.reshape(params[:hidden_size * (input_size + 1)], (hidden_size, (input_size + 1))))
theta2 = np.matrix(np.reshape(params[hidden_size * (input_size + 1):], (num_labels, (hidden_size + 1))))theta1.shape, theta2.shape


这边显示的是theta1和theta2的维度,要结合与输入X的维度理解。

a1, z2, a2, z3, h = forward_propagate(X, theta1, theta2)
a1.shape, z2.shape, a2.shape, z3.shape, h.shape


观察一下这些中间变量的维度。

代价函数在计算假设矩阵h之后,应用代价函数来计算y和h之间的总误差。

cost(params, input_size, hidden_size, num_labels, X, y_onehot, lamda)


这是初始时刻用随机设置的参数计算得到的初始代价函数值。

反向传播算法

接下来是反向传播算法。 反向传播参数更新计算将减少训练数据上的网络误差。 我们需要的第一件事是计算我们之前创建的Sigmoid函数的梯度的函数。

def sigmoid_gradient(z):return np.multiply(sigmoid(z), (1 - sigmoid(z)))

它所作的工作如下面这幅图所示,后面的计算中会经常使用到这个函数,所以提前写出来:

现在我们准备好实施反向传播来计算梯度。 由于反向传播所需的计算是代价函数中所需的计算过程,我们实际上将扩展代价函数以执行反向传播并返回代价和梯度。梯度的计算过程如下所示:



def backprop(params, input_size, hidden_size, num_labels, X, y, lamda):# INPUT:神经网络参数,输入层维度,隐藏层维度,训练数据及标签,正则化参数# OUTPUT:当前参数值下的代价函数# TODO:根据上面的公式计算代价函数# STEP1:获取样本个数m = X.shape[0]# STEP2:将矩阵X,y转换为numpy型矩阵X = np.matrix(X)y = np.matrix(y)# STEP3:从params中获取神经网络参数,并按照输入层维度和隐藏层维度重新定义参数的维度theta1 = np.matrix(np.reshape(params[:hidden_size * (input_size + 1)], (hidden_size, (input_size + 1))))theta2 = np.matrix(np.reshape(params[hidden_size * (input_size + 1):], (num_labels, (hidden_size + 1))))# STEP4:调用前面写好的前项传播函数a1, z2, a2, z3, h = forward_propagate(X, theta1, theta2)# STEP5:初始化J = 0delta1 = np.zeros(theta1.shape)delta2 = np.zeros(theta2.shape)# STEP6:计算代价函数(调用函数)for i in range(m):  #遍历每个样本first_term =np.multiply(-y[i,:], np.log(h[i,:]))second_term = np.multiply((1 - y[i,:]), np.log(1 - h[i,:]))J += np.sum(first_term - second_term)J = J / m# STEP7:实现反向传播(这里用到的公式请参考原版作业PDF的第5页)for t in range(m):  #遍历每个样本a1t = a1[t,:]  # (1, 401)z2t = z2[t,:]  # (1, 25)a2t = a2[t,:]  # (1, 26)ht = h[t,:]  # (1, 10)yt = y[t,:]  # (1, 10)d3t = ht - ytz2t = np.insert(z2t, 0, values=np.ones(1)) # (1, 26) d2t = np.multiply((theta2.T * d3t.T).T, sigmoid_gradient(z2t))  # (1, 26)delta1 = delta1 + (d2t[:,1:]).T * a1tdelta2 = delta2 + d3t.T * a2t# STEP8:加入正则化delta1[:,1:] = delta1[:,1:] + (theta1[:,1:] * lamda) / mdelta2[:,1:] =  delta2[:,1:] + (theta2[:,1:] * lamda) / m  # STEP9:将梯度矩阵转换为单个数组grad = np.concatenate((np.ravel(delta1), np.ravel(delta2)))return J, grad

反向传播计算最难的部分(除了理解为什么我们正在做所有这些计算)是获得正确矩阵维度。 顺便说一下,你容易混淆了A * B与np.multiply(A,B)使用。 基本上前者是矩阵乘法,后者是元素乘法(除非A或B是标量值,在这种情况下没关系)。 无论如何,让我们测试一下,以确保函数返回我们期望的。

J, grad = backprop(params, input_size, hidden_size, num_labels, X, y_onehot, lamda)
J, grad.shape


参数的数量应该为40125+2610=10285个,验证无误。

训练网络与验证

我们终于准备好训练我们的网络,并用它进行预测。 这与以往的具有多类逻辑回归的练习大致相似。

from scipy.optimize import minimize# minimize the objective function
fmin = minimize(fun=backprop, x0=params, args=(input_size, hidden_size, num_labels, X, y_onehot, lamda), method='TNC', jac=True, options={'maxiter': 250})
fmin


用训练好的参数来进行预测:

X = np.matrix(X)
theta1 = np.matrix(np.reshape(fmin.x[:hidden_size * (input_size + 1)], (hidden_size, (input_size + 1))))
theta2 = np.matrix(np.reshape(fmin.x[hidden_size * (input_size + 1):], (num_labels, (hidden_size + 1))))a1, z2, a2, z3, h = forward_propagate(X, theta1, theta2)
y_pred = np.array(np.argmax(h, axis=1) + 1)
y_pred

最后再计算一下准确率:

correct = [1 if a == b else 0 for (a, b) in zip(y_pred, y)]
accuracy = (sum(map(int, correct)) / float(len(correct)))
print ('accuracy = {0}%'.format(accuracy * 100))

吴恩达《机器学习》学习笔记十一——神经网络代码相关推荐

  1. 吴恩达机器学习学习笔记第七章:逻辑回归

    分类Classification分为正类和负类 (规定谁是正谁是负无所谓) 吴恩达老师举例几个例子:判断邮箱是否是垃圾邮箱 一个在线交易是否是诈骗 一个肿瘤是良性的还是恶性 如果我们用之前学习的lin ...

  2. 吴恩达深度学习笔记——卷积神经网络(Convolutional Neural Networks)

    深度学习笔记导航 前言 传送门 卷积神经网络(Convolutional Neural Networks) 卷积神经网络基础(Foundations of Convolutional Neural N ...

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

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

  4. 吴恩达机器学习学习笔记第二章:单变量线性回归

    模型描述: 训练集(training set):是监督学习中独有的概念,由我们人喂给电脑的既有既有特征x又有结果y的数据.下图x是房子面积 ,y是房屋对应的价格 符号记法解释: (x^(1),y^(1 ...

  5. 吴恩达深度学习笔记——卷积神经网络(CNN)

    目录 一.计算机视觉(Computer vision) 二.边缘检测示例(Edge detection example) 三.更多的边缘检测内容(More edge detection) 四.Padd ...

  6. 吴恩达“机器学习”——学习笔记六

    最优边界分类器(最大间隔分类器)(续学习笔记五) 在线性分类器中,我们要找到一个边界线,使得几何间隔最大,即: ||w||在几何间隔中是无关紧要的,这里取1,使得几何间距和函数间距一致. 但是这个并不 ...

  7. 吴恩达机器学习学习笔记第九章:神经网络学习

    课时①非线性假设 通过说Linear Regression和logistic Regression的不足来引入神经网络: 安卓告诉我们神经网络并不是什么新玩意儿,老早就有了,但是他经过了一段低迷期直到 ...

  8. 吴恩达机器学习学习笔记第一章:绪论初识机器学习

    一.   什么是机器学习(Machine Learning)?   首先学习的对象是电脑 学习指的其实就是算法 机器学习就是基于数据基于算法从数据中去提炼对事物的认知和规律 掌握了这些特征和规律后就可 ...

  9. 吴恩达深度学习笔记(21)-神经网络的权重初始化为什么要随机初始化?

    随机初始化(Random+Initialization) 当你训练神经网络时,权重随机初始化是很重要的. 对于逻辑回归,把权重初始化为0当然也是可以的. 但是对于一个神经网络,如果你把权重或者参数都初 ...

  10. 吴恩达机器学习 学习笔记 之 一 监督学习和无监督学习

    一. 1-1 welcome 1-2 什么是机器学习--Machine Learning 机器学习尚无明确定义,现有的定义有: (1)Field of study that gives compute ...

最新文章

  1. 一种关注于重要样本的目标检测方法!
  2. 静态html文件js读取url参数
  3. 关于JAVA_HOME, CLASSPATH和PATH的设置
  4. 【Augmented Reality】增强现实中的光学透射式头盔显示器的标定深入
  5. 06-列空间和零空间
  6. python随机生成中文句子_python – 如何使用NLTK从诱导语法中生成句子?
  7. Vue:默认的App.vue
  8. WebScraper for Mac(网站数据抓取工具)
  9. idea调试jdk源码
  10. C# Web服务器控件FileUpload()上传文件
  11. MariaDB安装配置
  12. 「解决方案」运维、能耗、网关整体解决方案
  13. neo4j java json_如何将Neo4j JSON转换为Java Object
  14. 数学在机器学习中的重要性
  15. VBA语言入门:一些简单语法在Excel应用实例
  16. Oracle-count加条件计算
  17. 具统计全国淘宝村增至211个 直接就业超过28万人
  18. 计算机毕业设计(22)java毕设作品之在线教育视频点播学习系统
  19. 鼎阳数字示波器上位机软件EasyScopeX安装和使用教程
  20. 《金属切削原理》教学大纲

热门文章

  1. 天天说常识推理,究竟常识是什么?
  2. 论文浅尝 | 问题多样性对于问答的帮助
  3. 论文浅尝 - SWJ | 基于知识图谱和注意力图卷积神经网络的可解释零样本学习
  4. 论文浅尝 | 基于知识库的类型实体和关系的联合抽取
  5. 论文浅尝 | 近期论文精选
  6. 头插法和尾插法创建链表(有无头结点)
  7. ASP.NET Core Web API 索引 (更新Identity Server 4 视频教程)
  8. MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)
  9. Delphi Format函数功能及用法详解
  10. 软件生存周期文档系列 之 6.用户操作手册