
chapter 3
- 케라스와 텐서플로 소개
import tensorflow as tf
x = tf.ones(shape=(2,1))
print(x)
x = tf.zeros(shape =(2,1))
print(x)
x = tf.random.normal(shape=(3,1),mean=0. , stddev=1.)
print(x)
mean: 평균 , stddev =표준편차를 의미
normal은 평균 ,표준편차를 기반으로 무작위 생성 -> 정규분포에서 값을 생성
x = tf.random.uniform(shape=(3, 1), minval=0., maxval=1.)
minval :생성될 값의 최솟값 , maxval : 생성될 값의 최댓값
uniform 은 최솟값 최댓값 기반으로 -> 균등분포에서 값을 생성
import numpy as np
x = np.ones(shape=(2, 2))
x[0, 0] = 0.
output :
array([[0., 1.],
[1., 1.]])
v = tf.Variable(initial_value=tf.random.normal(shape=(3, 1)))
tf.Variable() 함수는 TensorFlow에서 변수를 생성하는 함수
initial_value = 초기값 생성
v.assign(tf.ones((3, 1)))
v.assign_add(tf.ones((3, 1)))
b = tf.square(v)
square 가 제곱이라는 의미
c = tf.sqrt(a)
sqrt 는 제곱근의 의미
e = tf.matmul(a, b)
matmul 은 두개의 행렬을 곱한다
input_var = tf.Variable(initial_value=3.)
print(input_var)
with tf.GradientTape() as tape:
result = tf.square(input_var)
gradient = tape.gradient(result, input_var)
tape.gradient() 함수는 result 텐서와 input_var 변수를 입력으로 받아,
result 텐서의 각 원소에 대한 input_var 변수의 그래디언트 값을 계산
input_const = tf.constant(3.)
constant 가 상수생성
num_samples_per_class = 1000
negative_samples = np.random.multivariate_normal(
mean=[0, 3],
cov=[[1, 0.5],[0.5, 1]],
size=num_samples_per_class)
positive_samples = np.random.multivariate_normal(
mean=[3, 0],
cov=[[1, 0.5],[0.5, 1]],
size=num_samples_per_class)
num_samples_per_class : 클래스당 샘플수를 1000개로 지정
다중 정규 분포 -> multivariate normal
inputs = np.vstack((negative_samples, positive_samples)).astype(np.float32)
np.vstack(): NumPy 배열을 수직 방향으로 쌓아올리는 함수
import matplotlib.pyplot as plt
plt.scatter(inputs[:, 0], inputs[:, 1], c=targets[:, 0])
plt.show()
자세히
plt.scatter(inputs[:, 0], inputs[:, 1], c=targets[:, 0])
- inputs[:, 0]: inputs 배열에서 첫 번째 열(column)의 값을 추출합니다. 이 값은 x축에 해당하는 값
- inputs[:, 1]: inputs 배열에서 두 번째 열(column)의 값을 추출합니다. 이 값은 y축에 해당하는 값으로 사용
- plt.scatter(): x축과 y축의 값을 사용하여 산점도(Scatter plot)를 그리는 함수
input_dim = 2
output_dim = 1
W = tf.Variable(initial_value=tf.random.uniform(shape=(input_dim, output_dim)))
b = tf.Variable(initial_value=tf.zeros(shape=(output_dim,)))
input_dim = 2
입력데이터의 차원을 나타내는 변수 , 위에서 inputs의 배열의 열 수가 2 이므로 -> 2
output_dim = 1
출력 데이터의 차원을 나타내는 변수 , 이진 분류 문제를 풀고 있으므로 , 1이 된다
W = tf.Variable(initial_value=tf.random.uniform(shape=(input_dim, output_dim)))
가중치를 의미
b = tf.Variable(initial_value=tf.zeros(shape=(output_dim,)))
편향을 의미 , 벡터 생성
위 w,b 는 무작위로 초기화 된다.
learning_rate = 0.1
def training_step(inputs, targets):
with tf.GradientTape() as tape:
predictions = model(inputs)
loss = square_loss(targets, predictions)
grad_loss_wrt_W, grad_loss_wrt_b = tape.gradient(loss, [W, b])
W.assign_sub(grad_loss_wrt_W * learning_rate)
b.assign_sub(grad_loss_wrt_b * learning_rate)
return loss
- predictions = model(inputs)
가중치와 편향을 사용하여 예측값을 계산한다.
loss = square_loss(targets, predictions)
MSE 오차를 계산grad_loss_wrt_W, grad_loss_wrt_b = tape.gradient(loss, [W, b])
계산된 그래디언트를 사용하여 , w 와 b 변수에 대한 그래디언트를 계산한다.
W변수의 값을 업데이트한다. , assign_sub 는 현재값에서 뺴는 것이다.
gradient 반대 방향으로 일정한 속도로 이동한다
plt.scatter(inputs[:, 0], inputs[:, 1], c=predictions[:, 0] > 0.5)
예측값이 0.5보다 큰 경우를 true , 그렇지 않은 경우를 false로 나타내는 벡터를 만든다.
x = np.linspace(-1, 4, 100)
NumPy 라이브러리를 사용하여 -1부터 4까지의 범위를 100개의 동일한 간격으로 분할한 배열을 생성하는 코드
y = - W[0] / W[1] * x + (0.5 - b) / W[1]
우선, x와 y의 관계식인 y = - W[0] / W[1] * x + (0.5 - b) / W[1]을 계산합니다. 이 식은 2차원 평면 상에서의 직선을 나타내며, 결정 경계를 나타냅니다.
from tensorflow import keras
class SimpleDense(keras.layers.Layer):
def __init__(self, units, activation=None):
super().__init__()
self.units = units
self.activation = activation
def build(self, input_shape):
input_dim = input_shape[-1]
self.W = self.add_weight(shape=(input_dim, self.units),
initializer="random_normal")
self.b = self.add_weight(shape=(self.units,),
initializer="zeros")
def call(self, inputs):
y = tf.matmul(inputs, self.W) + self.b
if self.activation is not None:
y = self.activation(y)
return y
SimpleDense 클래스는 밀집 레이어(dense layer)를 구성하는 데 사용됩니다. 이 레이어는 입력값과 가중치를 곱하고 편향(bias)을 더한 후에 활성화 함수를 적용하여 출력값을 생성
init :계층의 단위(뉴런) 수 및 사용할 활성화 함수를 포함하여 계층의 속성을 초기화합니다.
build :메소드는 레이어가 모델에서 처음 사용될 때 호출되며 레이어의 가중치를 정의
call :방법은 레이어가 입력을 처리하는 방법을 정의
my_dense = SimpleDense(units=32, activation=tf.nn.relu)
input_tensor = tf.ones(shape=(2, 784))
output_tensor = my_dense(input_tensor)
print(output_tensor.shape)
[1] 출력 크기 32 , 활성화 함수 RELU
[2] 크기가 (2,784) 인 입력 텐서를 생성한다.
[3] my_dense 객체를 사용하여 입력 텐서를 처리하여 출력 텐서(output tensor)를 생성 , 출력텐서의 크기는 (2,32)
from tensorflow.keras import layers
layer = layers.Dense(32, activation="relu")
[1] from tensorflow.keras import layers 구문을 사용하여 Keras 라이브러리에서 layers 모듈을 임포트
[2] Dense 클래스를 사용하여 밀집 레이어(dense layer)를 구성합니다. 이 레이어는 입력값과 가중치를 곱하고 편향(bias)을 더한 후에 활성화 함수를 적용하여 출력값을 생성
from tensorflow.keras import models #models 모델 임포트
from tensorflow.keras import layers
model = models.Sequential([
layers.Dense(32, activation="relu"),
layers.Dense(32)
])
Sequential : 레이러를 순차적으로 연결하여 모델을 생성한다.
layers.Dense(32) : 활성화 함수를 지정하지 않았으므로, 기본값으로 선형함수가 사용
model = keras.Sequential([
SimpleDense(32, activation="relu"),
SimpleDense(64, activation="relu"),
SimpleDense(32, activation="relu"),
SimpleDense(10, activation="softmax")
])
SimpleDense(32, activation="relu") :노드가 32개이고 , 활성화 함수:RELU사용
model = keras.Sequential([keras.layers.Dense(1)])
model.compile(optimizer="rmsprop",
loss="mean_squared_error",
metrics=["accuracy"])
keras.Sequential([keras.layers.Dense(1)]) : 이진분류 Dense 생성
model.compile(optimizer="rmsprop",
loss="mean_squared_error",
metrics=["accuracy"])
compile : 메소드는 모델의 최적화 방법(optimizer), 손실 함수(loss), 평가 지표(metrics)를 지정
optimizer : 인자로는 rmsprop을 전달 rmsprop은 학습률(learning rate)을 조절하는 최적화 방법 중 하나
loss : 인자로는 mean_squared_error를 전달 , mean_squared_error는 평균 제곱 오차(MSE)를 계산하는 손실 함수
,MSE는 예측값과 실제값의 차이를 제곱하여 평균한 값으로, 값이 작을수록 모델의 예측이 정확
metrics : 인자로는 accuracy를 전달합니다. accuracy는 분류 문제에서 모델의 예측이 정확한 비율을 계산하는 평가 지표
metrics=[keras.metrics.BinaryAccuracy()])
BinaryAccuracy() : 클래스는 이진 분류 문제에서 모델의 예측이 정확한 비율을 계산하는 평가 지표
history = model.fit(
inputs,
targets,
epochs=5,
batch_size=128
)
fit : 메소드는 입력 데이터(inputs), 목표 데이터(targets), 에포크 수(epochs), 배치 크기(batch_size) 등을 지정
history.history
history.history : 학습 과정에서 발생한 손실(loss), 평가 지표(metrics) 등의 정보를 담은 딕셔너리를 반환
- Validation_data 매개변수 사용하기
indices_permutation = np.random.permutation(len(inputs))
shuffled_inputs = inputs[indices_permutation]
shuffled_targets = targets[indices_permutation]
len(inputs) : 함수를 사용하여 inputs 배열의 길이(데이터의 수)를 구합니다.
np.random.permutation : 함수를 사용하여 해당 길이를 인자로 넣어주면 0부터 해당 길이까지의 숫자가 랜덤한 순서로 섞인 배열을 반환합니다.
inputs와 targets : 배열에서 섞인 인덱스를 사용하여 각각 shuffled_inputs와 shuffled_targets 배열을 만듭니다.
predictions = model.predict(val_inputs, batch_size=128)
model.predict() : 함수는 모델을 사용하여 입력 데이터에 대한 예측값을 반환
val_inputs :모델의 입력으로 사용되는 데이터를 의미
batch_size=128 : 인자는 예측 작업을 수행할 때 데이터를 한 번에 처리하는 것이 아니라, 128개씩 묶어서 처리하도록 지정