프로그래밍 공부

전체 글 700

카테고리 설명
프로그래밍 공부하는 블로그
  • 순환신경망 (RNN)[Recurrent Neural Network]은 자연어 처리문제와 시계열 데이터를 다루기에 최적화된 인공신경망이다. 시계열 데이터시간 축을 중심으로 현재 시간의 데이터가 이전 및 이후 시간의 데이터와 연관관계를 가지는 데이터.예 : 주식 가격, 음성 데이터, 자연어 데이터 등.. 주식을 예로 들면오늘의 주식 가격은 어제의 주식 가격과 연관되어있고,내일의 주식 가격은 오늘의 주식 가격과 연관관계가 있다. 따라서 주식 가격은 시계열 데이터로 볼수 있다. RNN 구조 기본 개념기본적인 인공신경망(ANN) 구조에 이전 시간의 은닉층 출력값을 현재 시간의 입력값으로 사용하는 경로가 추가된 형태이다.이러한 순환 구조는 시간에 따라 데이터를 처리하고 이전 상태의 정보가 현재와 미래 상태에 영향을..

  • CIFAR-10 데이터셋은 10개의 클래스, 50,000개의 traing images, 10,000 개의 testing images로 구성되어있다. 이미지크기 : 32x32x3 pixels(Color Image) 레이블 : airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck. import tensorflow as tf# CIFAR-10 데이터를 다운로드하고 데이터를 불러옵니다.(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()# 이미지들을 float32 데이터 타입으로 변경합니다.x_train, x_test = x_train.astype('float..

  • 대표적인 Regulazation 기법이다. 오버피팅(OverFitting)을 방지할 수 있도록 만들어주는 기법을 총칭해서 Regularization기법 이라고 부른다. 드롭아웃(Dropout)은 대표적인 Regularization 기법 중 하나이다. 드랍아웃 기법은 학습 과정에서 일부 노드를 사용하지 않는 형태로 만들어서오버 피팅(OverFitting) 을 방지할 수 있도록 만들어주는 Regularization기법이다.  학습할 때 범위를 랜덤하게 설정해서, 일부 노드를 덜어낸다 라고 이해하면 된다.이렇게 덜어냄으로써 일정부분만 학습하게 되면 트레이닝데이터 에서만 정확도가 높아지는걸 방지할 수 있다. TrainingData에 대해서는 오버피팅을 방지하기 위해서는 드랍아웃을 수행하지만, TestData에 ..

  • import tensorflow as tf# MNIST 데이터를 다운로드 합니다.(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()# 이미지들을 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_tra..

  • 컨볼루션 신경망(CNN) 컨볼루션 신경망은 이미지 분야를 다루기에 최적화된 구조이다. 컨볼루선 신경망은 크게 컨볼루션층(COnvolution Layer)과 풀링층(Polling[Subsampling])Layer로 구성된다.풀링은 서브샘플링 이라고 불린다. 컨볼루션 층에서 이루어지는 동작3x3커널을 이용해서 5x5크기의 이미지 행렬에 컨볼루션 연산을 수행하는 과정이다. 입력에 해당되는 커널의 값을 1만큼, 0이라면 0을 곱해서 나온 모든 결과를 더해서 출력위치에 넣어서 압축하는것이다. 원본이미지에 커널을 이용해서 컨볼루션을 수행하면 커널의 종류에 따라 원본 이미지의 특징들이 화설화 맵으로 추출되게 한다. 이때 어떤 커널을 사용하느냐에 따라 원본 이미지에서 다양한 특징을 추출할 수 있다.이미지 노이즈처리를 ..

  • 컴퓨터 비전, 즉 컴퓨터가 이미지를 인식하고 이해하는 과정은 여러 가지 어려움이 있다. 밝기 변화사진을 찍는 환경에 따라 이미지의 밝기가 달라질 수 있다.예를 들어, 같은 물체라도 낮에 찍은 사진과 밤에 찍은 사진은 매우 다르게 보일 수 있다.변형물체는 다양한 각도와 거리에서 찍힐 수 있습니다. 예를 들어, 고양이는 옆모습, 정면, 또는 뒤에서 찍힐 수 있으며, 이는 이미지 인식의 어려움을 가중시킨다. 배경 장애 물체와 배경이 복잡하게 섞여 있는 경우, 배경의 복잡함이 물체 인식을 방해할 수 있다.가림물체의 일부가 다른 물체에 의해 가려질 수 있다.예를 들어, 나무 뒤에 숨어 있는 고양이를 인식하는 것은 일부만 보이기 때문에 어려울 수 있다. 인트라클래스 바리에이션 같은 종류의 물체라도 형태가 다를 수 ..

카테고리
작성일
2024. 6. 18. 03:32
작성자
WDmil
728x90

순환신경망 (RNN)[Recurrent Neural Network]

자연어 처리문제와 시계열 데이터를 다루기에 최적화된 인공신경망이다.

 

시계열 데이터

  • 시간 축을 중심으로 현재 시간의 데이터가 이전 및 이후 시간의 데이터와 연관관계를 가지는 데이터.
  • 예 : 주식 가격, 음성 데이터, 자연어 데이터 등..

 

주식을 예로 들면

오늘의 주식 가격은 어제의 주식 가격과 연관되어있고,

내일의 주식 가격은 오늘의 주식 가격과 연관관계가 있다.

 

따라서 주식 가격은 시계열 데이터로 볼수 있다.

 


RNN 구조

RNN의 구조

 

기본 개념

  • 기본적인 인공신경망(ANN) 구조에 이전 시간의 은닉층 출력값을 현재 시간의 입력값으로 사용하는 경로가 추가된 형태이다.
  • 이러한 순환 구조는 시간에 따라 데이터를 처리하고 이전 상태의 정보가 현재와 미래 상태에 영향을 미치도록 한다.

