TF v2 기초 실습

2020-02-28

.

Deep_Learning_Studynotes_(20190713)

study program : https://www.fastcampus.co.kr/data_camp_deeplearning

실습환경 : Google colab gpu 엔진

!pip install tensorflow-gpu==2.0.0
Collecting tensorflow-gpu==2.0.0
[?25l  Downloading https://files.pythonhosted.org/packages/25/44/47f0722aea081697143fbcf5d2aa60d1aee4aaacb5869aee2b568974777b/tensorflow_gpu-2.0.0-cp36-cp36m-manylinux2010_x86_64.whl (380.8MB)
     |████████████████████████████████| 380.8MB 46kB/s 
[?25hRequirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (1.1.0)
Requirement already satisfied: keras-preprocessing>=1.0.5 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (1.1.0)
Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (1.12.0)
Requirement already satisfied: numpy<2.0,>=1.16.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (1.17.5)
Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (1.27.1)
Requirement already satisfied: absl-py>=0.7.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (0.9.0)
Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (0.8.1)
Collecting tensorflow-estimator<2.1.0,>=2.0.0
[?25l  Downloading https://files.pythonhosted.org/packages/fc/08/8b927337b7019c374719145d1dceba21a8bb909b93b1ad6f8fb7d22c1ca1/tensorflow_estimator-2.0.1-py2.py3-none-any.whl (449kB)
     |████████████████████████████████| 450kB 52.4MB/s 
[?25hRequirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (3.1.0)
Collecting tensorboard<2.1.0,>=2.0.0
[?25l  Downloading https://files.pythonhosted.org/packages/76/54/99b9d5d52d5cb732f099baaaf7740403e83fe6b0cedde940fabd2b13d75a/tensorboard-2.0.2-py3-none-any.whl (3.8MB)
     |████████████████████████████████| 3.8MB 65.5MB/s 
[?25hRequirement already satisfied: wrapt>=1.11.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (1.11.2)
Requirement already satisfied: gast==0.2.2 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (0.2.2)
Requirement already satisfied: keras-applications>=1.0.8 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (1.0.8)
Requirement already satisfied: google-pasta>=0.1.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (0.1.8)
Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (0.34.2)
Requirement already satisfied: protobuf>=3.6.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0.0) (3.10.0)
Requirement already satisfied: setuptools>=41.0.0 in /usr/local/lib/python3.6/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (45.1.0)
Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.6/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (2.21.0)
Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.6/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (0.4.1)
Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.6/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (1.0.0)
Requirement already satisfied: google-auth<2,>=1.6.3 in /usr/local/lib/python3.6/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (1.7.2)
Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.6/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (3.2.1)
Requirement already satisfied: h5py in /usr/local/lib/python3.6/dist-packages (from keras-applications>=1.0.8->tensorflow-gpu==2.0.0) (2.8.0)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (3.0.4)
Requirement already satisfied: urllib3<1.25,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (1.24.3)
Requirement already satisfied: idna<2.9,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (2.8)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (2019.11.28)
Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.6/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (1.3.0)
Requirement already satisfied: cachetools<3.2,>=2.0.0 in /usr/local/lib/python3.6/dist-packages (from google-auth<2,>=1.6.3->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (3.1.1)
Requirement already satisfied: rsa<4.1,>=3.1.4 in /usr/local/lib/python3.6/dist-packages (from google-auth<2,>=1.6.3->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (4.0)
Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.6/dist-packages (from google-auth<2,>=1.6.3->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (0.2.8)
Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.6/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (3.1.0)
Requirement already satisfied: pyasn1>=0.1.3 in /usr/local/lib/python3.6/dist-packages (from rsa<4.1,>=3.1.4->google-auth<2,>=1.6.3->tensorboard<2.1.0,>=2.0.0->tensorflow-gpu==2.0.0) (0.4.8)
ERROR: tensorflow 1.15.0 has requirement tensorboard<1.16.0,>=1.15.0, but you'll have tensorboard 2.0.2 which is incompatible.
ERROR: tensorflow 1.15.0 has requirement tensorflow-estimator==1.15.1, but you'll have tensorflow-estimator 2.0.1 which is incompatible.
Installing collected packages: tensorflow-estimator, tensorboard, tensorflow-gpu
  Found existing installation: tensorflow-estimator 1.15.1
    Uninstalling tensorflow-estimator-1.15.1:
      Successfully uninstalled tensorflow-estimator-1.15.1
  Found existing installation: tensorboard 1.15.0
    Uninstalling tensorboard-1.15.0:
      Successfully uninstalled tensorboard-1.15.0
Successfully installed tensorboard-2.0.2 tensorflow-estimator-2.0.1 tensorflow-gpu-2.0.0
import numpy as np
import tensorflow as tf
print (tf.__version__)
2.0.0
  • 텐서플로우 즉시 실행 (TensorFlow Eager Execution)

참고 URL : https://github.com/tgjeon/TF-Eager-Execution-Guide-KR/blob/master/guide.md

텐서플로우의 즉시 실행 (Eager execution)은 그래프 생성 없이 연산을 즉시 실행하는 명령형 프로그래밍 환경을 뜻한다. 각 연산들은 나중에 실행할 계산 그래프를 만드는 것이 아니라, 실제 값이 반환된다. 이를 통해 텐서플로우를 좀더 쉽게 시작할 수 있고, 모델을 디버그 할 수 있다. 또한 불필요한 상용구도 줄여준다.

#tf.enable_eager_execution()
tf.executing_eagerly()
True

Defining Tensors

m1 = [[1.0, 2.0], 
      [3.0, 4.0]]
m2 = np.array([[1.0, 2.0],
              [3.0, 4.0]], dtype=np.float32)
m3 = tf.constant([[1.0, 2.0],
                 [3.0, 4.0]])

print(type(m1))
print(type(m2))
print(type(m3))
<class 'list'>
<class 'numpy.ndarray'>
<class 'tensorflow.python.framework.ops.EagerTensor'>
t1 = tf.convert_to_tensor(m1, dtype=tf.float32)
t2 = tf.convert_to_tensor(m2, dtype=tf.float32)
t3 = tf.convert_to_tensor(m3, dtype=tf.float32)

print(type(t1))
print(type(t2))
print(type(t3))
<class 'tensorflow.python.framework.ops.EagerTensor'>
<class 'tensorflow.python.framework.ops.EagerTensor'>
<class 'tensorflow.python.framework.ops.EagerTensor'>

Numpy Compatibility

ndarray = np.ones([3, 3])
print(ndarray,'\n')

print("TensorFlow operations convert numpy arrays to Tensors automatically")
tensor = tf.multiply(ndarray, 42)
print(tensor,'\n')


print("And NumPy operations convert Tensors to numpy arrays automatically")
print(np.add(tensor, 1),'\n')
# tf.add도 쓸 수 있다. 여기서 보여주고 싶은 것은 넘파이와 텐서플로우가 호환이 된다는 것이다.

print("The .numpy() method explicitly converts a Tensor to a numpy array")
print(tensor.numpy())
[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]] 

TensorFlow operations convert numpy arrays to Tensors automatically
tf.Tensor(
[[42. 42. 42.]
 [42. 42. 42.]
 [42. 42. 42.]], shape=(3, 3), dtype=float64) 

And NumPy operations convert Tensors to numpy arrays automatically
[[43. 43. 43.]
 [43. 43. 43.]
 [43. 43. 43.]] 

The .numpy() method explicitly converts a Tensor to a numpy array
[[42. 42. 42.]
 [42. 42. 42.]
 [42. 42. 42.]]

Constants

1.x 버전에서는 변수 선언 후 출력 시 오류가 발생했는데, 2버전은 아래와 같이 바로 출력이 가능하다

1.x 버전에서는 sess.run을 해주고 프린트를 해야 가능한 것이었다.

hello = tf.constant("Hello World!")
print(hello)
tf.Tensor(b'Hello World!', shape=(), dtype=string)
a = tf.constant(1.5)
b = tf.constant(2.5)
print(a)
print(b)
tf.Tensor(1.5, shape=(), dtype=float32)
tf.Tensor(2.5, shape=(), dtype=float32)

Operations

a_plus_b = tf.add(a, b)
print(a_plus_b)
tf.Tensor(4.0, shape=(), dtype=float32)
a_mul_b = tf.multiply(a, b)
print(a_mul_b)
tf.Tensor(3.75, shape=(), dtype=float32)

Variables

머신러닝에서는 결국 w값을 찾는 것이 목적인데 처음에는 이 가중치 w가 어떤 값인지 모르니까 랜덤값으로 채우는 것이다.

이때 보통은 가우시안 정규분포로 부터 랜덤한 값을 추출해서 쓴다. 아니면 유니폼분포를 쓰는 경우도 있다.

weight = tf.Variable(tf.random_normal_initializer(stddev=0.1)([5, 2]))
# 평균이 0이고 표준편차가 0.1인 가우시안 정규분포 변수를 5행 2열 사이즈로 뽑는다.
print(weight)

# 1.x버전에서는 위와같이 variable을 선언하면 글로벌 베리어블 이니셜라이저 같은 것을 만들고
# 실행하고 저 웨이트를 또 sess.run을 또 실행해줘야 나왔는데 2버전은 바로 실행이 가능하다.
<tf.Variable 'Variable:0' shape=(5, 2) dtype=float32, numpy=
array([[ 0.17056648, -0.10029701],
       [ 0.06359627, -0.07801517],
       [ 0.02875451, -0.07994997],
       [ 0.04571531,  0.00851992],
       [-0.11485572,  0.01776707]], dtype=float32)>

Shape, Rank, Axis

t = tf.constant([1,2,3,4])
print(t.shape)

# 텐서플로우에서 shape를 찍으면 파이썬의 튜플형태로 나온다.
(4,)
t = tf.constant([[1,2],
                 [3,4]])
print(t.shape)
(2, 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(t.shape)

# 괄호가 4개가 있으니까 일단 4차원이다.
# 이 4를 튜플의 맨 마지막에 써준다.
# 그리고 두번째 닫는괄호가 2개연속 나올때까지 이 괄호가 몇개 나온가 보니까 3개이다.
# 그러면 이 3을 튜플의 마지막에서 두번째로 써준다.
# 그 다음에 두개받는 괄호가 3개닫는 괄호나올때까지 몇번나왔는지 보니까 2개이다.
# 그 다음에 세개닫는 괄호가 네개 단는 괄호나올때까지 몇번나왔는지 보니까 1개이다.
# 그래서 (1,2,3,4)이고 이게 텐서플로우에서 shape이다.
(1, 2, 3, 4)
np.array(
[
    [
        [
            [1,2,3,4], 
            [5,6,7,8],
            [9,10,11,12]
        ],
        [
            [13,14,15,16],
            [17,18,19,20], 
            [21,22,23,24]
        ]
    ]
]
).shape
(1, 2, 3, 4)

Matmul VS multiply

matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],
                       [2.]])
print(tf.matmul(matrix1, matrix2))
tf.Tensor([[12.]], shape=(1, 1), dtype=float32)
print(matrix1*matrix2)
tf.Tensor(
[[6. 6.]
 [6. 6.]], shape=(2, 2), dtype=float32)

Watch out broadcasting

matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],
                       [2.]])
print(matrix1+matrix2)
tf.Tensor(
[[5. 5.]
 [5. 5.]], shape=(2, 2), dtype=float32)
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2., 2.]])
print(matrix1+matrix2)
tf.Tensor([[5. 5.]], shape=(1, 2), dtype=float32)

