# tensoRflow ML-lab-08
# Sung Kim 교수님 강의 소스: https://youtu.be/ZYX0FaqUeN4?list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm

library(tensorflow)
library(magrittr)

sess <- tf$InteractiveSession()

# 오브젝트 선언 실험
matrix1 <- tf$constant(matrix(c(1:6), ncol = 2))
matrix2 <- tf$constant(matrix(c(1:6), ncol = 2), dtype = "float32")
matrix3 <- tf$constant(matrix(as.numeric(c(1:6)), ncol = 2))

# 결과값 확인
matrix1   # int32
## Tensor("Const:0", shape=(3, 2), dtype=int32)
##  int [1:3, 1:2] 1 2 3 4 5 6
## 
matrix2   # float32
## Tensor("Const_1:0", shape=(3, 2), dtype=float32)
##  num [1:3, 1:2] 1 2 3 4 5 6
## 
matrix3   # float64
## Tensor("Const_2:0", shape=(3, 2), dtype=float64)
##  num [1:3, 1:2] 1 2 3 4 5 6
## 
# 결과값 해석
# Tensor("Const_1:0", shape=(3, 2), dtype=float32) 의미
# 두번째로 정의된 constant 오브젝트이며, 반환값이 1
# (3행, 2열) 모양이며, 원소타입: 32비트 실수
# 그래프 리셋방법: tf$reset_default_graph()

# 실제값 확인 => R에서는 다 똑같이 보임
matrix1$eval()
##      [,1] [,2]
## [1,]    1    4
## [2,]    2    5
## [3,]    3    6
matrix2$eval()
##      [,1] [,2]
## [1,]    1    4
## [2,]    2    5
## [3,]    3    6
matrix3$eval()
##      [,1] [,2]
## [1,]    1    4
## [2,]    2    5
## [3,]    3    6
# 함수 적용방향 실험
# 실험 대상 3D array: 3 행 4 열
matrix1 <- aperm(array(c(1:24), dim = c(4, 3, 2)), perm = c(2, 1, 3)) %>% 
           tf$constant()
matrix1$eval()
## , , 1
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## 
## , , 2
## 
##      [,1] [,2] [,3] [,4]
## [1,]   13   14   15   16
## [2,]   17   18   19   20
## [3,]   21   22   23   24
# tensoRfolw에서는 0L 세로방향, 1L 가로방향, 2L 레이어방향
# 참고: parameter 뒤에는 항상 정수를 의미하는 L을 붙여줌.

# 3D array 기준: 
tf$reduce_sum(matrix1, axis = 0L)$eval()  # 세로방향
##      [,1] [,2]
## [1,]   15   51
## [2,]   18   54
## [3,]   21   57
## [4,]   24   60
tf$reduce_sum(matrix1, axis = 1L)$eval()  # 가로방향
##      [,1] [,2]
## [1,]   10   58
## [2,]   26   74
## [3,]   42   90
tf$reduce_sum(matrix1, axis = 2L)$eval()  # 레이어방향
##      [,1] [,2] [,3] [,4]
## [1,]   14   16   18   20
## [2,]   22   24   26   28
## [3,]   30   32   34   36
# -의 의미는 정의된 방향 중 '뒤에서부터'를 의미함.
# 즉, -1L은 뒤에서부터 첫번째 방향인 레이어방향
tf$reduce_sum(matrix1, axis = -1L)$eval() # 레이어방향
##      [,1] [,2] [,3] [,4]
## [1,]   14   16   18   20
## [2,]   22   24   26   28
## [3,]   30   32   34   36
tf$reduce_sum(matrix1, axis = -2L)$eval() # 가로방향
##      [,1] [,2]
## [1,]   10   58
## [2,]   26   74
## [3,]   42   90
tf$reduce_sum(matrix1, axis = -3L)$eval() # 세로방향
##      [,1] [,2]
## [1,]   15   51
## [2,]   18   54
## [3,]   21   57
## [4,]   24   60
# Note: 방향 없으면 벡터취급
tf$reduce_sum(matrix1)$eval()
## [1] 300
tf$shape(matrix1) # 행,열,레이어 순서
## Tensor("Shape:0", shape=(3,), dtype=int32)
##  int [1:3(1d)] 3 4 2
## 
# tensor reshape: -1L의 의미는 "알아서" 하라는 의미.
# 다음 명령어의 의미는 2D 행렬로 변환하되,
# 열수는 4개, 행갯수는 알아서 바꿔라라는 의미.
matrix2 <- tf$reshape(matrix1, shape = c(-1L, 4L))
matrix2$eval() # 우리의 예상대로 나오지 않음.
##      [,1] [,2] [,3] [,4]
## [1,]    1   13    2   14
## [2,]    3   15    4   16
## [3,]    5   17    6   18
## [4,]    7   19    8   20
## [5,]    9   21   10   22
## [6,]   11   23   12   24
# 친근한 R함수 사용하기
matrix3 <- rbind(matrix1[,,0]$eval(), matrix1[,,1]$eval()) %>%
           tf$constant(dtype = "float32")
