使用python实现深度神经网络 2(转)

https://blog.csdn.net/oxuzhenyi/article/details/73026796

导数与梯度、矩阵运算性质、科学计算库numpy

一、实验介绍

1.1 实验内容

虽然在实验一中我想尽量少的引入(会让人放弃继续学习的)数学概念,但我似乎还是失败了。不过这几乎是没有办法的事,要想真正学会深度学习,没有一定的数学基础(高等数学、线性代数、概率论、信息论等),(几乎)是不可能的。学深度学习不学其中的原理你可能能够学会搭建模型,但当模型出了问题或者无法训练出好的结果时,不懂原理是很难调试的。

不过话说回来,要想理解深度学习中的基本概念(而不是想要在深度学习领域做研究),要学的数学知识也不是很难。你应该很快就能掌握这些知识。

所以本次实验课,我们介绍本课程会涉及到的数学知识以及在之后“ 图片英文字母识别”的项目中要用到的python numpy模块。

警告:本次实验介绍的数学知识只是为了让你更好地理解本课程中的相关概念,有些地方不够严谨,请勿等同于数学教科书参考

1.2 实验知识点

  • 导数、偏导、梯度、链式法则
  • 矩阵运算基本法则
  • numpy基本运算介绍

1.3 实验环境

  • python 2.7
  • numpy 1.12.1

二、实验步骤

2.1 导数、偏导、梯度、复合函数求导链式法则

2.1.1 函数值随自变量的变化速率--导数

高中数学里面我们已经学过,函数值随自变量的变化速率是导数。导数衡量的,其实是一个变量对函数值影响能力的大小。导数值越大,则该变量每改变一点对最终函数值的影响越大。且导数值为正时,代表自变量增大时函数值增大,反之若导数值为负,则自变量增大时函数值减小。

常见函数的导函数:

原函数f 导函数f‘
任何常数 0
x 1
e^x e^x
x^2 2*x
1/x -1/x^2
ln(x) 1/x

2.1.2 从单变量到多变量--偏导

上面我们列举的都是只有一个自变量的函数,如果自变量有多个,如何求导数呢?比如对于函数f=x+y,怎样衡量x和y分别对函数值f的影响快慢呢?

数学上引入了偏导的概念,对一个多变量函数f,求f对其中一个自变量x的偏导很简单,就是将与x无关的其他自变量视为常亮,再使用单变量求导的方法去求导。得到的即为f对x的偏导。比如:

令f=x+2y, 则f对x求偏导的结果为1,对y求偏导的结果为2。

令f=x*y, 则f对x求偏导结果为y,对y求偏导结果为x。

2.1.3 多变量函数变化最快的方向--梯度

2.1.1 中我们提到了,对单变量函数来说,导数值的正负代表自变量对函数值影响的“方向”:变大或变小。那对于多变量函数来说,如何表达这个方向呢?这就引入了梯度的概念:

梯度是一个向量,向量长度与自变量的个数相等,且其中的每一个元素为函数对于对应变量求偏导的值。

比如对于函数f=x*y, 其梯度向量为(y,x),
对于具体的自变量的值,比如x=1,y=1的点,其梯度向量就为(1,1),
又比如x=10,y=-20点,其梯度向量就为(-20,10)

梯度作为一个向量,指向的是使函数值增大最快的方向(回想第一次实验中的损失函数图,梯度所指的方向是向上的)。

2.1.4 复合函数求导链式法则

上面我们讲的求导数和求偏导,都是对于“简单函数”,对于“复合函数”,比如下面这样的函数:

  1. f1(x)=1/x

  2.  

    f2(x)=e^x

  3.  

  4.  

    f=f1(f2(x))

f函数是一个复合函数,它由f1f2函数“串联”而来。其中f1的输入是f2的输出。

对于复合函数求导,一种方法是将复合函数展开,比如对于上面的函数, 得到f=1/(e^x),然后再根据简单函数求导法则对自变量求导。过程如下:
f‘ = -1/((e^x)^2)*((e^x)‘) = -(e^x)/((e^x)^2) = -1/(e^x)

即 f‘ = -1/(e^x)

其实,在上面的求导过程中,我们已经使用了求导链式法则(chain
rule)
,只是你没有察觉而已。求导链式法则让我们可以一部分一部分地,对复合函数求导,而不用放在一起求。这对于编程来说十分重要,它使得对复合函数求导变得十分简单。