Reduce Mean/Sum

print(tf.cast(tf.reduce_mean([1., 2.], axis=0),tf.float32))
# reduce_mean은 평균낸다는 것이다.

print(tf.cast(tf.reduce_mean([1, 2], axis=0),tf.int32))
tf.Tensor(1.5, shape=(), dtype=float32)
tf.Tensor(1, shape=(), dtype=int32)
x = [[1., 2.],
     [3., 4.]]


print(tf.reduce_mean(x))
tf.Tensor(2.5, shape=(), dtype=float32)
# 아래와 같이 축을 정해서 reduce_mean을 할 수 있다.
# axis = 0은 행끼리 다 더해서 평균을 내는 것임
print(tf.reduce_mean(x, axis=0))
tf.Tensor([2. 3.], shape=(2,), dtype=float32)
print(tf.reduce_mean(x, axis=1))
# 반면에 axis =1 은 열끼리 더해서 평균을 낸다는 것이다.
tf.Tensor([1.5 3.5], shape=(2,), dtype=float32)
print(tf.reduce_mean(x, axis=-1))
# axis = -1은 맨마지막을 의미한다. 
# 0번 1번 축이 두개밖에 없는데 마지막이 1번 축이니까 1번축으로 reduce_mean을 한 것이다.
tf.Tensor([1.5 3.5], shape=(2,), dtype=float32)
print(tf.reduce_sum(x))
tf.Tensor(10.0, shape=(), dtype=float32)
print(tf.reduce_sum(x, axis=0))
tf.Tensor([4. 6.], shape=(2,), dtype=float32)
print(tf.reduce_sum(x, axis=-1))
tf.Tensor([3. 7.], shape=(2,), dtype=float32)
print(tf.reduce_mean(tf.reduce_sum(x, axis=-1)))
tf.Tensor(5.0, shape=(), dtype=float32)

