03_다중 퍼셉트론 MLP,인공신경망
Python/인공지능

03_다중 퍼셉트론 MLP,인공신경망

728x90

ANN(인공신경망)

 

실제 딥러닝 알고리즘에서 사용되는 기법중 하나이다. 해당 기법은 생물학적 신경망에서 아이디어를 얻었는데, 인간의 뇌가 여러개의 신경세포끼리 연결되어 있고, 이들이 병렬적으로 연산을 진행하는것이 발견되어 이에서 아이디어를 따왔다.

 

보통 인간의 뇌속에는 10^14개의 뉴런과 뉴런이 연결되어 있다!

 

즉, 쉽게 말하면 인간의 뇌 자체가 하나의 엄청난 병렬 처리 연산기라고 볼 수 있다.

 

하지만 컴퓨터는 메모리에서 값을 불러와 CPU에서 순차적으로 연산하는 순차처리 연산기이다. 물론, 컴퓨터는 하나의 연산을 처리하는 속도가 빠르지만, 물체인식,음성인식등 인지활동을 잘 못하는 단점이 있다.  이로인해 컴퓨터도 인간처럼 병렬처리를 하게 된다면?? 이란 생각에서 시작되었다.

 

 

퍼셉트론

 

인공신경만의 개념은 1943년에 제안되었다. 퍼셉트론은 생물학적 뉴런을 공학적 구조로 변형한 것이다. 즉, 입력층에서 인풋 데이터 x를 받고 가중치와 곱한후 바이어스 b를 더한후에 0 혹은 1을 뱉어내는 구조를 가지게 된다.

퍼셉트론

 

 

즉 퍼셉트론은 1 혹은 0을 출력하는 선형 이진 분류기라고 볼 수 있다.

 

 

예를들어 주말에 집에 나가 데이트를 할 것인가에 대한 질문에 대해

 

1. 날씨

2. 선약

3. 데이트 장소

 

기타 등등의 요소를 더해서 각 요소마다 다른 가중치를 더한 후에 데이트를 할지 안할지 결정을 하게 되는 것이다.

 

이로인해 인공지능에 의한 기대감이 높아졌지만, 선형분류기에 불과하단게 밝혀져 인기가 시들어들었다는 역사가 있다. 그럼에도 퍼셉트론은 인공신경망 개념을 공학적인 구조로 구현했다는 점에서 큰 의미가 있는 모델이다.

 

 

다충 퍼셉트론 MLP = 인공신경망

 

계속된 연구를 지속하면서 다층 퍼셉트론 을 활용하여 인공신경망 연구의 돌파구를 마련하게 되었다. 즉, 퍼셉트론을 여러 층으로 쌓아올려 선형분리가 불가능한 문제도 해결할 수 있게 되었다.

 

하나하나의 구조는 퍼셉트론과 같지만, 이를 쌓아올린 형태가 된 것이다!

 

추가하자면 다층 퍼셉트론에서 은닉층을 깊게 여러번 쌓아올린 형태를 깊은 인공신경망(DNN)이라고 부른다.

 

이어서 위 내용으로 저번에 구현해보았던 숫자분류기 구현을 해보자.

 

 

# 이미지들을 float32 데이터 타입으로 변경합니다.
x_train, x_test = x_train.astype('float32'), x_test.astype('float32')
# 28*28 형태의 이미지를 784차원으로 flattening 합니다.
x_train, x_test = x_train.reshape([-1, 784]), x_test.reshape([-1, 784])
# [0, 255] 사이의 값을 [0, 1]사이의 값으로 Normalize합니다.
x_train, x_test = x_train / 255., x_test / 255.
# 레이블 데이터에 one-hot encoding을 적용합니다.
y_train, y_test = tf.one_hot(y_train, depth=10), tf.one_hot(y_test, depth=10)

# 학습을 위한 설정값들을 정의합니다.
learning_rate = 0.001
num_epochs = 30     # 학습횟수
batch_size = 256    # 배치개수
display_step = 1    # 손실함수 출력 주기
input_size = 784    # 28 * 28
hidden1_size = 256
hidden2_size = 256
output_size = 10

# tf.data API를 이용해서 데이터를 섞고 batch 형태로 가져옵니다.
train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_data = train_data.shuffle(60000).batch(batch_size) #끝나면 섞게