但是这里描述起来可能稍显复杂。以f为例,当我们需要对自变量x求导时,我们可以先将f2(x)看做一个自变量f2,先让f1f2求导,得到第一部分导函数-1/(f2^2),再让f2x求导,得到第二部分导函数e^x。求好之后,直接将两部分导数乘起来,即得到最终复合函数整体的导数。不过要先使用实际的表达式替换掉第一部分导数中的f2,
即第一部分导数为-1/((e^x)^2), 第二部分导数为e^x。两部分乘起来就得到了最终正确的-1/(e^x)

现在你可能觉得这个链式法则是复杂乏味的,但是下一次实验你会发现链式法则真是太强大了。实际上,我们最后实现的深度神经网络,就是不断在运用求导链式法则。

2.2 矩阵及其基本运算性质

如果你上过本科线性代数课程,你十有八九会对矩阵没有什么感觉,甚至对这么一个运算法则十分奇怪的东西感到厌恶。但我希望你今后能改变对矩阵、对线性代数的看法,不要让糟糕的教材和老师糟糕的ppt毁掉线性代数可能带给你的巨大的提升自己(是的,这并不夸张)的机会。矩阵其实非常非常非常有用,在现代科学的每一个角落,几乎都能看到矩阵的身影,深度学习中更是如此。

限于篇幅,本节只会介绍必要的矩阵相关知识,线性代数中的更多东西,请你通过其他途径学习(推荐使用英文教材学习)。

2.2.1 矩阵的表达形式

一个m*n的矩阵为一个m行n列的数组,比如:

a是一个3*2的矩阵,b是一个2*3的矩阵,c是一个3*1的矩阵,d是一个1*2的矩阵。

其中,c只有一列,我们也可以称c列向量d只有一行,我们也可以称d行向量。本课程中,对于向量,默认都是指列向量

2.2.2 矩阵的运算法则

  1. 矩阵的数乘运算

    一个标量(你可以直接理解为一个数字)乘以矩阵,得到的结果为矩阵中的每个元素和该标量相乘,如下图:

  1. 矩阵的转置运算

    转置运算通过在矩阵右上角添加一“撇”表示。

    转置就是矩阵翻转一下,转置会改变矩阵的形状。注意观察转置是绕着哪个轴翻转的。

  2. 矩阵之间的加减法

    矩阵之间的加减法要求参与运算的两个矩阵尺寸相同,运算的结果等于两个矩阵对应元素相加减。

  3. 矩阵魔力的来源--矩阵之间的乘法

    矩阵的乘法有些复杂,但在第一讲实验中你已经见过它了。矩阵的乘法其实就是代表了一个线性方程组参数和自变量如何结合的过程(矩阵乘法还有更多丰富的含义,如有兴趣,请你自己去探索)。

    矩阵乘法的具体规则就是,第一个矩阵中的第i行的所有元素,与第二个矩阵中的第j列的所有元素,分别相乘之后再求和,得到结果矩阵中第i行第j列的元素。

    上面的描述只看一遍很难弄懂,请你结合图片中的例子仔细揣摩。

    矩阵乘法首先要求参与乘法运算的两个矩阵的尺寸能够“兼容”,具体的要求就是,第一个矩阵的列数与第二个矩阵的行数必须相同。你可以观察图片中的示例,第一个矩阵的列数都是2,第二个矩阵的行数也都是2,这样才能保证“第一个矩阵中的第i行所有元素”与“第二个矩阵中第j列的所有元素”能够一一对应。

    矩阵乘法运算得到的结果矩阵,其行数等于第一个矩阵的行数,其列数等于第二个矩阵的列数。
    矩阵乘法不满足交换律!!首先,交换两个矩阵的位置之后它们的尺寸不一定能够兼容,然后即使兼容,运算得到的结果也不一定与原来相同。你可以自己随便举几个例子试一下。

2.3 科学计算库 numpy

实现我们的深度神经网络,需要进行很多数学运算,尤其是矩阵运算。而你也看到了,矩阵的(乘法)运算很复杂,自己编程实现比较困难而且容易出错。为了解决这些问题,我们将会使用python中的科学计算库numpy。有了numpy,
我们的代码将大大简化,同时速度也会有很大提升。

2.3.1 使用numpy

实验楼环境已经安装了numpy,使用import语句导入即可,为了简化代码,导入后我们将numpy命名为np。

  1. import numpy as np

  2.  

    print numpy.__version__ # 查看numpy版本

当你使用numpy进行计算时,在terminal 里输入top命令,你会发现有多个"一样"的python进程在运行,这是因为numpy会自动进行多进程运算,提高计算速度。

>> top

以下的实例请你自己在python shell 中一起实验一遍。

