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