텐서플로를 통해 저수준 파이썬 API를 만들어보자!
텐서플로는 대규모 머신러닝에 맞도록 튜닝된 수치 계산용 라이브러리이다.
API를 살펴보자.
구조를 살펴보자. 고수준의 API부터 저수준까지 직접 다룰 수 있다.
텐서는 일반적으로 다차원 배열, 혹은 스칼라도 가능하다. 따라서 넘파이 ndarray 와 비슷한데 텐서를 직접 만들고 조작하는 방법을 알아보자.
tf.constant([[1., 2., 3.], [4., 5., 6.]]) # 행렬
tf.constant(42) # 스칼라
위는 행렬, 아래는 스칼라이다.
.shape
, dtype
으로 확인할 수 있다.t+10
을 하면 모든 텐서에 10을 더한다. 외에도 tf.add(), tf.multiply, tf.square, tf.exp, tf.sqrt() 등이 제공된다. 타입변환
타입 변환은 성능을 감소시킬 수 있으므로 자동 타입 변환을 지원하지 않는다.
변수
일반적인 tf.Tensor 는 변경이 불가능한 객체이므로 변경하고 싶은 대상일 경우 tf.Variable 을 사용한다.
v = tf.Variable([[1., 2., 3.], [4., 5., 6.]]
assign()
메서드를 사용하면 변숫값을 바꿀 수 있다. scatter_nd_update()
를 사용하면 개별 원소를 수정할 수 있다. def huber_fn(y_true, y_pred):
error = y_true - y_pred
is_small_error = tf.abs(error) < 1
squared_loss = tf.square(error) / 2
linear_loss = tf.abs(error) - 0.5
return tf.where(is_small_error, squared_loss, linear_loss)
모델을 컴파일할 때 만들어놓은 후버 손실을 쓰면 된다.
model = keras.models.load_model("my_model_with_a_custom_loss.h5",
custom_objects={"huber_fn": huber_fn})
def my_softplus(z): # tf.nn.softplus(z) 값을 반환합니다
return tf.math.log(tf.exp(z) + 1.0)
def my_glorot_initializer(shape, dtype=tf.float32):
stddev = tf.sqrt(2. / (shape[0] + shape[1]))
return tf.random.normal(shape, stddev=stddev, dtype=dtype)
def my_l1_regularizer(weights):
return tf.reduce_sum(tf.abs(0.01 * weights))
def my_positive_weights(weights): # tf.nn.relu(weights) 값을 반환합니다
return tf.where(weights < 0., tf.zeros_like(weights), weights)
이제 모델의 층을 정의할 때 다음과 같이 넣으면 된다.
layer = keras.layers.Dense(1, activation=my_softplus,
kernel_initializer=my_glorot_initializer,
kernel_regularizer=my_l1_regularizer,
kernel_constraint=my_positive_weights)
precision = keras.metrics.Precision()
precision([0, 1, 1, 1, 0, 1, 0, 1], [1, 1, 0, 1, 0, 1, 0, 1])