Argmax with axis

x = [[5, 6, 7],
     [7, 6, 5]]
print(tf.argmax(x, axis=0))
# argmax는 max값을 찾아서 거기의 index를 리턴하는 것이다.
# 얘도 마찬가지로 축을 정해서 연산할 수 있다.
# axis는 0이니까 행끼리 연산한다는 것이다.
tf.Tensor([1 0 0], shape=(3,), dtype=int64)
print(tf.argmax(x, axis=1))
# 반연에 여기서는 axis가 1이기 때문에 열끼리 연산한다.
tf.Tensor([2 0], shape=(2,), dtype=int64)
print(tf.argmax(x, axis=-1))
tf.Tensor([2 0], shape=(2,), dtype=int64)

Reshape, squeeze, expand_dims

t = np.array([[[0, 1, 2], 
               [3, 4, 5]],
              
              [[6, 7, 8], 
               [9, 10, 11]]])
print(t.shape)
(2, 2, 3)
print(tf.reshape(t, shape=[-1, 3]))
# reshape도 가능하다. 
# -1로 되어 있으면 알아서 채우라는 말인데 무슨말이냐면
# 총 숫자가 12개이고 열이 3개짜리니까 행은 4로해서 채우라는 것이다. 
tf.Tensor(
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]], shape=(4, 3), dtype=int64)
print(tf.reshape(t, shape=[-1, 1, 3]))
# 결국에는 (4,1,3)이 된다.
tf.Tensor(
[[[ 0  1  2]]

 [[ 3  4  5]]

 [[ 6  7  8]]

 [[ 9 10 11]]], shape=(4, 1, 3), dtype=int64)
