美文网首页
Tensorflow快餐教程(4) - 矩阵

Tensorflow快餐教程(4) - 矩阵

作者: Jtag特工 | 来源:发表于2018-04-24 21:34 被阅读60次

    矩阵

    矩阵的初始化

    矩阵因为元素更多,所以初始化函数更多了。光靠tf.linspace,tf.range之类的线性生成函数已经不够用了。

    可以通过先生成一个线性序列,然后再reshape成一个矩阵的方式来初始化。

    例:

    >>> g1 = tf.linspace(1.0,10.0,16)
    >>> g1
    <tf.Tensor 'LinSpace_6:0' shape=(16,) dtype=float32>
    >>> g2 = tf.constant(sess.run(tf.reshape(g1,[4,4])))
    >>> sess.run(g2)
    array([[ 1.       ,  1.6      ,  2.2      ,  2.8000002],
           [ 3.4      ,  4.       ,  4.6000004,  5.2000003],
           [ 5.8      ,  6.4      ,  7.       ,  7.6000004],
           [ 8.200001 ,  8.8      ,  9.400001 , 10.       ]], dtype=float32)
    >>> g2
    <tf.Tensor 'Const_29:0' shape=(4, 4) dtype=float32>
    

    tf.linspace生成了(16,)的一个向量,然后被reshape成(4,4)的矩阵。

    生成全0值的矩阵

    tf.zeros可以生成全0的矩阵,不指定类型时,默认为float32.

    >>> g7 = tf.zeros([4,5])
    >>> sess.run(g7)
    array([[0., 0., 0., 0., 0.],
           [0., 0., 0., 0., 0.],
           [0., 0., 0., 0., 0.],
           [0., 0., 0., 0., 0.]], dtype=float32)
    

    可以指定数据类型:

    >>> g8 = tf.zeros([10,10],dtype=tf.int32)
    >>> sess.run(g8)
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)
    

    生成全1的矩阵

    类似地,我们可以用tf.ones生成值全为1的矩阵。
    例:

    >>> g9 = tf.ones([8,2],dtype=tf.int64)
    >>> sess.run(g9)
    array([[1, 1],
           [1, 1],
           [1, 1],
           [1, 1],
           [1, 1],
           [1, 1],
           [1, 1],
           [1, 1]])
    

    将矩阵全部设成一个值

    tf.ones和tf.zeros其实是特例,tf.fill才是更通用的功能:

    >>> g10 = tf.fill([5,5],10.1)
    >>> sess.run(g10)
    array([[10.1, 10.1, 10.1, 10.1, 10.1],
           [10.1, 10.1, 10.1, 10.1, 10.1],
           [10.1, 10.1, 10.1, 10.1, 10.1],
           [10.1, 10.1, 10.1, 10.1, 10.1],
           [10.1, 10.1, 10.1, 10.1, 10.1]], dtype=float32)
    

    生成对角矩阵

    矩阵一个特点是经常是只有稀疏的值。最常用的就是对角阵,只有一条对角线上有值。
    例:

    >>> g11 =tf.diag([1,1,2,2])
    >>> sess.run(g11)
    array([[1, 0, 0, 0],
           [0, 1, 0, 0],
           [0, 0, 2, 0],
           [0, 0, 0, 2]], dtype=int32)
    

    除了生成对角阵,我们还可以从一个矩阵中将对角线值获取成一个向量:

    >>> g12 = tf.diag_part(g11)
    >>> sess.run(g12)
    array([1, 1, 2, 2], dtype=int32)
    >>> g12
    <tf.Tensor 'DiagPart:0' shape=(4,) dtype=int32>
    

    随机生成初始化值

    除了全0,全1,全确定值和对角线值,还有一种非常常用的方式就是生成随机值。
    我们可以按正态分布来生成初始值:

    >>> g13 = tf.random_normal([5,5])
    >>> sess.run(g13)
    array([[ 0.21010283,  1.083522  , -2.1688387 , -1.2340024 ,  0.9230036 ],
           [ 0.43592915, -0.7187195 , -1.3310403 ,  0.27570882,  1.3831469 ],
           [-0.42430717,  2.8005996 ,  1.1899991 ,  0.6987934 ,  1.6732428 ],
           [ 0.4975314 , -1.259698  ,  1.2508341 , -1.2581793 , -0.8776101 ],
           [ 0.49039882,  0.8129552 ,  1.2836359 , -0.3732389 , -2.034603  ]],
          dtype=float32)
    

    可以指定平均值和标准差,默认均值为0,标准差为1。默认的类型为float32,反正不支持整数。

    例:

    >>> g14 = tf.random_normal([3,8], mean=1.0, stddev=2.0, dtype=tf.float32)
    >>> sess.run(g14)
    array([[ 3.7580974 , -2.7150466 , -2.107638  ,  1.7130036 , -0.8702172 ,
            -1.0325654 ,  3.1230848 , -0.82150674],
           [-1.3860679 ,  0.03262603, -0.63146615, -0.71946084,  1.182011  ,
             0.34882843,  2.3536258 , -1.0503623 ],
           [-3.6498313 ,  0.4458651 ,  2.9859743 ,  2.153699  ,  3.8967788 ,
             1.895072  ,  3.5918627 ,  1.9855003 ]], dtype=float32)
    

    矩阵的转置

    将矩阵中的元素基于对角线对称交换,叫做矩阵的转置transpose。

    例:

    >>> g3 = tf.transpose(g2)
    >>> g3
    <tf.Tensor 'transpose_1:0' shape=(4, 4) dtype=float32>
    >>> sess.run(g3)
    array([[ 1.       ,  3.4      ,  5.8      ,  8.200001 ],
           [ 1.6      ,  4.       ,  6.4      ,  8.8      ],
           [ 2.2      ,  4.6000004,  7.       ,  9.400001 ],
           [ 2.8000002,  5.2000003,  7.6000004, 10.       ]], dtype=float32)
    

    1,4,7,10是对角线,在转置时保持不变。

    在非方阵的情况下,转置后对角线仍然保持不变。
    我们看一个2*3矩阵的例子:

    >>> g4 = tf.linspace(1.0,10.0,6)
    >>> g5 = tf.reshape(g4,[2,3])
    >>> sess.run(g5)
    array([[ 1.       ,  2.8      ,  4.6      ],
           [ 6.3999996,  8.2      , 10.       ]], dtype=float32)
    

    对角线是1和8.2.
    我们转置一下:

    >>> g6 = tf.constant(sess.run(tf.transpose(g5)))
    >>> sess.run(g6)
    array([[ 1.       ,  6.3999996],
           [ 2.8      ,  8.2      ],
           [ 4.6      , 10.       ]], dtype=float32)
    

    虽然从一个宽矩阵变成了高矩阵,但是对角线仍然是1和8.2.

    矩阵的数学运算

    加减运算

    两个行列相同的矩阵可以进行加减运算。
    例:

    >>> h01 = tf.random_normal([4,4])
    >>> h02 = tf.fill([4,4],1.0)
    >>> h03 = h01 + h02
    >>> sess.run(h03)
    array([[ 1.959749  ,  1.2833667 ,  0.12137735,  1.0297428 ],
           [ 1.3971953 , -0.0582509 ,  1.1770982 ,  2.154177  ],
           [-1.1314301 ,  1.6063341 , -1.2442939 ,  1.2752731 ],
           [ 1.3077021 ,  0.42679614,  2.9681108 ,  1.6179581 ]],
          dtype=float32)
    

    广播运算

    例:

    >>> h04 = h02 + 2.0
    >>> sess.run(h04)
    array([[3., 3., 3., 3.],
           [3., 3., 3., 3.],
           [3., 3., 3., 3.],
           [3., 3., 3., 3.]], dtype=float32)
    

    矩阵乘积

    "*"运算在矩阵乘法中,跟上节所讲一样,还是Hadamard积,就是对应元素的积,例:

    >>> h05 = tf.reshape(tf.linspace(1.0,10.0,16),[4,4])
    >>> sess.run(h05)
    array([[ 1.       ,  1.6      ,  2.2      ,  2.8000002],
           [ 3.4      ,  4.       ,  4.6000004,  5.2000003],
           [ 5.8      ,  6.4      ,  7.       ,  7.6000004],
           [ 8.200001 ,  8.8      ,  9.400001 , 10.       ]], dtype=float32)
    >>> h06 = tf.reshape(tf.linspace(1.0,16.0,16),[4,4])
    >>> sess.run(h06)
    array([[ 1.,  2.,  3.,  4.],
           [ 5.,  6.,  7.,  8.],
           [ 9., 10., 11., 12.],
           [13., 14., 15., 16.]], dtype=float32)
    >>> sess.run(h05 * h06)
    array([[  1.       ,   3.2      ,   6.6000004,  11.200001 ],
           [ 17.       ,  24.       ,  32.200005 ,  41.600002 ],
           [ 52.2      ,  64.       ,  77.       ,  91.200005 ],
           [106.600006 , 123.200005 , 141.00002  , 160.       ]],
          dtype=float32)
    

    我们也可以用matmul函数,或者"@"运算符计算矩阵相乘的结果:

    >>> h05 @ h06
    <tf.Tensor 'matmul:0' shape=(4, 4) dtype=float32>
    >>> sess.run(h05 @ h06)
    array([[ 65.200005,  72.8     ,  80.40001 ,  88.      ],
           [132.40001 , 149.6     , 166.80002 , 184.      ],
           [199.6     , 226.40002 , 253.20001 , 280.      ],
           [266.8     , 303.2     , 339.60004 , 376.      ]], dtype=float32)
    

    "@"是高版本Python中支持的操作,在tensorflow中重载它的函数为matmul。

    逆矩阵 Inverse Matrices

    定义I为单位对角矩阵,如果BA=I,那么我就说B是A的逆矩阵。可以通过matrix_inverse函数来获得逆矩阵,例:

    >>> i01 = tf.diag([1.0,2.0,3.0,4.0])
    >>> sess.run(i01)
    array([[1., 0., 0., 0.],
           [0., 2., 0., 0.],
           [0., 0., 3., 0.],
           [0., 0., 0., 4.]], dtype=float32)
    >>> i01_rev = tf.matrix_inverse(i01)
    >>> sess.run(i01_rev)
    array([[1.        , 0.        , 0.        , 0.        ],
           [0.        , 0.5       , 0.        , 0.        ],
           [0.        , 0.        , 0.33333334, 0.        ],
           [0.        , 0.        , 0.        , 0.25      ]], dtype=float32)
    

    我们来验算一下i01_rev与i01相乘是不是单位矩阵:

    >>> sess.run( i01_rev @ i01)
    array([[1., 0., 0., 0.],
           [0., 1., 0., 0.],
           [0., 0., 1., 0.],
           [0., 0., 0., 1.]], dtype=float32)
    

    果然是。

    对角阵比较特殊,还满足交换律:

    >>> sess.run( i01 @ i01_rev)
    array([[1., 0., 0., 0.],
           [0., 1., 0., 0.],
           [0., 0., 1., 0.],
           [0., 0., 0., 1.]], dtype=float32)
    

    求行列式的值以判断是否有逆矩阵

    我们学习线性代数知道,如果一个矩阵要想有逆矩阵,它的行列式一定不能为0。

    在Matlab和mathematica两大著名数学软件中,求行列式的函数名字很简单,就是det。
    Tensorflow因为是个库,所以名字比较长,叫tf.matrix_determinant.

    我们来看一个例子:

    >>> A1 = [[1,1,1],[1,-1,-1],[5,-2,2]]
    >>> A = tf.constant(A1, tf.float32)
    >>> A
    <tf.Tensor 'Const_3:0' shape=(3, 3) dtype=float32>
    >>> sess.run(A)
    array([[ 1.,  1.,  1.],
           [ 1., -1., -1.],
           [ 5., -2.,  2.]], dtype=float32)
    >>> d = tf.matrix_determinant(A)
    >>> sess.run(d)
    -8.0
    

    利用逆矩阵求解线性方程组

    假设有下列方程组,求解:

    x+y+z =1,
    x-y-z = 2,
    5x-2y+2z = 3
    

    这个题中的系数矩阵就是我们刚才例子中的矩阵,我们已经求得行列式值为-8不等于0,所以我们可以通过用系数矩阵的逆矩阵乘以常数向量的方式求解。

    >>> b = tf.constant([[1],[2],[3]],dtype=tf.float32)
    >>> b
    <tf.Tensor 'Const_4:0' shape=(3, 1) dtype=float32>
    >>> sess.run(b)
    array([[1.],
           [2.],
           [3.]], dtype=float32)
    >>> sess.run(tf.matmul(tf.matrix_inverse(A),b))
    array([[ 1.5000001],
           [ 0.875    ],
           [-1.3750001]], dtype=float32)
    

    最后求得,x=1.5, y=0.875, z = -1.375.

    相关文章

      网友评论

          本文标题:Tensorflow快餐教程(4) - 矩阵

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