수식

  • 은닉층 활성값 계산

    $ a_ {t}^{h} = \sum_{t=1}^{I}W_{ih}X_{i}^{t} + \sum_{h'=1}^{H}W_{h'h}b_{h'}^{t-1} $
    • $ X_{i}^{t}  $ : 시간 t에서 i번째 입력 데이터.
    • $ W_{ih} $ : 입력에서 은닉층으로 가는 가중치
    • $ b_{h'}^{t-1} $ : 이전 시간 ( t - 1) 의 은닉유닛 활성값.
    • $ W_{h'h} $ : 은닉 유닛간의 가중치
  • 활성 함수 적용

    $ b_{h}^{t} = \sigma _{h}(a_{h}^{t}) $
    • $ \sigma _{h} $ : 시그모이드 또는 ReLU와 같은 활성 함수.
  • 초기 은닉유닛 활성값

    $ b_{h}^{t} = 0 $
    • 보통은 위와같이 초기 은닉유닛의 경우 0으로 초기화한다.

    출력층

    • 출력값 계산
      • 은닉층으로부터 주어진 입력값과 가중치를 곱하고 합하여 출력값을 구한다.

        $ a_{k}^{t} = \sum_{h=1}^{H}W_{hk}X_{h}^{t} $
      • $ W_{hk} $ : 은닉층에서 출력층으로 가는 가중치.

    • 활성 함수 적용

      $b_{out}^{t} = \sigma _{out}(a_{out}^{t}) $
    • $ a_{out} $ : 출력층의 활성 함수.

     

    RNN의 장점

    • 메모리 효과:
      • 이전 상태의 정보를 저장하고 사용할 수 있는 메모리 형태를 가진다.
      • 시계열 데이터나 자연어 처리와 같은 앞뒤 문맥을 가지는 데이터를 다룰때 효과적이다.
    • 자연어 처리 예시
      • 예 : "푸른 하늘에 OO이 떠있다." 문장에서 OO에 들어갈 단어를 예측한다.
      • 앞뒤 문맥인 "푸른", "하늘", "떠있다" 라는 단어를 통해 OO에 "구름"이 들어갈 것을 예측할 수 있다.
728x90
카테고리
작성일
2024. 6. 18. 03:01
작성자
WDmil
728x90

CIFAR-10 데이터셋은 10개의 클래스, 50,000개의 traing images, 10,000 개의 testing images로 구성되어있다.

 

이미지크기 : 32x32x3 pixels(Color Image)

 

레이블 : airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck.

 

import tensorflow as tf

# CIFAR-10 데이터를 다운로드하고 데이터를 불러옵니다.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# 이미지들을 float32 데이터 타입으로 변경합니다.
x_train, x_test = x_train.astype('float32'), x_test.astype('float32')
# [0, 255] 사이의 값을 [0, 1]사이의 값으로 Normalize합니다.
x_train, x_test = x_train / 255., x_test / 255.
# scalar 형태의 레이블(0~9)을 One-hot Encoding 형태로 변환합니다.
y_train_one_hot = tf.squeeze(tf.one_hot(y_train, 10), axis=1)
y_test_one_hot = tf.squeeze(tf.one_hot(y_test, 10), axis=1)

# tf.data API를 이용해서 데이터를 섞고 batch 형태로 가져옵니다.
train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train_one_hot))
train_data = train_data.repeat().shuffle(50000).batch(128)
train_data_iter = iter(train_data)

test_data = tf.data.Dataset.from_tensor_slices((x_test, y_test_one_hot))
test_data = test_data.batch(1000)
test_data_iter = iter(test_data)

# tf.keras.Model을 이용해서 CNN 모델을 정의합니다.
class CNN(tf.keras.Model):
  def __init__(self):
    super(CNN, self).__init__()
    # 첫번째 convolutional layer - 하나의 RGB 이미지를 64개의 특징들(feature)으로 맵핑(mapping)합니다.
    self.conv_layer_1 = tf.keras.layers.Conv2D(filters=64, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_1 = tf.keras.layers.MaxPool2D(pool_size=(3, 3), strides=2)
    # 두번째 convolutional layer - 64개의 특징들(feature)을 64개의 특징들(feature)로 맵핑(mapping)합니다.
    self.conv_layer_2 = tf.keras.layers.Conv2D(filters=64, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_2 = tf.keras.layers.MaxPool2D(pool_size=(3, 3), strides=2)
    # 세번째 convolutional layer
    self.conv_layer_3 = tf.keras.layers.Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='relu')
    # 네번째 convolutional layer
    self.conv_layer_4 = tf.keras.layers.Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='relu')
    # 다섯번째 convolutional layer
    self.conv_layer_5 = tf.keras.layers.Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='relu')
    # Fully Connected Layer 1 - 2번의 downsampling 이후에, 우리의 32x32 이미지는 8x8x128 특징맵(feature map)이 됩니다.
    # 이를 384개의 특징들로 맵핑(mapping)합니다.
    self.flatten_layer = tf.keras.layers.Flatten()
    self.fc_layer_1 = tf.keras.layers.Dense(384, activation='relu')
    self.dropout = tf.keras.layers.Dropout(0.2)
    # Fully Connected Layer 2 - 384개의 특징들(feature)을 10개의 클래스-airplane, automobile, bird...-로 맵핑(mapsping)합니다.
    self.output_layer = tf.keras.layers.Dense(10, activation=None)

  def call(self, x, training=False):
    # 입력 이미지
    h_conv1 = self.conv_layer_1(x)
    h_pool1 = self.pool_layer_1(h_conv1)
    h_conv2 = self.conv_layer_2(h_pool1)
    h_pool2 = self.pool_layer_2(h_conv2)
    h_conv3 = self.conv_layer_3(h_pool2)
    h_conv4 = self.conv_layer_4(h_conv3)
    h_conv5 = self.conv_layer_5(h_conv4)
    h_conv5_flat = self.flatten_layer(h_conv5)
    h_fc1 = self.fc_layer_1(h_conv5_flat)
    # Dropout - 모델의 복잡도를 컨트롤합니다. 특징들의 co-adaptation을 방지합니다.
    h_fc1_drop = self.dropout(h_fc1, training=training)
    logits = self.output_layer(h_fc1_drop)
    y_pred = tf.nn.softmax(logits)

    return y_pred, logits

