Matrix01-1:标量、向量与矩阵

2018-10-14  本文已影响53人  杨强AT南京

1、向量与矩阵的正确表示。

2、向量与矩阵的数学四则运算;

一、Python中的数据表示

    只考虑数字类型的数据(其他的类型与数学运算关系不大,这里不考虑)。

    (1)标量数据

                #标量数据

                scalar=20 

    (2)元组与列表

                #元组列表数据

                vector_1=[1,2,3,4]

                vector_2=(1,2,3,4)

                vector_3=np.array((1,2,3,4))

        Python语言内置了元组与列表的数据表述类型(其区别在于稳定与不稳定的区别),这今后主要使用科学计算库,所以使用了numpy中的封装类型。可以使用Python内置列表类型构造numpy的ndarray对象,ndarray可以提供更加强大的运算。

        注意:在元组与列表的使用选择上,建议使用列表(list)。

     (3)二维与多维列表

                    #2.二维与多维数据

                    matrix_1=[

                        [1,2,3], [4,5,6],[7,8,9]]

                    matrix_2=(

                        (1,2,3), (4,5,6), (7,8,9))

                    matrix_3=(

                        (1,2,3), (4,5,6), [7,8,9])

                    vector_4=np.array([

                        [1,2,3], [4,5,6],[7,8,9]])

     (4)元组、列表与标量的运算

            元组、列表与标量的运算只支持乘法(*),其他运算+、-、%、//、**都不支持。  

            #元组、列表与标量的运算      

            #print(5-truple_1)      #不支持+-

            #print(list_1+5)        #不支持+-

            print(5*truple_1)#5倍克隆 (1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4)

            print(list_1*5)#5倍克隆 [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]

            #print(5/truple_1)      #不支持/ //  %  **

            #print(list_1**5)        #不支持/ //  %  **

    (5)元组、列表间运算

        元组、列表间只支持+运算,其他运算(*、=、%、//、**)不支持 

            #元组、列表间的运算

            print(truple_1+truple_2)#(1, 2, 3, 4, 0.1, 0.2, 0.3, 0.4)

            #print(truple_1-truple_2)#不支持

            print(truple_1*truple_2)#不支持

 (6)向量与矩阵表示

使用一维ndarray表示向量,使用二维ndarray表示矩阵。由于内置元组与列表类型的运算比较简单,所以向量与矩阵,都使用numpy中的ndarray类型,不直接使用原元组与列表(元组与列表也支持一些数学四则运算)。从上面的运算我们可以看到这点。

        【结论】:

        【1】 不使用内置类型元组与列表表示向量与矩阵。

        【2】不使用一维ndarray对象表示矩阵。

        【3】矩阵使用二维ndarray对象,向量使用一维ndarray对象。

二、ndarray类型与向量、矩阵

numpy官网:http://www.numpy.org 

    numpy1.14.5的参考手册下载:【  下载  】

    numpy1.14.5的用户教程下载:【  下载  】

    1、ndarray类型

        (1)ndarray构造器说明

ndarray类型的构造器原型

        如果没有buffer参数,则只有shape,dtype与order三个参数被使用,其他参数没有作用。

        如果buffer参数被设置,则所有参数被使用,如果没有设置,则使用参数的默认值。

        参数说明:

           【shape】:数组的维数,也就是向量、矩阵的形状,用元组表示。

           【dtype】:数组的类型;

           【buffer】:数组的数据来源缓冲;

           【offset】:数缓冲数据的开始获取位置;

           【strides】:数据的步长,要求一个元组,元组对应数组维数的大小;

           【order】:  数组数据取值的优先顺序,C风格(行优先),Fortran风格(列优先)

        (2)构造器使用例子

构造器使用例子

            其中重点理解dtype,buffer,offset,strides,order。

            【dtype】需要是numpy中定义的数据类型,numpy定义的类型是使用python内置类型规范后重定义的。

            【bufder】一般对缓冲使用字节码,不考虑维数,都是线性的字节流,元组与列表表示为缓冲字节流,可以直接使用ndarray对象,代码中array是一个创建ndarray对象的函数工具(下面会介绍这些工具,理解ndarray对象的结构后,使用这些工具非常简便,根据不同情况可以提高效率)。

            【offset】是缓冲开始位置,单位是字节(byte),根据buffer中数据项大小确定。一般是buffer数据项大小的倍数,比如:0,8,16。

            【strides】是数组的取值步长,隔多长取值,单位是字节。 一般也是数据项大小的倍数,比如对int类型而言就是0,8,16等。类型元组,对应数组维数大小,表示对应纬度的取值不长。

            【order】表示取值的优先方式,「C」优先取行,「F」优先取列。

        (3)理解dtype数据类型

        在numpy中使用数据类型,兼容python的数据类型,同时定义了新的数据类型dtype。

在开发工具下numpy的数据类型区别

    下面是来自官方文档对numpy的数据类型的定义与说明:

        【bool类型】

bool类型

        【int类型】

int类型

        【无符号unsigned int类型】

unsigned int类型

        【float类型】

float类型

        【复数类型】

complex类型

        【对象类型】

object类型

        (4)理解strides

            【代码】

            v=np.ndarray(shape=(3,3),#数组的维数大小,矩阵、向量的形状

                    dtype=np.int,#数组的元素类型

                     buffer=np.array((1,2,3,4,5,6,7,8,9)),#数组数据的存放缓冲(字节码格式)

                     offset=0,#数组数据缓冲的有效开始位置

                     strides=(24,8),#数组数据缓冲的数据获取步长

                     order='C')#数组的显示格式,C风格与Fortran风格

            【理解】

                    其中strides=(24,8),因为buffer中使用的数据类型是int_,该类型大小是8,所以strides的数据是8的倍数。(24,8)表示行按照隔3个整数取值,列按照隔一个整取值。运行的结果为:

            [ [1 2 3]

              [4 5 6]

              [7 8 9] ]

                行的开始,按照3个间隔取值,就是1,4,7;列按照1个间隔取值分别从1,4,7后面开始取值。注意要确保缓冲是足够的。

                如果buffer是(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)

                问:strides=(32,8)构造什么样的数组?

                    [  [ 1 2 3],[ 5  6  7],[ 9 10 11]  ]

                问:strides=(32,24)构造什么样的数组?

                     [  [ 1 4 7],[ 5  8 11],[ 9 12 15]  ]

        附加:整数类型的数据类型长度获取结果:

        print(np.int_().itemsize)        #8

        print(np.byte().itemsize)        #1

        print(np.int8().itemsize)        #1

        print(np.int16().itemsize)        #2

        print(np.int32().itemsize)        #4

        print(np.int64().itemsize)        #8

        (5)理解C风格与Fortran风格

        【代码】

order使用F与C的区别

            【运行结果】

F风格结果:

        [  [1 3 5 7]

           [2 4 6 8]  ]

C风格结果

        [  [1 2 3 4]

           [5 6 7 8]  ]

        【理解】

        一般在设置strides的情况下,order就不起效果,因为是用户定制的取值风格。一但设置strides情况下,就采用两种取值风格:Fortran风格与C风格。

        【Fortran风格】:按照缓冲的顺序,从第1列,第2列,......,取值填充数组。

        【C风格】:按照缓冲的顺序,从第1行,第2行,......,取值填充数组。        

    2、ndarray构造工具

        (1)构建空、0与1值数组

empty,zeros参考

                【例子】

empty、zeros,eye的使用

                运行效果 

运行效果

        (2)使用已有数据构建数组

array参考

                【例子】略

        (3)使用数组范围构建数组

arange参考

                【例子】略

        (4)构建特殊矩阵

diag与tri参考

                【例子】略

        (5)直接使用数据构建矩阵

mat参考

                【例子】略

        (6)构建数据集数组

数据集数组构建工具参考

                【例子】略

        (7)构建字符数组

构建字符数组工具参考

                【例子】略

    提示:上述函数的使用比较简单,结果也是显而易见的,这里省略。

三、构建随机数组

        在numpy中提供了随机数组构建工具,如下:

使用随机分布构建数组

        实际上numpy.random提供更多的随机分布来构建数组或者矩阵,这里列出一部分,我们常用会使用uniformnormal(高斯正态分布)等。

        如果是专门针对矩阵,则官方参考文档列出如下相关参考:

矩阵库与矩阵快捷工具函数

四、向量与矩阵的四则运算

        上面讲述了数组对象ndarray对象的构建,在今后的数学运算中,我们都采用ndarray表示向量与矩阵。

        向量与矩阵本身区别不大,向量我们都称为行矩阵,或者列矩阵。

        向量与矩阵的运算我们考虑三类:标量与向量,向量与向量,向量的函数运算。

        首先构造一个向量矩阵与普通矩阵:

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

m_3_4=np.array([

        [1,2,3,4],

        [4,5,6,7],

        [7,8,9,10]

])

1、标量与ndarray对象的四则运算

        标量与ndarray对象运算,等于变量与数组的每个元素对应运算,+,-,*,/,//,**都支持。

        【代码】

标量与ndarray对象的四则运算

        【结果】

结果

2、ndarray对象与ndarray对象的四则运算

    (1)形状相同的运算

        1)要求形状不同的不能运算。

        2)形状相同可以运算,运算规则是ndarray数组对应元素相运算,运算支持+,-,*,/,//,**。

