Tensor Manipulation

Tensor를 다루는 방법

array 차원 (rank) ndim

shape : 몇개의 element 가 있는가

Shape, Rank, Axis

[
    [
        [
            [1, 2, 3, 4  (axis = 3)] ,
            [5, 6, 7, 8],
            [9, 10, 11, 12]
        ],
        [
            [13, 14, 15, 16],
            [17, 18, 19, 20],
            [21, 22, 23, 24]
        ]
    ]
]
t = tf.constant([[ [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12] ], [ [13, 14, 15, 16],  [17, 18, 19, 20]
                                , [21, 22, 23, 24]] ])
tf.shape(t).eval()

array([1, 2, 3, 4], dtype=int32)

rank 4

Axis : 제일 안쪽에 있는 axis = 3, 바깥될수록 하나씩 감소한다.
또는 axis=-1로 하면 제일 안쪽에 있는 축을 가리킨다.

Matmul vs multiply

Matrix 곱을 할 때는 (2, 2) (2, 1) 이런식으로 끝에 있는 값과 앞에 있는 값이 일치해야 된다.

matrix1 = tf.constant([[1., 2.], [3., 4.]])
matrix2 = tf.constant([[1.], [2.]])
print("Metrix 1 shape", matrix1.shape)
print("Metrix 2 shape", matrix2.shape)
tf.matmul(matrix1, matrix2).eval()

Metrix 1 shape (2, 2)
Metrix 2 shape (2, 1)

array( [ [ 5.], [11.] ], dtype=float32)

(matrix1 * matrix2).eval()

array( [ [ 1., 2.], [6., 8.] ], dtype=float32)
실수로 이렇게 매트릭스를 곱해버리면 완전 이상한 값이 나온다.

Broadcasting : shape 이 다르더라도 연산을 할 수 있게 해주는 것. 가급적이면 앞 뒤 형태를 맞춰서 하는 것이 좋다.
(https://docs.spicy.org/doc/numpy/user/basics.broadcasting.html\

matrix1 = tf.constant([[1., 2.]])
matrix2 = tf.constant(3.)
(matrix1 + matrix2).eval()

array( [ [ 4., 5. ] ], dtype=float32)

matrix1 = tf.constant([[1., 2.]])
matrix2 = tf.constant([3., 4.])
(matrix1 + matrix2).eval()

array( [ [ 4., 6. ] ], dtype=float32)

matrix1 = tf.constant([[1., 2.]])
matrix2 = tf.constant([[3.], [4.]])
(matrix + matrix2).eval(session=sess)

array( [ [ 4., 5.],
[ 5., 6.] ], dtype=float32)

Reduce mean

tf.reduce_mean([1, 2], axis=0).eval()

1

x = [[1., 2.],
      [3., 4.]]
tf.reduce_mean(x).eval()

2.5 ... (전체평균)

tf.reduce_mean(x, axis=0).eval()

array( [2., 3.], dtype=float32) ... (열의 평균)

tf.reduce_mean(x, axis=1).eval()

array( [ 1.5, 3.5 ], dtype=float32) ... (행의 평균)

tf.reduce_mean(x, axis=-1).eval()

array( [ 1.5, 3.5], dtype=float32) ... -1 로 하면 제일 안에 있는 요소들의 평균을 낸다.

Reduce sum

x = [[1., 2.],
     [3., 4.]]
tf.reduce_sum(x).eval()

10.0

tf.reduce_sum(x, axis=0).eval()

array( [ 4., 6.], dtype=float32)

tf.reduce_sum(x, axis=-1).eval()

array( [ 3., 7.], dtype=float32)

tf.reduce_mean(tf.reduce_sum(x, axis=-1)).eval()

5.0 ... 각 합계를 구해서 평균내는 코드로 많이 사용한다.

Argmax : 제일 큰 것의 인덱스 넘버를 찾는다.

x = [[0, 1, 2],
      [2, 1, 0]]
tf.argmax(x, axis=0).eval()

array([1, 0, 0])

tf.argmax(x, axis=1).eval()

array([2, 0])

tf.argmax(x, axis=-1).eval()

array([2, 0])

Reshape : 제일 많이 사용하는 거라 중요하다.

t = np.array([[[0, 1, 2],
               [3, 4, 5],

              [[6, 7, 8],
               [9, 10, 11]])
t.shape

(2, 2, 3)

tf.reshape(t, shape=[-1, 3]).eval()

array( [ [ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])

tf.reshape(t, shape=[-1, 1, 3]).eval()

array( [ [ [ 0, 1, 2] ],
[ [ 3, 4, 5] ],
[ [ 6, 7, 8] ],
[ [ 9, 10, 11] ] )

tf.reshape(t, shape=[-1, 1, 3]).eval()

array( [ [ [ 0, 1, 2] ],
[ [ 3, 4, 5] ],
[ [ 6, 7, 8] ],
[ [ 9, 10, 11] ] ])

다른 형태의 Reshape : Squeeze, expand

tf.squeeze([[0], [1], [2]]).eval()

array( [ 0, 1, 2 ], dtype=int32)

tf.expand_dims([0, 1, 2], 1).eval()

array( [ [0],
[1],
[2] ], dtype=int32)

One Hot : One hot 을 하면 Rank가 하나 늘어난다. 이게 싫으면 reshape 를 해주면 된다.

 tf.one_hot([[0], [1], [2], [0]], depth=3).eval()

array( [ [ [ 1., 0., 0. ] ],
[ [ 0., 1., 0. ] ],
[ [ 0., 0., 1. ] ],
[ [ 1., 0., 0. ] ] ], dtype=float32)

t = tf.one_hot([[0], [1], [2], [0]], depth=3)
tf.reshape(t, shape=[-1, 3]).eval()

array( [ [ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.],
[ 1., 0., 0.] ], dtype=float32)

Casting : 타입 변환. True나 False 값을 Int로 바꾸는 거는 True의 개수를 셀 때 많이 사용한다.

tf.cast([1.8, 2.2, 3.3, 4.9], tf.int32).eval()

array( [ 1, 2, 3, 4 ], dtype=int32)

tf.cast([True, False, 1 == 1, 0 == 1], tf.int32).eval()

array( [1, 0, 1, 0], dtype=int32)

Stack

x = [1, 4]
y = [2, 5]
z = [3, 6]

tf.stack([x, y, z]).eval()

array( [ [ 1, 4 ],
[ 2, 5 ],
[ 3, 6 ] ], dtype=int32)

tf.stack([x, y, z], axis=1).eval()

array( [ [ 1, 2, 3 ],
[ 4, 5, 6 ], dtype=int32)

One and Zeros like : 어떤 Tensor과 같은 형태를 만들어서 0이나 1로 채워넣고 싶을 때 사용한다.

x = [[0, 1, 2],
     [2, 1, 0]]

tf.ones_like(x).eval()

array( [ [ 1, 1, 1 ],
[ 1, 1, 1 ], dtype=int32)

tf.zeros_like(x).eval()

array( [ [ 0, 0, 0 ],
[ 0, 0, 0 ] ], dtype=int32)

Zip : 복수 개의 tensor를 for 루프 같은 것을 통해서 한번에 처리하고자 할 때 사용할 수 있다.

for x, y in zip([1, 2, 3], [4, 5, 6]):
    print(x, y)

1 4
2 5
3 6

for x, y, z in zip([1, 2, 3], [4, 5, 6], [7, 8, 9]):
    print(x, y, z)

1 4 7
2 5 8
3 6 9

results for ""

    No results matching ""