기계 학습: 컴퓨터 비전의 딥 러닝: 컨볼루셔널 신경망 소개

기사 코드 출처: "deep learning on keras", 아주 좋은 책입니다. 영어를 잘한다면 직접 책을 읽는 것이 좋습니다. 시간이 부족하다면 이 일련의 기사를 읽으면 됩니다.

이번 장에서는 컴퓨터 비전에서 흔히 사용되는 딥러닝 모델의 일종인 컨볼루셔널 신경망(Convolutional Neural Network)을 연구하고, 이를 분류 문제에 적용하는 방법을 배웁니다.
먼저 컨벌루션 신경망의 배경이 되는 몇 가지 이론을 소개하겠습니다. 구체적으로는 다음과 같습니다.

  • 컨볼루션과 최대 풀링이란 무엇입니까?
  • 컨벌루션 네트워크란 무엇입니까?
  • 컨볼루셔널 네트워크는 무엇을 배웠나요?

다음으로 작은 데이터 세트를 사용하여 이미지 분류 문제를 일반화하겠습니다.

  • 소규모 컨볼루셔널 네트워크를 처음부터 훈련시키세요.
  • 과적합을 방지하려면 데이터 증대를 사용하세요.
  • 특징 추출을 위해 사전 훈련된 컨벌루션 네트워크 사용
  • 사전 훈련된 컨벌루션 네트워크의 매개변수 조정

마지막으로 분류 방법을 배우기 위한 몇 가지 시각화 기술을 간략히 설명하겠습니다.

다음은 첫 번째 섹션으로, 컨볼루션 신경망을 소개합니다.

우리는 컨볼루션 신경망 이론에 대해 자세히 알아보고 이것이 컴퓨터 비전 작업에서 왜 그렇게 성공적인지 탐구합니다. 먼저, 실제 작동하는 간단한 컨벌루션 네트워크 예제를 살펴보겠습니다. MNIST 숫자를 분류하기 위해 컨볼루셔널 네트워크를 사용할 것이며 이전에는 완전 연결 네트워크를 사용하여 97.8%의 인식률을 달성했습니다. 우리의 컨벌루션 네트워크는 매우 기본적이지만 정확도는 원래의 완전 연결 네트워크보다 여전히 좋습니다.
다음 6줄의 코드는 가장 기본적인 컨볼루션 네트워크의 모습을 보여줍니다. 이는 실제로 2차원 컨볼루션 레이어와 2차원 최대 풀링 레이어의 스택입니다. 다음에 무엇을 하는지 살펴보겠습니다 컨볼루션에 의해 취해진 텐서의 모양(길이, 너비, 채널 수)에는 배치 차원이 포함되지 않습니다. 이 예에서는 MNIST의 데이터 형식인 (28,28,1) 모양의 입력 데이터를 처리합니다.

from keras import layers
from keras import models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

다음으로 컨볼루셔널 네트워크의 구조를 살펴보겠습니다.

>>> model.summary()
________________________________________________________________
Layer (type) Output Shape Param #
================================================================
conv2d_1 (Conv2D) (None, 26, 26, 32) 320
________________________________________________________________
maxpooling2d_1 (MaxPooling2D) (None, 13, 13, 32) 0
________________________________________________________________
conv2d_2 (Conv2D) (None, 11, 11, 64) 18496
________________________________________________________________
maxpooling2d_2 (MaxPooling2D) (None, 5, 5, 64) 0
________________________________________________________________
conv2d_3 (Conv2D) (None, 3, 3, 64) 36928
================================================================
Total params: 55,744
Trainable params: 55,744
Non-trainable params: 0

각 컨볼루션 레이어와 풀링 레이어의 출력이 3차원 텐서임을 알 수 있습니다. 네트워크가 깊어짐에 따라 너비와 높이가 줄어들기 시작합니다. 채널 수는 컨벌루션 레이어에 전달된 첫 번째 매개변수에 의해 제어됩니다.
다음 단계는 출력 텐서를 완전히 연결된 분류 네트워크에 공급하는 것입니다. 분류기는 1차원 벡터를 처리하고 출력은 3차원 텐서이므로 3차원 출력을 1차원 출력으로 압축해야 합니다. 다음으로 밀도 레이어를 추가합니다.

model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

다음에는 10개 클래스 분류를 수행할 예정이며 활성화 함수로 소프트맥스를 선택하고 출력 차원은 10입니다. 이제 네트워크는 다음과 같습니다.

>>> model.summary()
Layer (type) Output Shape Param #
================================================================
conv2d_1 (Conv2D) (None, 26, 26, 32) 320
________________________________________________________________
maxpooling2d_1 (MaxPooling2D) (None, 13, 13, 32) 0
________________________________________________________________
conv2d_2 (Conv2D) (None, 11, 11, 64) 18496
________________________________________________________________
maxpooling2d_2 (MaxPooling2D) (None, 5, 5, 64) 0
________________________________________________________________
conv2d_3 (Conv2D) (None, 3, 3, 64) 36928
________________________________________________________________
flatten_1 (Flatten) (None, 576) 0
________________________________________________________________
dense_1 (Dense) (None, 64) 36928
________________________________________________________________
dense_2 (Dense) (None, 10) 650
================================================================
Total params: 93,322
Trainable params: 93,322
Non-trainable params: 0