【例子】

向量与矩阵的加减

    对乘积来说就是数学中的【哈达马积(hadamard product)】

下面是乘法,除法,整除,求余,幂运算的例子

例子

    运行结果如下:

运行结果输出

        注意:

                1)ndarray的四则运算支持,就可以支持函数运算,因为大部分函数中使用的运算符号,还是基于经典的四则运算意义。

                2)所以在函数中使用向量与矩阵,一定要清楚对应的运算的含义。 

            尽管对普通意义的四则运算,只支持形状相同的向量与矩阵。对不同形状的矩阵或者向量,只对乘法赋予更多的定义:内积与Kronecker积。这两个积支持不同形状的向量与矩阵的运算,尽管还是有条件要求,换句话说就是:向量可以与矩阵做内积乘积与Kronecker积。

        三种乘积的表示如下:

内积,哈马达积,克罗内克积数学表示

    (2)内积

        【条件】

                被乘矩阵(向量)的列数必须与乘矩阵的行数相等。表示为公式就是如下:

矩阵内积

            注意:如果不写出表达式,则默认表示内积,因为内积是矩阵与向量最常见的运算,而不是哈马达积与克罗内克积。

        【运算规则】

                k×m的矩阵A与m×n的矩阵相乘B,得到k×n的新矩阵C,新矩阵的元素的值为:

