일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 알고리즘 공부방법
- 장고란
- getline
- 표준 입출력
- Django란
- 시간복잡도
- c++
- scanf
- 입/출력
- 엑셀
- vscode
- UI한글변경
- string 메소드
- 입출력 패턴
- string 함수
- double ended queue
- k-eta
- iOS14
- correlation coefficient
- 백준
- 프레임워크와 라이브러리의 차이
- 매크로
- 구조체와 클래스의 공통점 및 차이점
- 연결요소
- EOF
- 이분그래프
- 자료구조
- Django의 편의성
- Django Nodejs 차이점
- 2557
- Today
- Total
Storage Gonie
모두를 위한 딥러닝 제24강 ML lab 08: Tensor Manipulation(연산함수) 본문
모두를 위한 딥러닝 제24강 ML lab 08: Tensor Manipulation(연산함수)
Storage Gonie 2018. 9. 29. 20:58* 키워드 : slicing, shape, rank, axis, matmul, broadcasting, reduce_mean, reduce_sum, argmax, reshape, squeeze, expand_dims, one_hot, cast, stack, ones_like, zeros_like, zip
#-*- coding: euc-kr -*-
# https://www.tensorflow.org/api_guides/python/array_ops
import tensorflow as tf
import numpy as np
import pprint
tf.set_random_seed(777) # for reproducibility
pp = pprint.PrettyPrinter(indent=4)
sess = tf.InteractiveSession()
# array & slicing 1
- slicing은 [a:b]를 사용한 것을 말함
- [a:b] 에서 a는 무조건 시작 index가 되지만, b는 b바로 앞 index까지를 의미한다. (단, b자리에 아무것도 없는 경우는 예외.)
- rank는 맨 앞의 연속적인 ' [ '의 개수를 세면 됨.
- shape은 rank 숫자의 개수대로 모양을 가지며, 맨 뒤에 채워질 값은 맨 안쪽의 element 개수, 그 앞엔 그 다음 바깥의 element 개수 ...
t = np.array([0., 1., 2., 3., 4., 5., 6.])
pp.pprint(t)
# array([0., 1., 2., 3., 4., 5., 6.])
print(t)
# [0. 1. 2. 3. 4. 5. 6.]
print(t.ndim) # rank
# 1
print(t.shape) # shape
# (7,)
print(t[0], t[1], t[-1])
# (0.0, 1.0, 6.0)
print(t[2:5], t[4:-1])
# (array([2., 3., 4.]), array([4., 5.]))
print(t[:2], t[3:])
# (array([0., 1.]), array([3., 4., 5., 6.]))
# array & slicing 2
t = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.], [10., 11., 12.]])
pp.pprint(t)
#array([[ 1., 2., 3.],
# [ 4., 5., 6.],
# [ 7., 8., 9.],
# [10., 11., 12.]])
print(t.ndim) # rank
# 2
print(t.shape) # shape
# (4, 3)
print(t[:2])
#[[1. 2. 3.]
# [4. 5. 6.]]
print(t[1:3])
#[[4. 5. 6.]
# [7. 8. 9.]]
# Tensor에서의 Shape, Rank, Axis
- axis는 rank의 수의 개수만큼 존재한다고 보면됨.
- axis는 축이라고 부르며, rank가 4 이면 4개의 축이 0부터 존재.
- axis는 뒤에 나오는 tf.reduce_mean() 혹은 tf.argmax() 사용법을 보면 이해됨. 연산의 방향을 결정하는 요소임.
t = tf.constant([1,2,3,4])
print(tf.shape(t).eval())
# [4]
print(tf.rank(t).eval())
# 1
t = tf.constant([[1,2],
[3,4]])
print(tf.shape(t).eval())
# [2 2]
print(tf.rank(t).eval())
# 2
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]]]])
print(tf.shape(t).eval())
# [1 2 3 4]
print(tf.rank(t).eval())
# 4
[ # axis = 0
[ # axis = 1
[ # axis = 2
[1,2,3,4], # axis = 3 or -1
[5,6,7,8],
[9,10,11,12]
],
[
[13,14,15,16],
[17,18,19,20],
[21,22,23,24]
]
]
]
# matmul(행렬곱) vs. multiply(일반곱)
- 텐서로 행렬곱셈을 수행할 때는 일반 '*'이 아닌 tf.matmul()를 사용해야한다. 그렇지 않으면 의도치 않은 결과가 나올 수 있다.
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
# shape(1,2) * shape(2,1) = shape = (1,1)에 대한 예상했던 결과
print(tf.matmul(matrix1, matrix2).eval())
#[[12.]]
# shape(1,2) * shape(2,1) = shape = (1,1)에 대한 의도치 않았던 결과, 뒷 행렬의 각각의 원소가 앞 행렬에 각각 곱해진 결과.
print((matrix1*matrix2).eval())
#[[6. 6.]
# [6. 6.]]
# broadcasting에서 주의할 점
- broadcasting에 대한 이해가 잘 된 상태에서 사용하면 좋긴 하지만 되도록 행렬의 크기를 맞춰준 다음에 사용하는게 좋음.
- 참고링크 : https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
# case1) 브로드캐스팅을 사용하지 않은 경우
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2., 2.]])
print((matrix1+matrix2).eval())
# [[5. 5.]]
# case2) 뒷 값이 앞 행렬과 똑같은 크기로 맞춰주어 덧셈이 이루어짐
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant(3.)
print((matrix1+matrix2).eval())
# [[6. 6.]]
# case3) rank가 다를 경우도 행렬의 덧셈 가능
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([2., 2.])
print((matrix1+matrix2).eval())
# [[5. 5.]]
# case4) 뒷 행렬, 앞 행렬 모두에서 extend가 이뤄나 덧셈이 이루어짐
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
print((matrix1+matrix2).eval())
#[[5. 5.]
# [5. 5.]]
# reduce_mean
- int형을 연산하면 결과 값도 int로 나오니 주의하자. 항상 숫자뒤에 '.' 을 찍어줘야 float형으로 인식하여 소수점까지 결과가 나옴.
- axis를 인자로 주어 연산의 방향을 결정할 수 있다.
- axis가 0일때 세로, axis가 1일때 가로 방향이라고 지칭하였지만 실은 가로세로가 아닌 [] 영역으로 구분한다.
x = [1, 2]
print(tf.reduce_mean(x).eval()) # 주의! int형을 연산하면 결과 값도 int로 나와서 예상과 다를 수 있다.
# 1
x = [[1., 2.],
[3., 4.]]
print(tf.reduce_mean(x).eval()) # axis를 인자로 주지 않으면 모든 원소를 더한 뒤 평균을 구한다.
# 2.5
print(tf.reduce_mean(x, axis=0).eval()) # axis 0 방향인 세로 방향으로 연산
# [2. 3.]
print(tf.reduce_mean(x, axis=1).eval()) # axis 1 방향인 가로 방향으로 연산
# [1.5, 3.5]
print(tf.reduce_mean(x, axis=-1).eval()) # 바로 위의 연산과 같음
# [1.5, 3.5]
# reduce_sum
- reduce_mean과 사용방법은 같음
x = [[1., 2.],
[3., 4.]]
print(tf.reduce_sum(x).eval()) # axis를 인자로 주지 않으면 모든 원소를 더함
# 10.0
print(tf.reduce_sum(x, axis=0).eval()) # axis 0 방향인 세로 방향으로 연산
# [4., 6.]
print(tf.reduce_sum(x, axis=1).eval()) # axis 1 방향인 가로 방향으로 연산
# [3., 7.]
print(tf.reduce_sum(x, axis=-1).eval()) # 바로 위의 연산과 같음
# [3., 7.]
print(tf.reduce_mean(tf.reduce_sum(x, axis=-1)).eval())
# 5.0
# argmax
- 비교 대상 요소중에서 큰쪽의 index를 알려줌
x = [[0, 1, 2],
[2, 1, 0]]
print(tf.argmax(x).eval()) # default로 axis가 0일 때의 결과를 줌
# [1 0 0]
print(tf.argmax(x, axis=0).eval()) # axis 0 방향인 세로 방향에서 큰 값을 가지는 index를 결과로 줌
# [1 0 0]
print(tf.argmax(x, axis=1).eval()) # axis 1 방향인 가로 방향에서 큰 값을 가지는 index를 결과로 줌
# [2 0]
print(tf.argmax(x, axis=-1).eval()) # 바로 위의 연산과 같음
# [2 0]
# reshape
t = np.array([[[0, 1, 2],
[3, 4, 5]],
[[6, 7, 8],
[9, 10, 11]]])
print(t.ndim) # rank
# 3
print(t.shape)
# (2, 2, 3)
print(tf.reshape(t, shape=[-1, 3]).eval()) # 2차원으로 변경, 보통 맨 뒤의 숫자는 원래 shape의 맨 뒤 숫자와 같음, 맨앞의 -1은 알아서 하란뜻
#[[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
print(tf.reshape(t, shape=[-1, 1, 3]).eval()) # 두개로 나뉘어 있던 것을 합침
#[[[ 0 1 2]]
# [[ 3 4 5]]
# [[ 6 7 8]]
# [[ 9 10 11]]]
# squeeze
- squeeze는 짜내다 라는 뜻인데 [ ]를 제거해서 하나로 만들어 줌.
print(tf.squeeze([[0], [1], [2]]).eval()) # squeeze는 짜내는 뜻인데 [ ]를 제거해서 하나로 만들어줌
# [0, 1, 2]
# expand_dims
- 한 차원이 늘어남
- 뒤의 인자는 axis 값으로 추정됨.
# case1) 뒤의 인자가 0이면 shape의 맨 앞에 1이 생기면서 한차원 늘어난다.
print(tf.expand_dims([0, 1, 2], 0).eval()) # shape(3) -> (1,3)
#[[0 1 2]]
print(tf.expand_dims([[0, 1], [2, 3]], 0).eval()) # shape(2,2) -> (1,2,2)
#[[[0 1]
# [2 3]]]
# case2) 뒤의 인자가 1이상이면 shape의 가운데 그 숫자가 들어가면서 한차원 늘어난다.
print(tf.expand_dims([0, 1, 2], 1).eval()) # shape(3) -> (3,1)
# [[0]
# [1]
# [2]]
print(tf.expand_dims([[0, 1], [2, 3]], 1).eval()) # shape(2,2) -> (2, 1, 2)
#[[[0 1]]
# [[2 3]]]
print(tf.expand_dims([[0, 1], [2, 3]], 2).eval()) # shape(2,2) -> (2, 2, 2)
#[[[0]
# [1]]
# [[2]
# [3]]]
# one_hot
- 주의! one_hot으로 변경해주면 한차원 증가하므로 마지막에 reshape을 해줘야 한다.
- depth는 만들어질 행렬의 제일 안쪽 원소의 개수를 설정하는 것임. 보통, class의 개수대로 설정함
- y label을 one-hot으로 변경할 때 많이 사용됨.
print(tf.one_hot([[0], [1], [2], [0]], depth=3).eval())
#[[[1. 0. 0.]]
# [[0. 1. 0.]]
# [[0. 0. 1.]]
# [[1. 0. 0.]]]
t = tf.one_hot([[0], [1], [2], [0]], depth=3)
print(tf.reshape(t, shape=[-1, 3]).eval())
#[[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]
# [1. 0. 0.]]
# cast
- 데이터 타입을 변경해줄 때 사용
- True, False 값을 0 또는 1의 숫자로 변경해 줄때도 사용
print(tf.cast([1.8, 2.2, 3.3, 4.9], tf.int32).eval())
#[1 2 3 4]
print(tf.cast([True, False, True, True], tf.int32).eval())
#[1 0 1 0]
print(tf.cast([True, False, 1 == 1, 0 == 1], tf.int32).eval())
#[1 0 1 1]
# stack
- 말 그대로 쌓는 것임. axis로 쌓이는 방향을 설정할 수 있음.
x = [1, 4]
y = [2, 5]
z = [3, 6]
print(tf.stack([x, y, z]).eval())
#[[1 4]
# [2 5]
# [3 6]]
print(tf.stack([x, y, z], axis=0).eval())
#[[1 4]
# [2 5]
# [3 6]]
print(tf.stack([x, y, z], axis=1).eval())
#[[1 2 3]
# [4 5 6]]
print(tf.stack([x, y, z], axis=-1).eval())
#[[1 2 3]
# [4 5 6]]
# ones_like & zeros_like
- 인자로 받은 행렬과 같은 크기의 행렬을 만들어 주며 ones의 경우 1로 채워진 행렬을 반환, zeros의 경우 0으로 채워진 행렬을 반환.
x = [[0, 1, 2],
[2, 1, 0]]
print(tf.ones_like(x).eval())
#[[1 1 1]
# [1 1 1]]
print(tf.zeros_like(x).eval())
#[[0 0 0]
# [0 0 0]]
# zip
- 여러군데서 하나씩 꺼낼 때 사용하는 것으로, 각각의 리스트의 원소를 순차적으로 하나씩 뽑아서 만든 리스트를 반환해줌
print(zip([1, 2, 3], [4, 5, 6], [7, 8, 9]))
# [(1, 4, 7), (2, 5, 8), (3, 6, 9)] -> type : list
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)
'데이터 사이언스 > 모두를 위한 딥러닝' 카테고리의 다른 글
모두를 위한 딥러닝 제26강 lec9-x: 특별편: 10분안에 미분 정리하기 (lec9-2 이전에 보세요) (0) | 2018.10.01 |
---|---|
모두를 위한 딥러닝 제25강 lec9-1: XOR 문제 딥러닝으로 풀기 (0) | 2018.09.30 |
모두를 위한 딥러닝 제22-23강 lec 08-1, lec 08-2: 딥러닝의 역사 (0) | 2018.09.27 |
모두를 위한 딥러닝 제21강 ML lab 07-2: Meet MNIST Dataset (0) | 2018.09.27 |
모두를 위한 딥러닝 제20강 ML lab 07-1: training/test dataset, learning rate, normalization (0) | 2018.09.26 |