# cross-entropy 손실 함수를 정의합니다.
@tf.function
def cross_entropy_loss(logits, y):
  return tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y, logits, from_logits=True))

# 최적화를 위한 RMSprop 옵티마이저를 정의합니다.
optimizer = tf.optimizers.RMSprop(1e-3)

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

# 모델의 정확도를 출력하는 함수를 정의합니다.
@tf.function
def compute_accuracy(y_pred, y):
  accuracy = tf.reduce_mean(tf.keras.metrics.categorical_accuracy(y, y_pred))
  return accuracy

# Convolutional Neural Networks(CNN) 모델을 선언합니다.
CNN_model = CNN()

# 10000 Step만큼 최적화를 수행합니다.
for i in range(10000):
  batch_x, batch_y = next(train_data_iter)

  # 100 Step마다 training 데이터셋에 대한 정확도와 loss를 출력합니다.
  if i % 100 == 0:
    y_pred, logits = CNN_model(batch_x, training=False)
    train_accuracy = compute_accuracy(y_pred, batch_y)
    loss_print = cross_entropy_loss(logits, batch_y)

    print("반복(Epoch): %d, 트레이닝 데이터 정확도: %f, 손실 함수(loss): %f" % (i, train_accuracy, loss_print))
  # 20% 확률의 Dropout을 이용해서 학습을 진행합니다.
  train_step(CNN_model, batch_x, batch_y)

# 학습이 끝나면 테스트 데이터(10000개)에 대한 정확도를 출력합니다.
test_accuracy = 0.0
for i in range(10):
  test_batch_x, test_batch_y = next(test_data_iter)
  y_pred, _ = CNN_model(test_batch_x, training=False)
  test_accuracy += compute_accuracy(y_pred, test_batch_y)

test_accuracy /= 10
print("테스트 데이터 정확도: %f" % test_accuracy)

 

 

유의! 학습과정이 엄청 오래걸린다!


 

코드를 분리해서 해석해보자.


1. 데이터 준비 및 전처리

# CIFAR-10 데이터를 다운로드하고 데이터를 불러옵니다.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# 이미지들을 float32 데이터 타입으로 변경합니다.
x_train, x_test = x_train.astype('float32'), x_test.astype('float32')
# [0, 255] 사이의 값을 [0, 1]사이의 값으로 Normalize합니다.
x_train, x_test = x_train / 255., x_test / 255.
# scalar 형태의 레이블(0~9)을 One-hot Encoding 형태로 변환합니다.
y_train_one_hot = tf.squeeze(tf.one_hot(y_train, 10), axis=1)
y_test_one_hot = tf.squeeze(tf.one_hot(y_test, 10), axis=1)

 

  • tf.keras.datasets.cifar10.load_data(): CIFAR-10 데이터셋을 다운로드.
    이는 32x32 크기의 3채널(RGB) 이미지와 해당 레이블로 구성된다.

  • astype('float32'): 이미지를 32비트 부동 소수점 형식으로 변환한다.

  • / 255.: 이미지 픽셀 값을 [0, 255] 범위에서 [0, 1] 범위로 정규화.

  • tf.squeeze(tf.one_hot(y_train, 10), axis=1): 레이블을 원-핫 인코딩.
    이는 각 레이블을 10차원 벡터로 변환하여 클래스별로 이진 값을 가지게 된다.

2. 데이터셋을 섞고 배치로 묶기

# tf.data API를 이용해서 데이터를 섞고 batch 형태로 가져옵니다.
train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train_one_hot))
train_data = train_data.repeat().shuffle(50000).batch(128)
train_data_iter = iter(train_data)

test_data = tf.data.Dataset.from_tensor_slices((x_test, y_test_one_hot))
test_data = test_data.batch(1000)
test_data_iter = iter(test_data)

 

 

  • tf.data.Dataset.from_tensor_slices((x_train, y_train_one_hot)): 훈련 데이터를 텐서로 변환.
  • repeat(): 데이터셋을 무한 반복한다.
  • shuffle(50000): 50000개의 데이터를 무작위로 섞는다.
  • batch(128): 데이터를 128개의 배치로 나눈다.
  • iter(train_data): 데이터셋을 반복할 수 있는 이터레이터로 변환한다.

3. CNN모델 정의