먼저 위 코드들은 저번 글에서부터 계속 반복되어 왔던 코드이다. 중요한건, epochs를 30으로 두어서 총 6만개의 데이터가 있다고 생각하면 이를 나누어서 반복한다고 보면 될 것 같다. 그이후, 한번의 train 이 끝나면 섞어주는 과정을 수행해준다.

 

def random_normal_intializer_with_stddev_1():
  return tf.keras.initializers.RandomNormal(mean=0.0, stddev=1.0, seed=None)

 

랜덤세팅한 후에 초기 바이어스 값을 가져오는 함수를 하나 세팅해준다.

 

class ANN(tf.keras.Model):
  def __init__(self):
    super(ANN, self).__init__()
    self.hidden_layer_1 = tf.keras.layers.Dense(hidden1_size,
                                                activation='relu',
                                                kernel_initializer=random_normal_intializer_with_stddev_1(),
                                                bias_initializer=random_normal_intializer_with_stddev_1())
    self.hidden_layer_2 = tf.keras.layers.Dense(hidden2_size,
                                                activation='relu',
                                                kernel_initializer=random_normal_intializer_with_stddev_1(),
                                                bias_initializer=random_normal_intializer_with_stddev_1())
    self.output_layer = tf.keras.layers.Dense(output_size,
                                              activation=None,
                                              kernel_initializer=random_normal_intializer_with_stddev_1(),
                                              bias_initializer=random_normal_intializer_with_stddev_1())

  def call(self, x):
    H1_output = self.hidden_layer_1(x)
    H2_output = self.hidden_layer_2(H1_output)
    logits = self.output_layer(H2_output)

    return logits

# cross-entropy 손실 함수를 정의합니다.

 

keras.Model를 이용하여 ANN 모델을 정의한다. 이 구조는 784 > 256 > 256 > 10 으로 정해준 레이어를 따르게 된다.

 

# cross-entropy 손실 함수를 정의합니다.
@tf.function
def cross_entropy_loss(logits, y):
  return tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))

# 최적화를 위한 Adam 옵티마이저를 정의합니다.
optimizer = tf.optimizers.Adam(learning_rate)

# 최적화를 위한 function을 정의합니다.
@tf.function
def train_step(model, x, y):
  with tf.GradientTape() as tape:
    y_pred = model(x)
    loss = cross_entropy_loss(y_pred, y)
  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))

# 모델의 정확도를 출력하는 함수를 정의합니다.
@tf.function
def compute_accuracy(y_pred, y):
  correct_prediction = tf.equal(tf.argmax(y_pred,1), tf.argmax(y,1))
  accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

  return accuracy

# ANN 모델을 선언합니다.
ANN_model = ANN()

# 지정된 횟수만큼 최적화를 수행합니다.
for epoch in range(num_epochs):
  average_loss = 0.
  total_batch = int(x_train.shape[0] / batch_size)
  # 모든 배치들에 대해서 최적화를 수행합니다.
  for batch_x, batch_y in train_data:
    # 옵티마이저를 실행해서 파라마터들을 업데이트합니다.
    _, current_loss = train_step(ANN_model, batch_x, batch_y), cross_entropy_loss(ANN_model(batch_x), batch_y)
    # 평균 손실을 측정합니다.
    average_loss += current_loss / total_batch
  # 지정된 epoch마다 학습결과를 출력합니다.
  if epoch % display_step == 0:
    print("반복(Epoch): %d, 손실 함수(Loss): %f" % ((epoch+1), average_loss))

# 테스트 데이터를 이용해서 학습된 모델이 얼마나 정확한지 정확도를 출력합니다.
print("정확도(Accuracy): %f" % compute_accuracy(ANN_model(x_test), y_test)) # 정확도: 약 94%

 

그 이후는 이전 글에서 했던 과정과 같은 과정을 수행하게 된다.

728x90

'Python > 인공지능' 카테고리의 다른 글

06_CNN ILSVRC,CNN모델들  (0) 2022.03.18
05_CNN 기초  (0) 2022.03.18
04_오토인코더  (0) 2022.03.18
02_ Softmax Regression을 활용한 MNIST숫자분류기 구현  (0) 2022.03.13
01_ 선형회귀 알고리즘 구현  (0) 2022.03.13