2.3.2 numpy基本数据类型

numpy中的数据类型被称为ndarray(即 N-dimensional array,多维数组),创建一个ndarray很简单:

  1. import numpy as np

  2.  

  3.  

    array=np.array([1,2,3],dtype=np.uint8)

  4.  

    print array

即向np.array()函数传入一个python列表即可。注意dtype参数是可选的,它指定了生成的数组的数据长度和类型,这里是长度为8bit的无符号整数。

2.3.3 快速创建矩阵

mat1=np.zeros((2,3))

np.zeros()快速创建一个指定维度的全0矩阵,注意传进去的参数是一个tuple

2.3.4 numpy中的高维矩阵

"矩阵"一般指有行和列的“二维”矩阵,但numpy还支持高维矩阵,比如下面:

  1. nd=np.zeros((1,2,3,4))

  2.  

    print nd.shape

  3.  

    print nd.size

nd就可以看作是一个1x2x3x4尺寸的高维矩阵。ndarray.shape保存的是数组的“形状”,也就是高维矩阵每一维的长度。ndarray.size保存的是数组每一维长度相乘的结果,即数组元素的个数。

2.3.5 标准矩阵运算

首先你要注意的是,numpy中的运算和数学中的运算不是完全一样的,实际上,numpy不仅为我们提供了标准运算,还提供了更多方便我们编程的运算类型和特性。

我们先来看标准的矩阵运算:

  1. 标量与矩阵相乘

    1. scalar=2

    2.  

      mat=np.zeros((2,3))

    3.  

      mat1=scalar*mat

  2. 矩阵转置
    1. mat=np.zeros((2,3))

    2.  

      tmat=mat.T

    3.  

      print mat.shape, tmat.shape

    4.  

      mat3=np.array((1,2,3))

    5.  

      tmat3=mat3.T

    6.  

      print mat3.shape, tmat3.shape

    对于二维矩阵,ndarray.T即可得到其转置。对于高维矩阵,ndarray.T会将维度的顺序完全翻转(顺序逆过来)。

  3. 矩阵相加
    1. mat1=np.array([[1,2],[3,4]])

    2.  

      mat2=np.array([[1,0],[0,1]])

    3.  

      mat3=mat1+mat2

  4. 矩阵乘法
    1. mat1=np.array([[1,2],[3,4]])

    2.  

      mat2=np.array([[5,6],[7,8]])

    3.  

      mat3=mat1.dot(mat2)

    注意这里有一些变化,矩阵相乘不能直接使用*号,而是通过.dot()函数。

2.3.6 扩展运算

numpy内置的扩展运算用起来非常方便。

  1. 两个矩阵的对应元素相乘

    1. mat1=np.array([[1,2],[3,4]])

    2.  

      mat2=np.array([[5,6],[7,8]])

    3.  

      mat=mat1*mat2

    注意相乘的两个矩阵尺寸必须相同。

  2. 标量与矩阵相加
    1. scalar=2

    2.  

      mat=np.array([[1,2],[3,4]])

    3.  

      mat1=scalar+mat

    标量与矩阵相加就相当于对矩阵的每个元素都加上该标量。

  3. 操纵高维矩阵的维度
    1. mat3=np.zeros((1,2,3))

    2.  

      tmat3=mat3.transpose(0,2,1)

    3.  

      print mat3.shape,tmat3.shape

    有时候,我们想要改变高维矩阵维度的顺序,但ndarray.T只能完全翻转,无法满足我们的需求,这个时候就可以调用ndarray.transpose(),其参数代表原本矩阵的维度重新排列的顺序。所以这里的例子实际上相当于第0维不变,第1第2维交换。

  4. broad cast--拓宽操作
    国内有些人将numpy的broadcast按照字面意思翻译为“广播”,这样显然是容易误导人的。根据broadcast在numpy中的实际作用,我个人更倾向于将braodcast 拆开并翻译为“拓宽”(向更宽的矩阵拓展)。其具体作用为:
    当两个矩阵进行加/减法运算时,比如我们需要将一个列向量加到一个矩阵的每一列上,由于尺寸不同,无法直接进行运算,一种直接粗暴的做法就是循环遍历矩阵的每一列,再把列向量加到每一列上,这样代码会显得很复杂。而 numpy会自动执行的broadcast操作则会先将列向量“拓宽”成一个相同尺寸的矩阵,且其每一列都是对原列向量的复制,然后再进行运算。如下:
    1. mat1=np.zeros((3,2))

    2.  

      vec=np.array([[1],[2],[3]])

    3.  

      print mat1+vec

    对于行向量和高维矩阵也是如此。
    更详细的描述,请参考numpy文档:broadcasting

