美文网首页
Matrix01-1:标量、向量与矩阵

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

作者: 杨强AT南京 | 来源:发表于2018-10-14 16:56 被阅读53次

    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积也有差异,后面专门主题说明。

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

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

    相关文章

      网友评论

          本文标题:Matrix01-1:标量、向量与矩阵

          本文链接:https://www.haomeiwen.com/subject/dpqkaftx.html