마지막으로 이전에 훈련에 사용한 코드를 사용합니다.

from keras.datasets import mnist
from keras.utils import to_categorical
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
model.compile(optimizer='rmsprop',
 loss='categorical_crossentropy',
 metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=5, batch_size=64)

그런 다음 최종 결과를 평가합니다.

>>> test_loss, test_acc = model.evaluate(test_images, test_labels)
>>> test_acc
0.99080000000000001

단순한 컨볼루션 신경망이 완전 연결 모델보다 훨씬 더 나은 성능을 발휘할 수 있는 이유는 무엇입니까?이 문제를 이해하려면 컨볼루션 계층과 최대 풀링 계층을 계속해서 살펴봐야 합니다.

컨볼루션 연산자

완전 연결 레이어는 전역 패턴을 학습하고 컨벌루션 레이어는 로컬 패턴을 학습합니다.

여기에 이미지 설명을 삽입하세요.

이미지는 가장자리, 질감 등과 같은 로컬 패턴으로 분할될 수 있습니다.

이 주요 기능은 컨벌루션 네트워크에 두 가지 흥미로운 속성을 제공합니다.

  • 학습된 패턴은 변환 불변이며 완전히 연결된 네트워크에서 학습된 패턴은 위치에 따라 달라지지만 컨벌루션 네트워크는 데이터 효율성이 더 높습니다.

  • 아래와 같이 패턴의 공간적 계층 구조를 학습할 수 있습니다. 첫 번째 레이어는 가장자리와 같은 작은 로컬 패턴을 학습하지만 두 번째 컨벌루션 레이어는 첫 번째 레이어를 기반으로 더 큰 특징을 학습합니다. 이를 통해 컨벌루션 네트워크는 복잡한 특징을 더욱 효과적으로 추상화하는 방법을 학습할 수 있습니다.

    여기에 이미지 설명을 삽입하세요.

    시각적 세계는 시각적 모듈의 공간적 계층 구조를 형성합니다. 하이퍼로컬 가장자리는 눈이나 귀와 같은 로컬 객체로 결합되고, 이는 "고양이"와 같은 상위 수준 개념으로 결합됩니다.

    3차원 텐서에 대한 컨볼루션 연산을 "피처 맵"이라고 하며 두 개의 공간 좌표(폭과 높이)와 깊이 좌표(채널 수라고도 함)가 있습니다. RGB 이미지의 경우 깊이의 차원 좌표는 3이다. MNIST의 경우 흑백 이미지의 깊이는 1입니다. 컨볼루션 연산자는 입력 특성 맵에서 패치를 추출하고 모든 패치에 대해 일부 변환을 수행한 다음 출력 특성 맵을 생성합니다. 출력 기능 맵은 여전히 ​​3차원 텐서이지만 여기서 깊이는 더 이상 특정 색상을 나타내지 않고 필터라고 부르는 것을 나타냅니다. 필터는 입력 데이터의 특정 측면을 인코딩합니다. 높은 수준에서 간단한 필터는 입력에 있는 얼굴의 존재를 인코딩할 수 있습니다.
    컨볼루션은 다음 두 가지 주요 매개변수로 정의됩니다.

  • 입력에서 추출된 패치 청크의 크기입니다. 우리의 경우에는 대개
    여기에 이미지 설명을 삽입하세요.

의.

  • 출력 특징 맵의 깊이, 즉 필터 수입니다. 이 예에서는 깊이 32로 시작하여 깊이 64로 끝납니다.

keras의 컨볼루셔널 레이어에서 전달된 첫 번째 매개변수는 Conv2D(output_length, (window_height, window_width))입니다.
컨볼루션은 슬라이딩하고 가능한 모든 위치에서 멈추고 주변 기능에서 3D 패치를 추출하는 방식으로 작동합니다.
개략도는 다음과 같습니다.

여기에 이미지 설명을 삽입하세요.

컨볼루션 작동 방식

출력되는 너비와 높이는 입력된 너비와 높이와 다를 수 있습니다. 여기에는 두 가지 이유가 있습니다.

  • 입력 기능 맵 패딩으로 인해 발생하는 테두리 효과.
  • 슬라이딩의 사용은 나중에 정의하겠습니다.

이러한 주의사항을 살펴보겠습니다.

테두리 효과 및 패딩 이해

고려하다

여기에 이미지 설명을 삽입하세요.

특징 맵은 총 25개의 작은 블록입니다. 하지만 9개의 서로 다른 작은 조각만 있으므로 집중할 수 있습니다.

여기에 이미지 설명을 삽입하세요.

작은 창문에. 따라서 출력 특징 맵은 다음과 같습니다.