class CNN(tf.keras.Model):
  def __init__(self):
    super(CNN, self).__init__()
    self.conv_layer_1 = tf.keras.layers.Conv2D(filters=64, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_1 = tf.keras.layers.MaxPool2D(pool_size=(3, 3), strides=2)
    self.conv_layer_2 = tf.keras.layers.Conv2D(filters=64, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_2 = tf.keras.layers.MaxPool2D(pool_size=(3, 3), strides=2)
    self.conv_layer_3 = tf.keras.layers.Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='relu')
    self.conv_layer_4 = tf.keras.layers.Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='relu')
    self.conv_layer_5 = tf.keras.layers.Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='relu')
    self.flatten_layer = tf.keras.layers.Flatten()
    self.fc_layer_1 = tf.keras.layers.Dense(384, activation='relu')
    self.dropout = tf.keras.layers.Dropout(0.2)
    self.output_layer = tf.keras.layers.Dense(10, activation=None)

  def call(self, x, is_training):
    h_conv1 = self.conv_layer_1(x)
    h_pool1 = self.pool_layer_1(h_conv1)
    h_conv2 = self.conv_layer_2(h_pool1)
    h_pool2 = self.pool_layer_2(h_conv2)
    h_conv3 = self.conv_layer_3(h_pool2)
    h_conv4 = self.conv_layer_4(h_conv3)
    h_conv5 = self.conv_layer_5(h_conv4)
    h_conv5_flat = self.flatten_layer(h_conv5)
    h_fc1 = self.fc_layer_1(h_conv5_flat)
    h_fc1_drop = self.dropout(h_fc1, training=is_training)
    logits = self.output_layer(h_fc1_drop)
    y_pred = tf.nn.softmax(logits)

    return y_pred, logits

 

 

  • Conv2D: 2D 합성곱 층. 필터 수, 커널 크기, 스트라이드, 패딩 방식, 활성화 함수를 지정한다.
    • filters=64: 첫 번째 합성곱 층은 64개의 필터를 사용.
    • kernel_size=5: 각 필터의 크기는 5x5
    • strides=1: 필터가 한 번에 이동하는 픽셀 수는 1
    • padding='same': 출력 크기를 입력 크기와 동일하게 유지
    • activation='relu': 활성화 함수로 ReLU를 사용
  • MaxPool2D: 최대 풀링 층. 풀링 크기와 스트라이드를 지정
    • pool_size=(3, 3): 풀링 윈도우 크기는 3x3.
    • strides=2: 풀링 윈도우가 한 번에 이동하는 픽셀 수는 2.
  • Flatten(): 입력을 1차원으로 변환
  • Dense: 완전 연결 층.
    • units=384: 첫 번째 완전 연결 층은 384개의 뉴런을 가진다.
    • activation='relu': 활성화 함수로 ReLU를 사용.
    • units=10: 출력 층은 10개의 뉴런을 가지며, 클래스 수와 동일하다.
  • Dropout(0.2): 20%의 드롭아웃 확률을 사용하여 오버피팅을 방지한다.

4. 손실 함수와 옵티마이저 정의

@tf.function
def cross_entropy_loss(logits, y):
  return tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))

optimizer = tf.optimizers.RMSprop(1e-3)

 

  • cross_entropy_loss(logits, y): 크로스 엔트로피 손실 함수를 정의.
    이는 모델의 출력값과 실제 레이블 사이의 차이를 계산하는것 과 같다.
    • logits: 모델의 출력값.
    • y: 실제 레이블.
  • tf.optimizers.RMSprop(1e-3): RMSprop 옵티마이저를 정의한다. 학습률은 0.001로 설정.

5. 학습 단계 정의

@tf.function
def train_step(model, x, y, is_training):
  with tf.GradientTape() as tape:
    y_pred, logits = model(x, is_training)
    loss = cross_entropy_loss(logits, y)
  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))

 

 

  • train_step(model, x, y, is_training): 한 단계 학습을 수행하는 함수.
    • model(x, is_training): 모델에 입력값 x를 넣어 예측값 y_pred와 로짓 logits를 얻는다.
    • cross_entropy_loss(logits, y): 손실을 계산.
    • tape.gradient(loss, model.trainable_variables): 손실에 대한 그라디언트를 계산.
    • optimizer.apply_gradients(zip(gradients, model.trainable_variables)): 그라디언트를 적용하여 모델의 파라미터를 업데이트.

6. 정확도 계산 함수

@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
  • compute_accuracy(y_pred, y): 모델의 예측 정확도를 계산하는 함수.
    • tf.argmax(y_pred, 1): 예측값에서 가장 높은 확률을 가진 클래스의 인덱스를 찾는다.
    • tf.equal(...): 예측값과 실제값이 같은지 비교한다.
    • tf.reduce_mean(...): 정확도의 평균을 계산.

7. 모델 학습 및 평가

# Convolutional Neural Networks(CNN) 모델을 선언합니다.
CNN_model = CNN()

# 10000 Step만큼 최적화를 수행합니다.
for i in range(10000):
  batch_x, batch_y = next(train_data_iter)

  # 100 Step마다 training 데이터셋에 대한 정확도와 loss를 출력합니다.
  if i % 100 == 0:
    train_accuracy = compute_accuracy(CNN_model(batch_x, False)[0], batch_y)
    loss_print = cross_entropy_loss(CNN_model(batch_x, False)[1], batch_y)

    print("반복(Epoch): %d, 트레이닝 데이터 정확도: %f, 손실 함수(loss): %f" % (i, train_accuracy, loss_print))
  # 20% 확률의 Dropout을 이용해서 학습을 진행합니다.
  train_step(CNN_model, batch_x, batch_y, True)

# 학습이 끝나면 테스트 데이터(10000개)에 대한 정확도를 출력합니다.
test_accuracy = 0.0
for i in range(10):
  test_batch_x, test_batch_y = next(test_data_iter)
  test_accuracy = test_accuracy + compute_accuracy(CNN_model(test_batch_x, False)[0], test_batch_y).numpy()
