- Tensorflow : tensor가 한 연산에서 다른 연산으로 흐르기 때문에 tensor + flow 가 되었다.
- Tensor : ndarray와 매우 비슷하고 기본적으로 다차원 배열을 다룬다. 스칼라 값을 가질 수도 있다.
12.2.1 텐서와 연산
텐서 생성
import tensorflow as tf
tf.constant([[1,2,3], [4,5,6]]) #matrix
# <tf.Tensor: shape=(2, 3), dtype=int32, numpy=
# array([[1, 2, 3],
# [4, 5, 6]], dtype=int32)>
- tf.constant()를 통해 tensor를 생성할 수 있다.
- 텐서는 ndarray와 같이 shape와 dtype을 가진다.
인덱스 참조
t=tf.constant([[1.,2.,3.],[4.,5.,6.]])
t.shape
t[:, 1:]
# <tf.Tensor: shape=(2, 2), dtype=float32, numpy=
# array([[2., 3.],
# [5., 6.]], dtype=float32)>
- 인덱스 참조 또한 가능하다.
텐서 연산
t=tf.constant([[1.,2.,3.],[4.,5.,6.]])
plus = t + 10
sqaure = tf.sqaure(t)
matrix_multiplication = t @ tf.transpose(t)
- 위의 @ 연산자는 tf.matmul() 함수를 호출하는 것과 동일한 역할을 한다.
- 위의 기본적인 연산 외에도
tf.add()
,tf.multiply()
,tf.square()
,tf.exp()
,tf.sqrt()
등이 가능하다. tf.reshape()
,tf.sqeeeze()
,tf.tile()
은 numpy 메소드와 이름이 같고 기능도 같다.- 하지만,
tf.reduce_mean()
은np.mean()
,tf.reduce_sum()
은 np.sum(),tf.reduce_max()
는np.max()
,tf.math.log()
는np.max()
와 동일하다. 이처럼 기능은 같지만 tensorlfow와 numpy의 이름이 다른 경우도 있다. - 텐서 연산에서 넘파이와 기능은 같지만 이름이 다른 함수들의 경우엔 특별한 이유가 있다.
tf.transpose()
의 경우 전치된 데이터의 복사본으로 새로운 데이터가 만들어지지만, t.T는(numpy 연산) 동일한 데이터의 view일 뿐이다.tf.reduce_sum()
의 경우 GPU커널이 reduce알고리즘을 사용하여 연산을 수행하기 때문에 np.sum()과 다르다.tf.reduce_sum()
와tf.reduce_mean()
의 경우 부동소수점 연산의 어쩔수 없는 오차로 인해 결과값이 호출시마다 조금씩 달라진다.- 이러한 이유로 numpy와 tensorflow 연산 함수 간에는 이름과 작동 '과정'의 차이가 존재한다('결과적으로는 같은 연산을 수행한다').
케라스의 저수준 API
from tensorflow import keras
K=keras.backend
K.sqaure(K.transpose(t))+10
- 다른 케라스 구현에 적용할 수 있는 코드를 사용할 떄는 keras.backend의 자체 저수준 API를 사용하여야 한다.
- 하지만, tensorflow가 제공하는 함수의 일부만이 사용 가능하다는 점이 단점이다.
12.2.2 텐서와 넘파이
t=tf.constant([[1.,2.,3.],[4.,5.,6.]])
a=np.array([2.,4.,5.])
a=tf.constant(a)
t=t.numpy() # or np.array(t)
- tensor와 numpy간의 변환은 자유롭다.
- numpy는 기본으로 64비트 정밀도를 사용하지만, 신경망은 32비트 정밀도로 충분하고 메모리도 적게 사용하기 때문에 32비트를 사용한다.
- 이러한 이유로 numpy를 tensorflow로 변환하기 위해 numpy array를 생성할 떄 dtype=tf.float32로 지정해야 한다.
12.2.3 타입 변환
- tensor 연산에서 타입 변환은 자동으로 이뤄지지 않는다. 즉 다른 타입끼리의 연산이 불가능하다.
- 때문에 만약 다른 타입끼리의 연산이 필요하다면
tf.cast(tensor, dtype)
을 사용해 수동으로 dtype을 변경해줘야 한다.
12.2.4 변수
- 앞서 살펴본
tf.constant()
를 통해 생성되는 tf.Tensor 객체는 내용의 변경이 불가능한 객체이다. - 하지만 deep learning 과정에서 backpropagation을 통해 weight을 update하기 위해서는 tensor가 변경 가능해야 한다.
- 이럴 때
tf.Variable()
을 통해 변경 가능한 객체를 만들어야 한다.
v = tf.Variable([[1.,2.,3.],[4.,5.,6.]])
v
# <tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=
# array([[1., 2., 3.],
# [4., 5., 6.]], dtype=float32)>
- tf.Variable 객체는 tf.Tensor 객체와 동일한 연산이 가능하고 넘파이 호환도 역시 가능하다.
v = tf.Variable([[1.,2.,3.],[4.,5.,6.]])
v
v.assign(2*v)
v[0,1].assign(42)
v[:,2].assign([0.,1.])
v.scatter_nd_update(indices=[[0,0],[1,2]], updates=[100., 200.])
assing()
메소드를 이용해 변숫값을 바꿀 수 있다. 또한assign_add()
나assign_sub()
메소드를 사용하여 주어진 값만큼 변수를 증가시키거나 감소시킬 수 있다.scatter_update(), scatter_nd_update()
를 통해 개별 원소를 변경할 수 있고,assign()
메소드를 사용해서도 가능하다.
'Deep Learning > Hands On Machine Learning' 카테고리의 다른 글
12.4 텐서플로 함수와 그래프 (0) | 2021.11.11 |
---|---|
12.3 사용자 정의 모델과 훈련 알고리즘 (0) | 2021.11.11 |
12.1 텐서플로 훑어보기 (0) | 2021.09.29 |
10.4 연습문제 (0) | 2021.09.24 |
10.3 신경망 하이퍼 파라미터 튜닝하기 (0) | 2021.09.24 |