여기에 이미지 설명을 삽입하세요.

: 이렇게 하면 각 차원에서 두 개의 작은 블록으로 많이 줄어들고 이전 예에서 "경계 효과"를 볼 수 있습니다.
여기에 이미지 설명을 삽입하세요.

5x5 입력 기능 맵에서 3x3 패치의 유효한 위치

원래 입력과 동일한 출력 특징 맵을 얻으려면 패딩을 사용하도록 선택할 수 있습니다. 적절한 수의 행 및 열 벡터를 추가하여 채웁니다.

여기에 이미지 설명을 삽입하세요.

창에서는 왼쪽과 오른쪽에 열을 추가하고 위쪽과 아래쪽에 행을 추가하도록 선택할 수 있습니다. ~을 위한

여기에 이미지 설명을 삽입하세요.

창에는 두 줄만 있습니다.

여기에 이미지 설명을 삽입하세요.

25개의 3x3 패치를 추출할 수 있도록 5x5 입력 패딩

컨볼루션 레이어에서는 "padding" 매개변수를 통해 패딩을 구성할 수 있는데, "padding" 매개변수에는 "valid"와 "same"이라는 두 가지 값이 있는데, 전자는 패딩이 없다는 뜻이고, 후자는 입력과 출력이 동일하다는 뜻이다. 너비와 높이가 동일하며 패딩 매개변수의 기본값은 "유효함"입니다.

컨볼루션 슬라이딩 이해

출력 크기에 영향을 미치는 또 다른 요소는 "스트라이드"입니다. 지금까지 컨볼루션에 대한 설명에서는 컨볼루션 창의 중앙 블록이 구성되어 있다고 가정했습니다. 그러나 실제로 두 개의 연속 창 사이에는 "stride"라고 하는 컨볼루션 매개변수가 있으며 기본값은 1입니다. 다음 그림에서는 보폭이 2로 설정된 것을 볼 수 있습니다.

여기에 이미지 설명을 삽입하세요.

2x2 스트라이드를 포함한 3x3 컨볼루션 패치

2의 보폭을 사용한다는 것은 너비와 높이가 모두 2배로 다운샘플링됨을 의미합니다. 슬라이딩 컨볼루션은 다양한 모델에서 유용할 수 있지만 실제로는 거의 사용되지 않으며 항상 익숙해지는 것이 좋습니다.
특징을 다운샘플링하기 위해 슬라이딩 외에도 최대 풀링 연산자를 통해 수행할 수도 있습니다.

최대 풀링 연산자

컨볼루션 예에서는 슬라이딩 컨볼루션과 마찬가지로 다운샘플링에 매우 공격적인 최대 풀링 후에 기능 맵 수가 절반으로 줄어드는 것을 볼 수 있습니다.
Max pooling은 입력특징에서 윈도우를 추출하여 각 채널의 최대값을 출력하는 방식으로 구성됩니다. 이는 컨볼루션과 매우 유사합니다.
우리는 왜 풀링을 하는가? 풀링 단계가 제거되면 어떻게 되나요?

model_no_max_pool = models.Sequential()
model_no_max_pool.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model_no_max_pool.add(layers.Conv2D(64, (3, 3), activation='relu'))
model_no_max_pool.add(layers.Conv2D(64, (3, 3), activation='relu'))

출력 구조:

>>> model_no_max_pool.summary()
Layer (type) Output Shape Param #
================================================================
conv2d_4 (Conv2D) (None, 26, 26, 32) 320
________________________________________________________________
conv2d_5 (Conv2D) (None, 24, 24, 64) 18496
________________________________________________________________
conv2d_6 (Conv2D) (None, 22, 22, 64) 36928
================================================================
Total params: 55,744
Trainable params: 55,744
Non-trainable params: 0

이 설정에 문제가 있나요? 두 가지 점이 있습니다.

  • 이는 공간 수준 기능을 학습하는 데 도움이 되지 않습니다.
    여기에 이미지 설명을 삽입하세요.

레이어 3의 창에는 입력만 포함됩니다.

여기에 이미지 설명을 삽입하세요.

정보. 컨벌루션 네트워크가 학습할 수 있는 고급 기능은 여전히 ​​너무 작습니다. 모든 입력 정보를 포함하려면 마지막 컨볼루셔널 레이어가 필요합니다.

  • 최종 특성에 계수가 너무 많습니다.

간단히 말해서, 다운샘플링은 특징 계수의 수를 줄이는 동시에 연속적인 컨벌루션 레이어가 더 큰 창을 처리하여 공간 필터의 수를 줄이는 데 사용됩니다.
최대 풀링이 다운샘플링을 달성하는 유일한 방법은 아닙니다. 또한 스트라이드도 사용할 수 있고 평균 풀링도 사용할 수 있다는 것을 알고 있습니다. 그러나 최대 풀링은 종종 이러한 대안보다 더 나은 성능을 발휘합니다.

추천

출처blog.csdn.net/lijunhcn/article/details/135073031