test_accuracy = test_accuracy / 10
print("테스트 데이터 정확도: %f" % test_accuracy)

 

  • CNN_model = CNN(): CNN 모델을 선언.
  • for i in range(10000): 10000번 반복하여 학습을 수행.
    • batch_x, batch_y = next(train_data_iter): 학습 데이터를 배치 단위로 가져온다.
    • if i % 100 == 0: 100번 반복마다 훈련 데이터의 정확도와 손실을 출력.
      • compute_accuracy(...): 정확도를 계산.
      • cross_entropy_loss(...): 손실을 계산.
    • train_step(...): 학습을 진행.
  • test_accuracy = 0.0: 테스트 데이터 정확도를 초기화.
  • for i in range(10): 테스트 데이터 10개 배치에 대해 정확도를 계산.
    • test_accuracy = test_accuracy + compute_accuracy(...): 각 배치의 정확도를 누적.
  • test_accuracy = test_accuracy / 10: 평균 정확도를 계산.
  • print("테스트 데이터 정확도: %f" % test_accuracy): 최종 테스트 데이터 정확도를 출력한다.

 

728x90
카테고리
작성일
2024. 6. 18. 01:31
작성자
WDmil
728x90

대표적인 Regulazation 기법이다.

 

오버피팅(OverFitting)을 방지할 수 있도록 만들어주는 기법을 총칭해서 Regularization기법 이라고 부른다.

 

드롭아웃(Dropout)은 대표적인 Regularization 기법 중 하나이다.

 

드랍아웃 기법은 학습 과정에서 일부 노드를 사용하지 않는 형태로 만들어서

오버 피팅(OverFitting) 을 방지할 수 있도록 만들어주는 Regularization기법이다.

 

 

학습할 때 범위를 랜덤하게 설정해서, 일부 노드를 덜어낸다 라고 이해하면 된다.

이렇게 덜어냄으로써 일정부분만 학습하게 되면 트레이닝데이터 에서만 정확도가 높아지는걸 방지할 수 있다.

 

TrainingData에 대해서는 오버피팅을 방지하기 위해서는 드랍아웃을 수행하지만, TestData에 대해서는 Dropout을 수행하지 않는다.

 

최대결과값을 보여주어야 하기 때문에, 일부를 덜어낼 필요가 없기 때문.

 

Tensworflow에서 사용하는 방식은 아래 참조.

 

https://www.tensorflow.org/api_docs/python/tf/nn/dropout

 

tf.nn.dropout  |  TensorFlow v2.16.1

Computes dropout: randomly sets elements to zero to prevent overfitting.

www.tensorflow.org

 

 

728x90
카테고리
작성일
2024. 6. 18. 01:23
작성자
WDmil
728x90
import tensorflow as tf

# MNIST 데이터를 다운로드 합니다.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# 이미지들을 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)

# tf.data API를 이용해서 데이터를 섞고 batch 형태로 가져옵니다.
train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_data = train_data.repeat().shuffle(60000).batch(50)
train_data_iter = iter(train_data)

# tf.keras.Model을 이용해서 CNN 모델을 정의합니다.
class CNN(tf.keras.Model):
  def __init__(self):
    super(CNN, self).__init__()
    # 첫번째 Convolution Layer
    # 5x5 Kernel Size를 가진 32개의 Filter를 적용합니다.
    self.conv_layer_1 = tf.keras.layers.Conv2D(filters=32, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_1 = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=2)

    # 두번째 Convolutional Layer
    # 5x5 Kernel Size를 가진 64개의 Filter를 적용합니다.
    self.conv_layer_2 = tf.keras.layers.Conv2D(filters=64, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_2 = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=2)

    # Fully Connected Layer
    # 7x7 크기를 가진 64개의 activation map을 1024개의 특징들로 변환합니다.
    self.flatten_layer = tf.keras.layers.Flatten()
    self.fc_layer_1 = tf.keras.layers.Dense(1024, activation='relu')

    # Output Layer
    # 1024개의 특징들(feature)을 10개의 클래스-one-hot encoding으로 표현된 숫자 0~9-로 변환합니다.
    self.output_layer = tf.keras.layers.Dense(10, activation=None)

  def call(self, x):
    # MNIST 데이터를 3차원 형태로 reshape합니다. MNIST 데이터는 grayscale 이미지기 때문에 3번째차원(컬러채널)의 값은 1입니다.
    x_image = tf.reshape(x, [-1, 28, 28, 1])
    # 28x28x1 -> 28x28x32
    h_conv1 = self.conv_layer_1(x_image)
    # 28x28x32 -> 14x14x32
    h_pool1 = self.pool_layer_1(h_conv1)
    # 14x14x32 -> 14x14x64
    h_conv2 = self.conv_layer_2(h_pool1)
    # 14x14x64 -> 7x7x64
    h_pool2 = self.pool_layer_2(h_conv2)
    # 7x7x64(3136) -> 1024
    h_pool2_flat = self.flatten_layer(h_pool2)
    h_fc1 = self.fc_layer_1(h_pool2_flat)
    # 1024 -> 10
    logits = self.output_layer(h_fc1)
    y_pred = tf.nn.softmax(logits)

    return y_pred, logits

# 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(1e-4)