内积的定义

矩阵的内积实现:dot函数介绍:

dot函数的参考

        【例子】

内积的三种使用方式

           运行结果:

内积的运算结果

    注意:在numpy库中也定义了哈马达积的集中实现方式。

    (3)Kronecker积(直积/张量积)

            该乘积方式以德国数学家利奥波德·克罗内克命名。Kronecker积的定义如下: 

Kronecker积的定义

            numpy的Kronecker积实现:kron函数参考

Kronecker积参考

        Kronecker积分左右,其定义就是每个元素都全部相乘,m×n形状的矩阵与p×q形状的矩阵做Kronecker积,得到形状为mp×nq的矩阵。

        【例子】

Kronecker积例子

        运行结果

Kronecker积运行结果

            提示:在数学上定义了两个矩阵的Khatri-Rao积。每种矩阵乘积都有其物理与现实意义,如果在深度学习中用到这个乘积,在详细阐述,目前还没有见到用过。    

 注意:

        1)我们这里关注Kronecker积的目的在于,在卷积神经网络的池化层会使用这类运算。

        2)numpy提供的outer函数与Kronecker积也有差异,后面专门主题说明。

本主题的代码下载:【 代码

本主题的公式下载:【 公式 】

上一篇下一篇

猜你喜欢

热点阅读