matrix3$eval()
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16
## [5,]   17   18   19   20
## [6,]   21   22   23   24
# tensoRflow 함수만 이용하기
matrix4 <- tf$concat(c(matrix1[,,0], matrix1[,,1]), axis = 0L)
matrix4$eval()
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16
## [5,]   17   18   19   20
## [6,]   21   22   23   24
# squeeze와 expand_dim 함수
matrix4 <- tf$expand_dims(tf$transpose(matrix4), 0L)
matrix4$eval()
## , , 1
## 
##      [,1] [,2] [,3] [,4]
## [1,]   -1   -1   -1   -1
## 
## , , 2
## 
##      [,1] [,2] [,3] [,4]
## [1,]   -1   -1   -1   -1
## 
## , , 3
## 
##      [,1] [,2] [,3] [,4]
## [1,]   -1   -1   -1   -1
## 
## , , 4
## 
##      [,1] [,2] [,3] [,4]
## [1,]   -1   -1   -1   -1
## 
## , , 5
## 
##      [,1] [,2] [,3] [,4]
## [1,]   -1   -1   -1   -1
## 
## , , 6
## 
##      [,1] [,2] [,3] [,4]
## [1,]   -1   -1   -1   -1
matrix4 <- tf$squeeze(tf$transpose(matrix4))
matrix4$eval()
##      [,1] [,2] [,3] [,4]
## [1,]   -1   -1   -1   -1
## [2,]   -1   -1   -1   -1
## [3,]   -1   -1   -1   -1
## [4,]   -1   -1   -1   -1
## [5,]   -1   -1   -1   -1
## [6,]   -1   -1   -1   -1
matrix4 <- tf$expand_dims(matrix4, 1L)
matrix4$eval()
## , , 1
## 
##      [,1]
## [1,]   -1
## [2,]   -1
## [3,]   -1
## [4,]   -1
## [5,]   -1
## [6,]   -1
## 
## , , 2
## 
##      [,1]
## [1,]   -1
## [2,]   -1
## [3,]   -1
## [4,]   -1
## [5,]   -1
## [6,]   -1
## 
## , , 3
## 
##      [,1]
## [1,]   -1
## [2,]   -1
## [3,]   -1
## [4,]   -1
## [5,]   -1
## [6,]   -1
## 
## , , 4
## 
##      [,1]
## [1,]   -1
## [2,]   -1
## [3,]   -1
## [4,]   -1
## [5,]   -1
## [6,]   -1
matrix4 <- tf$squeeze(matrix4)
matrix4$eval()
##      [,1] [,2] [,3] [,4]
## [1,]   -1   -1   -1   -1
## [2,]   -1   -1   -1   -1
## [3,]   -1   -1   -1   -1
## [4,]   -1   -1   -1   -1
## [5,]   -1   -1   -1   -1
## [6,]   -1   -1   -1   -1
# onehot coding
onehot <- tf$one_hot(as.integer(c(0,1,2,0)), depth = 3L)
onehot$eval()
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1
## [4,]    1    0    0
# Close session
sess$close()