# 최적화를 위한 function을 정의합니다.
@tf.function
def train_step(model, x, y):
  with tf.GradientTape() as tape:
    y_pred, logits = model(x)
    loss = cross_entropy_loss(logits, 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

# Convolutional Neural Networks(CNN) 모델을 선언합니다.
CNN_model = CNN()

# 10000 Step만큼 최적화를 수행합니다.
for i in range(10000):
  # 50개씩 MNIST 데이터를 불러옵니다.
  batch_x, batch_y = next(train_data_iter)
  # 100 Step마다 training 데이터셋에 대한 정확도를 출력합니다.
  if i % 100 == 0:
    train_accuracy = compute_accuracy(CNN_model(batch_x)[0], batch_y)
    print("반복(Epoch): %d, 트레이닝 데이터 정확도: %f" % (i, train_accuracy))
  # 옵티마이저를 실행해 파라미터를 한스텝 업데이트합니다.
  train_step(CNN_model, batch_x, batch_y)

# 학습이 끝나면 학습된 모델의 정확도를 출력합니다.
print("정확도(Accuracy): %f" % compute_accuracy(CNN_model(x_test)[0], y_test))

코드를 분할해서 이해해보자.


1. 데이터 준비 및 전처리

# MNIST 데이터를 다운로드 합니다.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# 이미지들을 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)

 

  • tf.keras.datasets.mnist.load_data()
    MNIST 데이터셋을 다운로드. 이는 28x28 크기의 손글씨 숫자 이미지와 해당 레이블로 구성된다.

  • astype('float32')
    이미지를 32비트 부동 소수점 형식으로 변환한다.

  • reshape([-1, 784])
    이미지를 28x28에서 784 차원의 벡터로 평탄화한다.

  • / 255.
    이미지 픽셀 값을 [0, 255] 범위에서 [0, 1] 범위로 정규화.

  • tf.one_hot(y_train, depth=10)
    레이블을 원-핫 인코딩 이는 각 레이블을 10차원 벡터로 변환하여 클래스별로 이진 값을 가진다.

2. 데이터셋을 섞고 배치로 묶기

# tf.data API를 이용해서 데이터를 섞고 batch 형태로 가져옵니다.
train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_data = train_data.repeat().shuffle(60000).batch(50)
train_data_iter = iter(train_data)

 

  • tf.data.Dataset.from_tensor_slices((x_train, y_train))
    훈련 데이터를 텐서로 변환.

  • repeat()
    데이터셋을 무한 반복 한다.

  • shuffle(60000)
    60000개의 데이터를 무작위로 섞는다.

  • batch(50)
    데이터를 50개의 배치로 나눈다.

  • iter(train_data)
    데이터셋을 반복할 수 있는 이터레이터로 변환.

 


3. CNN 모델 정의

class CNN(tf.keras.Model):
  def __init__(self):
    super(CNN, self).__init__()
    self.conv_layer_1 = tf.keras.layers.Conv2D(filters=32, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_1 = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=2)
    self.conv_layer_2 = tf.keras.layers.Conv2D(filters=64, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_2 = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=2)
    self.flatten_layer = tf.keras.layers.Flatten()
    self.fc_layer_1 = tf.keras.layers.Dense(1024, activation='relu')
    self.output_layer = tf.keras.layers.Dense(10, activation=None)
  
  def call(self, x):
    x_image = tf.reshape(x, [-1, 28, 28, 1])
    h_conv1 = self.conv_layer_1(x_image)
    h_pool1 = self.pool_layer_1(h_conv1)
    h_conv2 = self.conv_layer_2(h_pool1)
    h_pool2 = self.pool_layer_2(h_conv2)
    h_pool2_flat = self.flatten_layer(h_pool2)
    h_fc1 = self.fc_layer_1(h_pool2_flat)
    logits = self.output_layer(h_fc1)
    y_pred = tf.nn.softmax(logits)
    return y_pred, logits

 

  • Conv2D : 2D 합성곱 층. 필터 수, 커널 크기, 스트라이드, 패딩 방식, 활성화 함수를 지정.
    • filters=32 : 첫 번째 합성곱 층은 32개의 필터를 사용.
    • kernel_size=5: 각 필터의 크기는 5x5.
    • strides=1: 필터가 한 번에 이동하는 픽셀 수는 1.
    • padding='same': 출력 크기를 입력 크기와 동일하게 유지.
    • activation='relu': 활성화 함수로 ReLU를 사용.
  • MaxPool2D : 최대 풀링 층. 풀링 크기와 스트라이드를 지정.
    • pool_size=(2, 2) : 풀링 윈도우 크기는 2x2.
    • strides=2: 풀링 윈도우가 한 번에 이동하는 픽셀 수는 2.
  • Flatten() : 입력을 1차원으로 변환.
  • Dense : 완전 연결 층.
    • units=1024 : 첫 번째 완전 연결 층은 1024개의 뉴런을 가진다.
    • activation='relu': 활성화 함수로 ReLU를 사용.
    • units=10: 출력 층은 10개의 뉴런을 가지며, 클래스 수와 동일.

4. 손실 함수와 옵티마이저 정의

@tf.function
def cross_entropy_loss(logits, y):
  return tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))

optimizer = tf.optimizers.Adam(1e-4)

 

  • cross_entropy_loss(logits, y) :
    크로스 엔트로피 손실 함수를 정의.
    이는 모델의 출력값과 실제 레이블 사이의 차이를 계산 하는것이다.
    • logits: 모델의 출력값.
    • y: 실제 레이블
  • tf.optimizers.Adam(1e-4): Adam 옵티마이저를 정의 학습률은 0.0001로 설정한다.

5. 학습 단계 정의

@tf.function
def train_step(model, x, y):
  with tf.GradientTape() as tape:
    y_pred, logits = model(x)
    loss = cross_entropy_loss(logits, y)
  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  • train_step(model, x, y) : 한 단계 학습을 수행하는 함수.
    • model(x) :
      모델에 입력값 x를 넣어 예측값 y_pred와 로짓 logits를 얻는다.

    • cross_entropy_loss(logits, y) :
      손실을 계산.

    • tape.gradient(loss, model.trainable_variables) :
      손실에 대한 그라디언트를 계산.

    • optimizer.apply_gradients(zip(gradients, model.trainable_variables)) :
      그라디언트를 적용하여 모델의 파라미터를 업데이트.

6. 정확도 계산 함수

 

@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
  • compute_accuracy(y_pred, y): 모델의 예측 정확도를 계산하는 함수.
    • tf.argmax(y_pred, 1): 예측값에서 가장 높은 확률을 가진 클래스의 인덱스를 찾는다.
    • tf.equal(...): 예측값과 실제값이 같은지 비교.
    • tf.reduce_mean(...): 정확도의 평균을 계산한다.

 