2.3.7 杂项操作

本节介绍一些后面的项目会用到的其他杂项操作

  1. 生成随机数据

    rannum=np.random.randn(5,10)
    

    这里的np.random.randn()函数生成一个指定尺寸的矩阵,且矩阵中的所有数字符合正态分布(normal distribution)

    1. l=[1,2,3]

    2.  

      np.random.shuffle(l)

    3.  

      print l

    np.random.shuffle()函数可以接收python list或者numpy ndarray,并将数组中的元素随机打乱。

  2. 对矩阵求和
    1. a=np.random.randn(3,2)

    2.  

      print np.sum(a)

    np.sum()函数会对矩阵中的所有元素求和。

  3. numpy中的“轴(axis)”
    我们之前使用“维度”描述矩阵的形状,这样容易和之前提到的向量的维度(长度)混淆,numpy中有另一个概念叫做“轴(axis)”与这里所说的“维度”很类似,指的是对一个矩阵进行操作时,所执行的“方向”。文字不太好描述,我们结合实例来理解:
    1. a=np.random.zeros((3,2))

    2.  

      a=a+1

    3.  

      print np.sum(a,axis=0)

    4.  

      print np.sum(a,axis=1)

    np.sum(a,axis=0)就是对矩阵a,在第一个“轴”上求和,具体效果就是对矩阵的每一列求和。np.sum(a,axis=1)就是对矩阵a,在第二个“轴”上求和,具体效果就是对矩阵的每一行求和。
    这里可能不太好理解,请自己多举几个例子实验一下。

  4. e的指数
    1. a=np.random.randn(3,2)

    2.  

      print np.exp(a)

    np.exp()返回输入中的每个元素x都对e求指数的结果。

  5. 求一个数组中最大元素的下标
    1. a=[1,2,3,4,3,2,1]

    2.  

      print np.argmax(a)

    np.argmax()返回一个python列表或numpy ndarray中的最大元素的下标。

三、实验总结

本次实验的内容已经被我尽量精简了,只保留了后面的项目当中会用到的内容。我希望你能尽量理解上面的知识,虽然对于一些人来说这可能有些难,但数学最能体现人类的智慧不是吗,数学是深度学习,乃至人工智能得以发展的重要基础。
如果你觉得本次实验内容太简单或者写的不够好,请自行查阅其他资料学习相关内容。

本次实验,我们学习了:

  1. 导数衡量一个自变量对函数值影响的能力大小。
  2. 偏导用来衡量多变量函数中的一个自变量对函数值影响的能力大小。
  3. 梯度是一个向量,指向函数值增大最快的方向。
  4. 链式法则是指,对于复合函数,其求导过程可以一部分一部分地进行,再“链接”起来。
  5. 可以认为向量是矩阵的一种特殊形式。
  6. 矩阵乘法与线性方程组关系密切。
  7. numpy库中的ndarray可以很方便的用来进行矩阵运算。

四、课后作业

    1. 请你回想本次实验所讲的每一个知识点,确保你对它们都理解的很清楚。
    2. numpy是一个非常著名的,经常被使用的库,值得你进一步学习,请你自己继续学习numpy中的其他东西:numpy官网

原文地址:https://www.cnblogs.com/quietwalk/p/9287176.html

时间: 2024-07-31 09:01:57

使用python实现深度神经网络 2(转)的相关文章

如何利用Python和深度神经网络锁定即将流失的客户?业绩过十万!

烦恼 作为一名数据分析师,你来到这家跨国银行工作已经半年了. 今天上午,老板把你叫到办公室,面色凝重. 你心里直打鼓,以为自己捅了什么篓子.幸好老板的话让你很快打消了顾虑. 客户主要分布在法国.德国和西班牙. 你手里掌握的信息,包括他们的年龄.性别.信用.办卡信息等.客户是否已流失的信息在最后一列(Exited). 请选择左侧的Python 3.6版本下载安装. 其次是新建文件夹,起名为demo-customer-churn-ann,并且从这个链接下载数据,放到该文件夹下. 点击界面右上方的Ne

使用python实现深度神经网络 4(转)

https://blog.csdn.net/oxuzhenyi/article/details/73026807 使用浅层神经网络识别图片中的英文字母 一.实验介绍 1.1 实验内容 本次实验我们正式开始我们的项目:使用神经网络识别图片中的英文字母. 激动人心的时刻到了,我们将运用神经网络的魔力,解决一个无法使用手工编程解决的问题.如果你(自认为)是一个程序员,本次实验结束后,你将变得与其他只会手工编写程序的程序员不同. 1.2 实验知识点 "浅层"与"深度"的区别

