텐서플로우

박재형·2025년 2월 15일

텐서플로우란?

딥러닝을 쉽게 구현할 수 있도록 만들어주는 오픈 소스 라이브러리이다.

딥러닝에선 신경망이 데이터를 학습하면서 수많은 행렬 연산과 미분 연산이 필요하기 때문에 연산량이 매우 많아진다.

이 과정에서 매우 짧고 단순한 코드라도 연산량이 많아질 수록 코드의 양도 기하급수적으로 늘게 되는데, 텐서플로우를 활용하면

이 연산 과정을 아주 간단한 코드로 줄일 수 있게 된다.

텐서플로우는 tensor 라고 부르는 기본 자료형을 활용해서 정보들을 저장한다.

리스트와 똑같아 보일 수 있지만 자료들의 차원이 높아질수록 파이썬 리스트를 쓰면 처리가 매우 느리고 비효율적이다.

딥러닝 과정에선 고차원 자료들을 많이 다루므로 메모리 관리, 연산 속도, GPU 가속 등에서 한계가 크기 때문에 텐서를 사용하는 것이 훨씬 유리하다.

텐서플로우의 간단한 연산 메소드

텐서 생성 및 조작

tf.constant()

변경할 수 없는 상수 텐서를 생성한다.

예제

import tensorflow as tf
텐서 = tf.constant([1, 2, 3])
print(텐서)

tf.Tensor([1 2 3], shape=(3,), dtype=int32) #출력문

 ㅤ

tf.Variable()

변수(가중치 등)를 저장하는 텐서를 생성한다.

예제

w = tf.Variable([0.5, -0.2])
print(w)

tf.Variable 'Variable:0' shape=(2,) dtype=float32, numpy=array([ 0.5, -0.2], dtype=float32) #출력문

 ㅤ

tf.reshape()

텐서의 형태를 변경한다.

예제

x = tf.constant([[1, 2, 3], [4, 5, 6]])
y = tf.reshape(x, [3, 2])
print(y)

tf.Tensor(
[[1 2]
 [3 4]
 [5 6]], shape=(3, 2), dtype=int32) #출력문

 ㅤ

연산

tf.add(x, y), tf.subtract(x, y), tf.multiply(x, y), tf.divide(x, y)

순서대로 덧셈, 뺄셈, 곱셈, 나눗셈 연산이다.

예제

x = tf.constant(3)
y = tf.constant(2)

print(tf.add(x, y))       
print(tf.subtract(x, y))  
print(tf.multiply(x, y))  
print(tf.divide(x, y))    

tf.Tensor(5, shape=(), dtype=int32) #출력문
tf.Tensor(1, shape=(), dtype=int32) 
tf.Tensor(6, shape=(), dtype=int32)
tf.Tensor(1.5, shape=(), dtype=float64)

 ㅤ

tf.square()

제곱 연산이다.

예제

x = tf.constant([1.0, 2.0, 3.0, 4.0])
y = tf.square(x)
print(y)

tf.Tensor([ 1.  4.  9. 16.], shape=(4,), dtype=float32) #출력문

 ㅤ

tf.matmul()

행렬 곱셈 연산이다.

예제

A = tf.constant([[1, 2], [3, 4]])
B = tf.constant([[5, 6], [7, 8]])
C = tf.matmul(A, B)
print(C)

tf.Tensor(
[[19 22]
 [43 50]], shape=(2, 2), dtype=int32) #출력문

 ㅤ

자동 미분

tf.GradientTape()

자동 미분 연산이다.

예제

x = tf.Variable(3.0)
with tf.GradientTape() as tape:
    y = x**2  # y = x^2
dy_dx = tape.gradient(y, x)
print(dy_dx)

tf.Tensor(6.0, shape=(), dtype=float32) #출력문

 ㅤ
그럼 텐서플로우의 기본 연산들을 이용하여 간단하게 키와 신발 사이즈의 연관성을 찾는 알고리즘을 짜보겠다. 사실 이 방법은 기초적인 단계라 아예 사용하지 않는다고 한다.

일단 신발 사이즈와 키를 지정하겠다.

신발 = [260, 280, 270, 255]
키 = [170, 180, 175, 160]

그리고 자료의 구조가 선형적으로 표시될 수 있을 것 같으니 신발 사이즈 = 키 * a + b 라는 일차함수 형태의 식으로 가정하겠다.

그리고 계속 바뀌어야 하는 미지수 a, b 값을 variable 형태로 랜덤하게 지정하겠다.

a = tf.Variable(1.0)

b = tf.Variable(1.5)

그리고 예측값과 실제값의 오차를 줄이기 위해 optimizer를 도입하겠다. learning rate는 0.1로 설정해두겠다.

opt = tf.keras.optimizers.Adam(learning_rate=0.1)

그리고 손실함수를 설정하겠다. 손실함수는 1/n ∑ (예측값 - 실제값)^2

def 손실함수(): 
    예측값 = 키 * a + b
    return tf.square(신발 - 예측값)

위 과정을 반복할 반복문을 짜준다. 계산하면서 a값과 b값을 계속 업데이트해주는 minimize 메소드를 사용했다. 반복을 하면서 a와 b값을 계속 보여주게 numpy()도 사용했다.

for i in range(3000):
    opt.minimize(손실함수, var_list=[a,b])
    print(a.numpy(), b.numpy()) 

코드를 실행해보면 일련의 숫자들이 반복되어서 나온다.

처음 설정해둔 a값과 b값으로 계산하면 신발 = 키 X 1.0 + 1.5이다.

170 X 1.0 + 1.5 로 260과 전혀 가까운 값이 아니다.

하지만 3000번의 반복으로 나온 a 값인 1.486, b값인 11.5706을 대입해보면 170 X 1.486 + 11. 5706 = 264.1906으로 얼추 비슷한 값이 된다.

다른 값을 넣어봐도 예측했던 a와 b값보다 정확도가 올라간 걸 알 수 있다.

반복 횟수를 높여 계속 반복을 했을 때, a값은 1.228, b값은 55.856에 수렴하게 된다. 이를 실제 수식에 넣으면 전보다 더 정확한 것을 알 수 있다.

물론 자료들이 완전한 선형도 아닐뿐더러 비선형적인 자료에서 레이어를 쌓지도 않아 완벽하게 정확하다곤 할 수 없지만 텐서플로우를 통해 딥러닝 과정에 대해 알 수 있었다.

0개의 댓글