7. 모델 학습 및 평가

CNN_model = CNN()

for i in range(10000):
  batch_x, batch_y = next(train_data_iter)
  if i % 100 == 0:
    train_accuracy = compute_accuracy(CNN_model(batch_x)[0], batch_y)
    print("반복(Epoch): %d, 트레이닝 데이터 정확도: %f" % (i, train_accuracy))
  train_step(CNN_model, batch_x, batch_y)

print("정확도(Accuracy): %f" % compute_accuracy(CNN_model(x_test)[0], y_test))

 

 

  • CNN_model = CNN(): CNN 모델을 생성.
  • for i in range(10000): 10000번의 학습 스텝을 수행한다.
    • batch_x, batch_y = next(train_data_iter): 배치 데이터를 가져온다.
    • if i % 100 == 0: 매 100 스텝마다 정확도를 출력.
      • train_accuracy = compute_accuracy(CNN_model(batch_x)[0], batch_y):
        학습 배치에 대한 정확도를 계산한다.
      • print("반복(Epoch): %d, 트레이닝 데이터 정확도: %f" % (i, train_accuracy)): 정확도를 출력.
    • train_step(CNN_model, batch_x, batch_y): 모델을 한 스텝 학습.
  • print("정확도(Accuracy): %f" % compute_accuracy(CNN_model(x_test)[0], y_test)):
    테스트 데이터에 대한 최종 정확도를 출력한다.

 

728x90
카테고리
작성일
2024. 6. 18. 00:35
작성자
WDmil
728x90

컨볼루션 신경망(CNN)

 

컨볼루션 신경망은 이미지 분야를 다루기에 최적화된 구조이다.

 

컨볼루선 신경망은 크게 컨볼루션층(COnvolution Layer)과 풀링층(Polling[Subsampling])Layer로 구성된다.

풀링은 서브샘플링 이라고 불린다.

 

컨볼루션 층에서 이루어지는 동작

3x3커널을 이용해서 5x5크기의 이미지 행렬에 컨볼루션 연산을 수행하는 과정이다.

 

입력에 해당되는 커널의 값을 1만큼, 0이라면 0을 곱해서 나온 모든 결과를 더해서 출력위치에 넣어서 압축하는것이다.

 

원본이미지에 커널을 이용해서 컨볼루션을 수행하면 커널의 종류에 따라 원본 이미지의 특징들이 화설화 맵으로 추출되게 한다.

 

이때 어떤 커널을 사용하느냐에 따라 원본 이미지에서 다양한 특징을 추출할 수 있다.

이미지 노이즈처리를 한다고 생각하면 된다.

 

 

커널의 종류에 따라 원본 이미지의 모서리(Edge)를 추출하거나 더 명확한 이미지(Sharpen)으로 바꾸거나 원본 이미지를 흐리게(Blur)할 수 있다.

 

이렇게 추출한 활성화 맵은 원본 이미지에서 명확하게 드러나지 않던 특징을 볼 수 있다.

 

우리가 어떤 사진이 자동차인지 사람인지를 분류하고자 한다면, 원본 이미지 자체를 사용하는것 보다

모서리만 추출된 특징 이미지를 사용하는 것이 더 효율적일 것이다.

 

좀더 구체적으로 말하면, 모서리가 추출된 이미지를 통해 분류기를 학습하면

컴퓨터는 모서리가 각진 형태면 자동차, 모서리가 둥근 형태면 사람이라고 손쉽게 구분할 수 있을것이다.


풀링

 

풀링은 차원을 축소하는 연산을 수행한다.

 

풀링의 종류에는 최대값 풀링(Max Pooling), 평균값 풀링(Average Pooling), 최소값 풀링(Min Pooling)이 있다.

최대값 풀링은 이미지의 X x X크기 부분에서 가장 큰 값(Max Value)하나를 추출해서 원본 이미지의 X x X개의 값을 1개의 값으로 축소한다.

 

동일한 원리로 평균값 풀링, 최소값 풀링은 평균값, 최소값으로 축소한다.

풀링층 역시 이미지의 좌측 상단에서 우측 하단으로 순차적으로 전체 이미지에 대해 풀링을 수행한다.

 

풀링 예시

풀링 수행과정을 보자.

 

풀링층은 크게 2가지 장점이 있다.

이미지의 차원을 축소함으로써 필요한 연산량을 감소시킬 수 있고, 이미지의 가장 강한 특징만을 추출하는 특징 선별 효과가 있다.

 

예를들어, 모서리만 추출된 활성화 맵에서 최대값 풀링을 수행하면, 차원은 축소되고 흐릿하던 모서리 부분이 더욱 뚜렷해질 것이다.


 

컨볼루션층을 거치면 인풋 이미지의 가로, 세로 차원이 축소된다.

 

구체적으로 인풋 이미지의 가로 길이가 $ W_{in} $ 이라면, 컨볼루션 층을 거친 출력 이미지의 가로 길이 $ W_{out} $ 은 다음과 같이 계산된다.

 $  W_{out} = \frac{W_{in} - F + 2P}{S} + 1 $

 

여기서 F는 필터의 크기, S는 스트라이드 를 의미한다.

 

스트라이드

스트라이드는 컨볼루션 연산 시 건너뛰는 정도를 나타낸다.

 

만약, 스트라이드를 크게 잡아서 이미지를 성큼성큼 건너뛰어서 컨볼루션을 수행하면 차원이 많이 축소되고, 스트라이드를 작게 잡아서 이미지를 촘촘히 건너뛰면 차원이 조금 축소된다.

 

