美文网首页
TensorFlow入门极简教程(五):Matrix

TensorFlow入门极简教程(五):Matrix

作者: Bobby0322 | 来源:发表于2019-03-05 12:51 被阅读0次

    矩阵

    矩阵的初始化

    矩阵因为元素更多,所以初始化函数更多了。光靠tf.linspace,tf.range之类的线性生成函数已经不够用了。
    可以通过先生成一个线性序列,然后再reshape成一个矩阵的方式来初始化。
    例:

    g1 = tf.linspace(1.0,10.0,16)
    print(g1)
    
    g2 = tf.constant(sess.run(tf.reshape(g1,[4,4])))
    print(g2)
    
    print(sess.run(g2))
    

    Tensor("LinSpace:0", shape=(16,), dtype=float32)
    Tensor("Const_4:0", shape=(4, 4), dtype=float32)
    [[ 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. ]]

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

    生成全0值的矩阵

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

    g7 = tf.zeros([4,5])
    print(sess.run(g7))
    

    [[0. 0. 0. 0. 0.]
    [0. 0. 0. 0. 0.]
    [0. 0. 0. 0. 0.]
    [0. 0. 0. 0. 0.]]

    可以指定数据类型:

    g8 = tf.zeros([10,10],dtype=tf.int32)
    print(sess.run(g8))
    

    [[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]]

    生成全1的矩阵

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

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

    [[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)
    print(sess.run(g10))
    

    [[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]]

    生成对角矩阵

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

    g11 = tf.diag([1, 1, 2, 2])
    print(sess.run(g11))
    

    [[1 0 0 0]
    [0 1 0 0]
    [0 0 2 0]
    [0 0 0 2]]

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

    g11 = tf.diag([1, 1, 2, 2])
    g12 = tf.diag_part(g11)
    print(sess.run(g12))
    print(g12)
    

    [1 1 2 2]
    Tensor("DiagPart:0", shape=(4,), dtype=int32)

    随机生成初始化值

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

    g13 = tf.random_normal([5, 5])
    print(sess.run(g13))
    

    [[ 0.25405225 0.44904745 -1.5468271 -0.835405 0.34003055]
    [ 1.9063158 1.1063404 1.2292559 -0.83762854 -0.02943441]
    [ 1.0375446 -1.0552472 -1.1881195 -0.3283966 0.812467 ]
    [ 0.55426043 -0.4972653 0.6334804 0.262765 0.0152008 ]
    [-1.7565544 -0.08327941 0.00738091 1.0632299 1.0563724 ]]

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

    g14 = tf.random_normal([3,8], mean=1.0, stddev=2.0, dtype=tf.float32)
    print(sess.run(g14))
    

    [[ 0.8916285 2.2956815 3.2678025 0.8529626 0.60075164 -1.9739718
    -0.01435184 0.9320197 ]
    [-1.6734488 2.5063558 3.7253733 -0.50914896 3.712727 2.1626568
    3.3386974 2.5216594 ]
    [ 2.1141312 2.620947 1.0357903 -0.64942276 2.6657484 0.28470635
    1.1828697 0.52249104]]

    矩阵的转置

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

    例:

    g1 = tf.linspace(1.0,10.0,16)
    g2 = tf.constant(sess.run(tf.reshape(g1,[4,4])))
    g3 = tf.transpose(g2)
    print(g3)
    print(sess.run(g3))
    

    Tensor("transpose:0", shape=(4, 4), dtype=float32)
    [[ 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. ]]

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

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

    g4 = tf.linspace(1.0, 10.0, 6)
    g5 = tf.reshape(g4,[2,3])
    print(sess.run(g5))
    

    [[ 1. 2.8 4.6 ]
    [ 6.3999996 8.2 10. ]]

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

    [[ 1. 2.8 4.6 ]
    [ 6.3999996 8.2 10. ]]
    [[ 1. 6.3999996]
    [ 2.8 8.2 ]
    [ 4.6 10. ]]

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

    矩阵的数学运算

    加减运算

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

    h01 = tf.random_normal([4,4])
    h02 = tf.fill([4,4],1.0)
    h03 = h01 + h02
    print(sess.run(h03))
    

    [[ 1.336098 1.8155456 2.3138926 0.81175077]
    [ 0.5926143 1.1805032 1.4293556 1.2853649 ]
    [ 3.34655 2.0858011 2.020999 0.4845155 ]
    [ 0.13710737 -0.1502235 0.58834183 2.3814282 ]]

    广播运算

    例:

    h01 = tf.random_normal([4,4])
    h02 = tf.fill([4,4],1.0)
    
    h04 = h02 + 2.0
    print(sess.run(h04))
    

    [[1. 1. 1. 1.]
    [1. 1. 1. 1.]
    [1. 1. 1. 1.]
    [1. 1. 1. 1.]]
    [[3. 3. 3. 3.]
    [3. 3. 3. 3.]
    [3. 3. 3. 3.]
    [3. 3. 3. 3.]]

    矩阵乘积

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

    h05 = tf.reshape(tf.linspace(1.0,10.0,16),[4,4])
    print(sess.run(h05))
    h06 = tf.reshape(tf.linspace(1.0,16.0,16),[4,4])
    print(sess.run(h06))
    print(sess.run(h05 * h06))
    

    [[ 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. ]]

    [[ 1. 2. 3. 4.]
    [ 5. 6. 7. 8.]
    [ 9. 10. 11. 12.]
    [13. 14. 15. 16.]]

    [[ 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. ]]

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

    h05 = tf.reshape(tf.linspace(1.0,10.0,16),[4,4])
    h06 = tf.reshape(tf.linspace(1.0,16.0,16),[4,4])
    print(h05 @ h06)
    print(sess.run(h05 @ h06))
    

    Tensor("matmul:0", shape=(4, 4), dtype=float32)

    [[ 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. ]]

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

    逆矩阵 Inverse Matrices

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

    i01 = tf.diag([1.0,2.0,3.0,4.0])
    print(sess.run(i01))
    
    i01_rev = tf.matrix_inverse(i01)
    print(sess.run(i01_rev))
    

    [[1. 0. 0. 0.]
    [0. 2. 0. 0.]
    [0. 0. 3. 0.]
    [0. 0. 0. 4.]]

    [[1. 0. 0. 0. ]
    [0. 0.5 0. 0. ]
    [0. 0. 0.33333334 0. ]
    [0. 0. 0. 0.25 ]]

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

    print(sess.run(i01_rev @ i01))
    

    [[1. 0. 0. 0.]
    [0. 1. 0. 0.]
    [0. 0. 1. 0.]
    [0. 0. 0. 1.]]

    果然是。
    对角阵比较特殊,还满足交换律:

    print(sess.run(i01 @ i01_rev))
    

    [[1. 0. 0. 0.]
    [0. 1. 0. 0.]
    [0. 0. 1. 0.]
    [0. 0. 0. 1.]]

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

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

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

    我们来看一个例子:

    A1 = [[1,1,1],[1,-1,-1],[5,-2,2]]
    A = tf.constant(A1, tf.float32)
    print(A)
    print(sess.run(A))
    
    d = tf.matrix_determinant(A)
    print(sess.run(d))
    

    Tensor("Const_4:0", shape=(3, 3), dtype=float32)

    [[ 1. 1. 1.]
    [ 1. -1. -1.]
    [ 5. -2. 2.]]

    -8.0

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

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

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

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

    A1 = [[1,1,1],[1,-1,-1],[5,-2,2]]
    A = tf.constant(A1, tf.float32)
    b = tf.constant([[1],[2],[3]],dtype=tf.float32)
    print(b)
    print(sess.run(b))
    
    print(sess.run(tf.matmul(tf.matrix_inverse(A),b)))
    

    Tensor("Const_5:0", shape=(3, 1), dtype=float32)

    [[1.]
    [2.]
    [3.]]

    [[ 1.5000001]
    [ 0.875 ]
    [-1.3750001]]

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

    相关文章

      网友评论

          本文标题:TensorFlow入门极简教程(五):Matrix

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