print(tf.squeeze([[0], [1], [2]]))
# squeeze라는 것은 차원이 여러개 있는것을 한방에 1차원으로 줄여주는 것을 말한다.
tf.Tensor([0 1 2], shape=(3,), dtype=int32)
print(tf.expand_dims([0, 1, 2], 1))
# 반면에 expand_dim이라는 것은 여기서는 얘가 지금 1차원을 하나 뒤에 늘려준다는 것이다.
tf.Tensor(
[[0]
 [1]
 [2]], shape=(3, 1), dtype=int32)

One hot

print(tf.one_hot([0, 1, 2, 0], depth=3))
tf.Tensor(
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]
 [1. 0. 0.]], shape=(4, 3), dtype=float32)

Type Casting

print(tf.cast([1.8, 2.2, 3.3, 4.9], tf.int32))
tf.Tensor([1 2 3 4], shape=(4,), dtype=int32)
print(tf.cast([True, False, 1 == 1, 0 == 1], tf.int32))
tf.Tensor([1 0 1 0], shape=(4,), dtype=int32)

Create a Dataset

a = np.arange(10)
print(a)
ds_tensors = tf.data.Dataset.from_tensor_slices(a)

# 데이터를 사용할 수 있게 전처리를 하면 네트워크에 데이터를 넣어줘야 하기 때문에
# input 데이터랑 정답 레이블을 묶어서 보통 데이터셋이라는 것을 만들고 파이프 라인을 구성한다.
[0 1 2 3 4 5 6 7 8 9]

Apply Transformations

ds_tensors = ds_tensors.map(tf.square).shuffle(20).batch(2)
# tf.square = 제곱을해라
# shuffle 괄호 안에 20은 20이라는 공간을 준다는 것이다 위에서는 10개를 만들었기 때문에
# 공간은 10개 이상만 주면 문제 없다.
# 예를 들어서 위와 같이 ds_tensors를 만들면 이걸 가지고 배치를 임의로 하라고 할 수도 있고, 셔플을 할 수도 있다.

Iterate

# 데이터 셋을 한번씩 다 쓰는 것을 1에포크라고 한다.
# 보통 1에포크를 돌고나서 데이터셋을 셔플한다음에 또 에포크를 돈다.
print('Elements of ds_tensors:')
for _ in range(3):
  for x in ds_tensors:
    print(x)
Elements of ds_tensors:
tf.Tensor([81  1], shape=(2,), dtype=int64)
tf.Tensor([16 64], shape=(2,), dtype=int64)
tf.Tensor([25 36], shape=(2,), dtype=int64)
tf.Tensor([0 4], shape=(2,), dtype=int64)
tf.Tensor([49  9], shape=(2,), dtype=int64)
tf.Tensor([0 1], shape=(2,), dtype=int64)
tf.Tensor([25 16], shape=(2,), dtype=int64)
tf.Tensor([81 64], shape=(2,), dtype=int64)
tf.Tensor([ 4 49], shape=(2,), dtype=int64)
tf.Tensor([ 9 36], shape=(2,), dtype=int64)
tf.Tensor([36 25], shape=(2,), dtype=int64)
tf.Tensor([ 1 81], shape=(2,), dtype=int64)
tf.Tensor([ 9 16], shape=(2,), dtype=int64)
tf.Tensor([ 4 64], shape=(2,), dtype=int64)
tf.Tensor([ 0 49], shape=(2,), dtype=int64)