또한 $ \frac{W_{in} - F + 2P}{S} $ 의 차원이 정수로 나누어 떨어지지 않을 수도 있기 때문에 인풋 이미지의 상하좌우 모서리에 P만큼 0을 채워주는 제로패딩 을 P만큼 적용해준다.

제로패딩

 

마찬가지로, 인풋 이미지의 세로 길이가 $ H_{in} $ 이라면 컨볼루션층을 거친 출력 이미지의 세로길이 $ H_{out} $ 은 아래와 같이 계산된다.

 

$ H_{out} = \frac{H_{in} - F + 2P}{S} + 1 $

 

컨볼루션 층의 출력결과의 3번째 차원은 컨볼루션 필터 개수가 K가 된다.

따라서 컨볼루션층의 결과로 출력되는 차원은 $ [W_{out}, H_{out}, K] $ 이다.

 

예를 들어 [28x28x1] MINST이미지에 4X4크기의 필터 (F=4)에 스트라이드가 2(S=2)이고 제로패딩을 1만큼 적용한(P = 1), 64개의 필터개수(K=64)를 가진 컨볼루션 층을 적용하면 출력 결과로 [14, 14, 64], 즉, 14X14크기의 64개의 활성화맵 이 추출될것이다.

 

$ W_{out} = \frac{28 - 4 + 2 * 1}{2} + 1 = 14 $

$ H_{out} = \frac{28 - 4 + 2 * 1}{2} + 1 = 14 $

$ K = 64 $

 

 

728x90

'알고리즘' 카테고리의 다른 글

드랍아웃(Dropout)  (0) 2024.06.18
CNN을 사용한 MNIST숫자분류기 구현  (0) 2024.06.18
CNN기반 컴퓨터비전처리  (0) 2024.06.17
AutoEncoder를 사용한 MNIST 데이터 재구축  (1) 2024.06.17
오토인코더(Autoencoder)  (0) 2024.06.16
카테고리
작성일
2024. 6. 17. 23:58
작성자
WDmil
728x90

컴퓨터 비전,

즉 컴퓨터가 이미지를 인식하고 이해하는 과정은 여러 가지 어려움이 있다.

  • 밝기 변화
    사진을 찍는 환경에 따라 이미지의 밝기가 달라질 수 있다.
    예를 들어, 같은 물체라도 낮에 찍은 사진과 밤에 찍은 사진은 매우 다르게 보일 수 있다.

  • 변형
    물체는 다양한 각도와 거리에서 찍힐 수 있습니다. 예를 들어, 고양이는 옆모습, 정면, 또는 뒤에서 찍힐 수 있으며, 이는 이미지 인식의 어려움을 가중시킨다.

  • 배경 장애
    물체와 배경이 복잡하게 섞여 있는 경우, 배경의 복잡함이 물체 인식을 방해할 수 있다.

  • 가림
    물체의 일부가 다른 물체에 의해 가려질 수 있다.
    예를 들어, 나무 뒤에 숨어 있는 고양이를 인식하는 것은 일부만 보이기 때문에 어려울 수 있다.

  • 인트라클래스 바리에이션
    같은 종류의 물체라도 형태가 다를 수 있습니다. 예를 들어, 모든 고양이는 고양이지만, 색상, 크기, 무늬 등이 다양합니다.

CNN의 핵심 아이디어: 자동 특징 학습

Convolutional Neural Networks (CNNs)는 컴퓨터 비전에서 주로 사용되는 딥러닝 모델이다.

CNN의 핵심 아이디어는 **Raw Image(원본 이미지)**로부터 **Features(특징)**를 자동으로 학습하는 것,

이는 기존의 방법과 크게 다르다.



Handcrafted Feature vs. End-to-End Learning

기존에는 사람이 직접 이미지를 분석하여 특징을 추출했다.

이를 Handcrafted Feature라고 한다.

예를 들어, 고양이를 인식하기 위해 줄무늬가 많은 필터를 만들어 줄무늬가 있는 경우 고양이로 분류했다.

가끔알바공고 사이트에 뜨는 AI마스킹작업을 말할 수 있다.

하지만 그러한 방식은 한계가 있다.


Handcrafted Feature의 한계

사람이 직접 만든 특징은 모든 경우를 고려할 수 헚다.

예를 들어, 줄무늬가 없는 고양이는 이런 필터에서 잘못 인식될 수 있다.

이러한 예외를 코너 케이스라고 한다.


End-to-End Learning의 도입

최근에는 데이터의 시작과 끝만 사람이 넣어주고, 중간 과정을 전부 딥러닝 모델에 맡기는 End-to-End Learning이 사용된다.

 

딥러닝 모델은 많은 데이터를 학습하여 스스로 특징을 추출한다.

예를 들어, 다양한 고양이의 이미지를 많이 학습시켜 모델이 스스로 줄무늬 유무, 고양이의 형태 등을 학습하게 한다.


Feature Extraction의 자동화

CNN은 Feature Extraction(특징 추출)을 자동으로 수행하는 End-to-End Learning의 대표적인 예이다.

CNN은 여러 층의 뉴런으로 구성되며, 각 층은 이미지를 필터링하여 특징을 추출한다.

 

예를 들어, 첫 번째 층은 가장 기본적인 특징(예: 가장자리)을 추출하고,

다음 층은 더 복잡한 특징(예: 모서리, 패턴)을 추출한다.

이 과정을 통해 CNN은 다음과 같은 장점을 가진다.

 

  • 자동 특징 학습
    사람이 직접 특징을 설계하지 않아도 된다.

  • 높은 정확도
    다양한 데이터를 학습하여 코너 케이스를 포함한 다양한 상황에 대응할 수 있다.

  • 적응성
    새로운 데이터에도 빠르게 적응할 수 있다.



728x90