使用Python中NetworkX包绘制深度神经网络结构图

1 """ 使用Python中NetworkX包绘制深度神经网络结构图 """ 2 # 导入相应包 3 import networkx as nx 4 import matplotlib.pyplot as plt 5 6 # 创建DAG 7 G = nx.DiGraph() 8 9 # 创建结构图顶点列表 10 vertex_list = ['v'+str(i) for i in range(1, 22)] 11 12 # 添加结构图顶点 13

深度神经网络可视化工具集锦

深度神经网络可视化工具集锦 雷锋网按:原文作者zhwhong,载于作者的个人博客,雷锋网(公众号:雷锋网)经授权发布.  TensorBoard:TensorFlow集成可视化工具 GitHub官方项目:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tensorboard TensorBoard 涉及到的运算,通常是在训练庞大的深度神经网络中出现的复杂而又难以理解的运算. 为了更方便 TensorFlow 程序的理

深度学习实践系列(2)- 搭建notMNIST的深度神经网络

如果你希望系统性的了解神经网络,请参考零基础入门深度学习系列,下面我会粗略的介绍一下本文中实现神经网络需要了解的知识. 什么是深度神经网络? 神经网络包含三层:输入层(X).隐藏层和输出层:f(x) 每层之间每个节点都是完全连接的,其中包含权重(W).每层都存在一个偏移值(b). 每一层节点的计算方式如下: 其中g()代表激活函数,o()代表softmax输出函数. 使用Flow Graph的方式来表达如何正向推导神经网络,可以表达如下: x: 输入值 a(x):表示每个隐藏层的pre-acti

深度神经网络全面概述:从基本概念到实际模型和硬件基础

国内镜像:苏轶然-CSDN 论文地址:https://arxiv.org/pdf/1703.09039.pdf 原文地址:机器之心-深度神经网络全面概述:从基本概念到实际模型和硬件基础 目前,包括计算机视觉.语音识别和机器人在内的诸多人工智能应用已广泛使用了深度神经网络(deep neural networks,DNN).DNN 在很多人工智能任务之中表现出了当前最佳的准确度,但同时也存在着计算复杂度高的问题.因此,那些能帮助 DNN 高效处理并提升效率和吞吐量,同时又无损于表现准确度或不会增加

从图像到知识:深度神经网络实现图像理解的原理解析

摘要:本文将详细解析深度神经网络识别图形图像的基本原理.针对卷积神经网络,本文将详细探讨网络中每一层在图像识别中的原理和作用,例如卷积层(convolutional layer),采样层(pooling layer),全连接层(hidden layer),输出层(softmax output layer).针对递归神经网络,本文将解释它在在序列数据上表现出的强大能力.针对通用的深度神经网络模型,本文也将详细探讨网络的前馈和学习过程.卷积神经网络和递归神经网络的结合形成的深度学习模型甚至可以自动生

深度神经网络DNN的多GPU数据并行框架 及其在语音识别的应用

深度神经网络(Deep Neural Networks, 简称DNN)是近年来机器学习领域中的研究热点,产生了广泛的应用.DNN具有深层结构.数千万参数需要学习,导致训练非常耗时.GPU有强大的计算能力,适合于加速深度神经网络训练.DNN的单机多GPU数据并行框架是腾讯深度学习平台的一部分,腾讯深度学习平台技术团队实现了数据并行技术加速DNN训练,提供公用算法简化实验过程.对微信语音识别应用,在模型收敛速度和模型性能上都取得了有效提升--相比单GPU 4.6倍加速比,数十亿样本的训练数天收敛,测

深度神经网络在量化交易里的应用 之二 -- 用深度网络(LSTM)预测5日收盘价格

    距离上一篇文章,正好两个星期. 这边文章9月15日 16:30 开始写. 可能几个小时后就写完了.用一句粗俗的话说, "当你怀孕的时候,别人都知道你怀孕了, 但不知道你被日了多少回 " ,纪念这两周的熬夜,熬夜.  因为某些原因,文章发布的有点仓促,本来应该再整理实验和代码比较合适.文章都是两个主要作用: 对自己的工作总结, 方便自己回顾和分享给有兴趣的朋友. 不说废话了, 进入正题. 本次的课题很简单, 深度神经网络(AI)来预测5日和22日后的走势. (22日尚未整理, 不