[케라스(keras) 이해] 5장. 컴퓨터 비전을 위한 딥러닝 (1)
본 글은 [케라스 창시자에게 배우는 딥러닝] - (박해선 옮김) 책을 개인공부하기 위해 요약, 정리한 내용입니다.
전체 코드는 https://github.com/ingu627/deep-learning-with-python-notebooks에 기재했습니다.(원본 코드 fork)
뿐만 아니라 책에서 설명이 부족하거나 이해가 안 되는 것들은 외부 자료들을 토대로 메꿔 놓았습니다. 즉, 딥러닝은 이걸로 끝을 내보는 겁니다.
오타나 오류는 알려주시길 바라며, 도움이 되길 바랍니다.
5_1. 합성곱 신경망 소개
- 일반 DNN은 기본적으로 1차원 형태의 데이터를 사용한다. 때문에 이미지가 입력값이 되는 경우, 이것을 flatten시켜서 한줄 데이터로 만들어야 하는데 이 과정에서 이미지의 공간적/지역적 정보(spatial/topological information)가 손실된다.
- 추상화과정 없이 바로 연산과정으로 넘어가 버리기 때문에 학습시간과 능률의 효율성이 저하된다.
- CNN은 이미지를 날것(raw input) 그대로 받음으로써 공간적/지역적 정보를 유지한 채 특성(feature)들의 계층을 빌드업한다.
- CNN의 중요 포인트는 이미지 전체보다는 부분을 보는 것, 그리고 이미지의 한 픽셀과 주변 픽셀들의 연관성을 살리는 것이다.
- 합성곱 신경망은 크게 합성곱층 (Convolution layer)과 풀링층 (Pooling layer)으로 구성
- CONV는 합성곱 연산을 의미하고, 합성곱 연산의 결과가 활성화 함수 ReLU를 지난다. 이 두 과정을 합성곱층이라고 한다. 그 후에 POOL이라는 구간을 지나는데 이는 풀링 연산을 의미하며 풀링층이라고 한다.
Conv2D
와MaxPooling2D
층의 출력은 (height, width, channels) 크기의 3D 텐서이다.- 높이와 너비 차원은 네트워크가 깊어질수록 작아지는 경향이 있다.
- 채널의 수는 Conv2D 층에 전달된 첫 번째 매개변수에 의해 조절된다.(32개 또는 64개)
- 위와 같이 결과는 변환 전에 가지고 있던 공간적인 구조(spatial structure) 정보가 유실된 상태이다.
- 여기서 공간적인 구조 정보라는 것은 거리가 가까운 어떤 픽셀들끼리는 어떤 연관이 있고, 어떤 픽셀들끼리는 값이 비슷하거나 등을 포함하고 있다.
- 결국 이미지의 공간적인 구조 정보를 보존하면서 학습할 수 있는 방법이 필요해졌고, 이를 위해 사용하는 것이 합성곱 신경망이다.
- CNN - activation - Pooling 과정을 통해 이미지 부분 부분의 주요한 Feature 들을 추출한다.
5_1_1. 합성곱 연산
- Dense층은 입력 특성 공간에 있는 전역 패턴을 학습한다.
- 합성곱층은 입력 특성 공간에 있는 지역 패턴을 학습한다.
- 이미지일 경우 작은 2D 윈도우(window)로 입력에서 패턴을 찾는다.
- 이미지는 에지(edge), 질감(texture) 등 지역 패턴으로 분해될 수 있다.
특징
- 학습된 패턴은 평행 이동 불변성을 가진다.
- 컨브넷이 이미지의 오른쪽 아래 모서리에서 어떤 패턴을 학습했다면 다른 곳에서도 이 패턴을 인식할 수 있다.
- (완전 연결 네트워크는 새로운 위치에 나타난 것은 새로운 패턴으로 학습해야 한다.)
- 적은 수의 훈련 샘플을 사용해서 일반화 능력을 가진 표현을 학습할 수 있다.
- 컨브넷은 패턴의 공간적 계층 구조를 학습할 수 있다.
- 첫 번째 합성곱 층이 에지 같은 작은 지역 패턴을 학습한다.
- 두 번째 합성곱 층은 첫 번째 층의 특성으로 구성된 더 큰 패턴을 학습한다.
- 이런 방식을 사용하여 컨브넷은 매우 복잡하고 추상적인 시각적 개념을 효과적으로 학습할 수 있다.
- 합성곱 연산은 특성 맵(feature map)이라고 부르는 3D 텐서에 적용된다.
- 이 텐서는 2개의 공간(높이와 너비)과 깊이 축(=채널)으로 구성된다.
- RGB 이미지는 3개의 컬러채널을 가지므로 깊이 축의 차원이 3이 된다.
- 흑백 이미지는 깊이 축의 차원이 1.
- 합성곱 연산은 입력 특성 맵에서 작은 패치들을 추출하고 이런 모든 패치에 같은 변환을 적용하여 출력 특성 맵을 만든다.
- 특성 맵 : 입력으로부터 커널을 사용하여 합성곱 연산을 통해 나온 결과
- 필터 (filter) : 입력 데이터의 어떤 특성을 인코딩한다.
- 필터 하나의 크기는
(patch_height, patch_width, input_depth)
이다. - ex. (26, 26, 32) 크기의 특성 맵은 32개의 출력 채널 각각은 26 x 26 크기의 배열 값을 가진다.
- 입력에 대해 32개의 필터를 적용 (Conv2D의 첫 번째 매개변수(필터 또는 채널 수)가 추력 특성 맵의 깊이 차원을 결정)
- 필터 하나의 크기는
2개의 파라미터 정의
- 입력으로부터 뽑아낼 패치의 크기 : 전형적으로 3x3 또는 5x5 크기를 사용한다.
- 특성 맵의 출력 깊이 : 합성곱으로 계산할 필터의 수
-
특성맵 (feature map) : 입력으로부터 커널을 사용하여 합성곱 연산을 통해 나온 결과
- 케라스의 Conv2D 층에서 이 파라미터는
Conv2D(output_depth, (window_height, window_width))
처럼 첫 번째와 두 번째 매개변수로 전달된다. - 3D 특성 맵 위를 3x3 또는 5x5 크기의 윈도우가 슬라이딩(sliding)하면서 모든 위치에서 3D 특성 패치를 추출하는 방식으로 합성곱이 작동한다.
- 패딩 (padding) : 입력 특성 맵의 가장자리에 적절한 개수의 행과 열을 추가
- 합성곱 연산 이후에도 특성 맵의 크기가 입력의 크기와 동일하게 유지되도록 하고 싶을 때 패딩을 쓴다.
- 스트라이드 (stride) : 필터를 적용하는 위치의 간격 (이동 범위)
5_1_2. 최대 풀링 연산
- 최대 풀링의 역할 : 강제적으로 특성 맵을 다운샘플링하는 것
- 다운샘플링을 하는 이유는 처리할 특성 맵의 가중치 개수를 줄이기 위해서
- 최대 풀링 (Max pooling) : 입력 특성 맵에서 윈도우에 맞는 패치를 추출하고 각 채널별로 최댓값을 출력한다.
- CNN에서는 padding을 이용해서 사이즈를 보존해주되, 동시에 사이즈를 점점 줄어나가는 것이 중요하다.
5_2. 소규모 데이터셋에서 밑바닥부터 컨브넷 훈련하기
- 캐글의 데이터 셋 불러오기 : https://www.kaggle.com/c/dogs-vs-cats/data
os.mkdir()
: 해당 주소에 폴더를 만든다.shutil.rmtree
: 재귀적으로 폴더를 지운다. (존재하면)
os.path.join
: str들을 붙여준다.shutil.copyfile(src, dst)
: 파일을 src에서 dst로 복사한다.
5_2_3. 네트워크 구성하기
Conv2D
와MaxPooling2D
층을 번갈아 쌓은 컨브넷을 만든다.Conv2D
와MaxPooling2D
단계를 하나 더 추가하면 네트워크의 용량을 늘리고 Flatten 층의 크기가 너무 커지지 않도록 특성 맵의 크기를 줄일 수 있다.- 150x150 크기(임의로 선택)의 입력으로 시작해서 Flatten 층 이전에 7x7 크기의 특성 맵으로 줄어든다.
- 특성 맵의 깊이는 네트워크에서 점진적으로 증가하지만(32에서 128까지), 특성 맵의 크기는 감소한다.(150x150에서 7x7)
강아지 vs 고양이 분류를 위한 소규모 컨브넷 만들기
컨브넷 코드 파헤치기
model.add(layers.Conv2D(32, (3,3), activation='relu', input_shape=(150,150,3)))
-> (None, 148, 148, 32), param : 896Convolution
: 이미지에 kernel이나 필터를 적용하는 과정input_shape=(150, 150 ,3)
: image_height=150, image_width=150, 그리고 color_channels 는 3을 의미activation='relu'
: relu 는 (Rectified Linear Unit의 약자). 보통 활성화 함수로 쓰이고, input값이 0이하이면 0으로 나타내고, input값이 양수이면 input값을 그대로 나타낸다.- 비선형 문제를 해결하기 위해.
- 인풋값(150,150)이 no-padding을 통해 (148,148)로 줄어들었다.
(3,3)
: kernel이 3x3 격자무늬32
: kernel 필터의 개수 (feature map이라고도 불리는 convolution 채널을 총 32개 가지게 된다.)Param
의 의미 : R, G, B각각에 3x3 픽셀 kernel을 적용시켰는데, 3x3x3=27개의 픽셀과, bias kernel을 하나 가진다. 따라서 (27+1)x32=896parameter
수 : (노드의 수) * (input의 차원) + (노드의 수)
model.add(layers.MaxPooling2D((2,2)))
-> (None,74,74,32)MaxPooling
: convoluted 이미지의 최댓값을 줄이는 것(=downsampling)- 2X2 kernel을 활용해 최댓값을 뽑는 작업
- feature 개수는 그대로 32개. 이미지의 크기는 반으로 된다.
model.add(layers.Conv2D(64, (3,3), activation='relu'))
-> (None,72,72,64), param : 18496MaxPooling
을 적용한 74x74 feature map은 convoltion 필터를 통과하며 가장자리가 삭제되어 72x72으로 크기가 줄어든다.convolution layer
는 3x3픽셀로 구성된 kernel을 64개 갖는다.Param
의 의미 : 필터의 사이즈가 3x3이고 개수는 32개 -> (3332+1)*64=18496- 이 과정을 반복
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
- 분류하기 위해
dense layer
가 필요. 이 레이어는 1차원 벡터를 갖기 때문에, 앞의 convolutional 레이어의 output을 조개야 한다. (=layers.Flatten()
) - 고양이와 강아지를 분류하기 때문에
sigmoid
함수 사용
- 분류하기 위해
모델의 훈련 선택
5_2_4. 데이터 전처리
- JPEG 데이터가 네트워크에 주입하는 과정
- 사진 파일을 읽는다.
- JPEG 콘텐츠를 RGB 픽세 값으로 디코딩한다.
- 그다음 부동 소수 타입의 센서로 변환한다.
- 픽셀 값의 스케일을 [0,1] 사이로 조정한다. (신경망은 작은 입력 값을 선호한다.)
-> keras.preprocessing.image
가 이런 단계를 자동으로 처리해준다.
ImageDataGenerator
클래스는 디크스에 있는 이미지 파일을 전처리된 배치 텐처로 자동으로 바꾸어 주는 파이썬 제너레이터(generator)를 만들어 준다.- 파이썬 제너레이터(generator) : 특수한 반복자이며 yield 문을 사용하여 만든 경우를 제너레이터 함수, 소괄호와 리스트 내포 구문을 사용하는 경우를 제너레이터 표현식이라고 한다.
ImageDataGenerator
ImageDataGenerator
: 이미지를 학습시킬 때 학습데이터의 양이 적을 경우 학습데이터를 조금씩 변형시켜서 학습데이터의 양을 늘리는 방식중에 하나이다.ImageDataGenerator()
- 객체 생성
flow_from_directory()
메서드는 서브 디렉터리의 순서대로 레이블을 할당한다.- datagen 이라는 틀에 flow 함수를 사용해서 실제 데이터를 파라미터를 넣어주면 이미지 변형이 완료된다.
target_size
: 이미지 사이즈batch_size
: 배치사이즈class_mode
: Y 값 변화방법 ex) ‘categorical’color_mode
: 이미지 채널 수 ex) ‘rgb’shuffle
: 랜덤 여부
제너레이터를 사용한 데이터에 모델을 훈련시키기
fit_generator
메서드는 fit 메서드와 동일하되 데이터 제너레이터를 사용할 수 있다.- 이 메서드는 첫 번째 매개변수로 입력과 타깃의 배치를 끝없이 반환하는 파이썬 제너레이터를 기대한다.
- 데이터가 끝없이 생성되기 때문에 케라스 모델에 하나의 에포크를 정의하기 위해 제너레이터로부터 얼마나 많은 샘플을 뽑을 것인지 알려주어야 한다.
steps_per_epoch
매개변수에서 이를 설정한다.
- 제러네이터부터
steps_per_epoch
개의 배치만큼 뽑은 후, 즉steps_per_epoch
횟수만큼 경사 하강법 단계를 실행한 후에 훈련 프로세스는 다음 에포크로 넘어간다. validation_data
로 제너레이터를 전달하면 검증 데이터의 배치를 끝없이 반환한다.- 따라서 검증 데이터 제너레이터에서 얼마나 많은 배치를 추추하여 평가할지
validation_steps
매개변수에 지정해야 한다.
- 훈련이 끝나면 항상 모델을 저장하는 것이 좋다.
내용 정리
- 비교적 훈련 샘플의 수(2000개)가 적기 때문에 과대적합이 가장 중요한 문제이다.
- 드롭아웃이나 가중치 감소(L2 규제)처럼 과대적합을 감소시킬 수 있는 방법들이 있다.
- 다음에서는 데이터 증식을 시도해 본다.
5_2_5. 데이터 증식 사용하기
- 과대적합은 학습할 샘플이 너무 적어 새로운 데이터에 일반화할 수 있는 모델을 훈련시킬 수 없기 때문에 발생한다.
- 데이터 증식은 기존 훈련 샘플로부터 더 많은 훈련 데이터를 생성하는 방법이다.
- 이 방법은 그럴듯한 이미지를 생성하도록 여러 가지 랜덤한 변환을 적용하여 샘플을 늘린다.
- 훈련할 때 모델이 정확히 같은 데이터를 두 번 만나지 않도록 하는 것이 목표이다.
- 모델이 데이터의 여러 측면을 학습하면 일반화에 도움이 된다.
- 케라스에서는
ImageDataGenerator
가 읽은 이미지에 여러 종류의 랜덤 변환을 적용하도록 설정할 수 있다.
- 여기까진 똑같이 해준다.
ImageDataGenerator를 사용하여 데이터 증식 설정하기
rotation_range
: 랜덤하게 사진을 회전시킬 각도 범위 (0~180사이)width_shift_range
orheight_shift_range
: 사진을 수평과 수직으로 랜덤하게 평행 이동 시킬 범위 (전체 너비와 높이에 대한 비율)shear_range
: 랜덤하게 전단 변환(shearing transformation)을 적용할 각도 범위 (이미지 굴절)- 전담 변환은 rotation_range로 회전할 때 y축 방향으로 각도를 증가시켜 이미지를 변형시킨다.
zoom_range
: 랜덤하게 사진을 확대할 범위horizontal_flip
: 랜덤하게 이미지를 수평으로 뒤집는다. (반전)- 수평 대칭을 가정할 수 있을 때 사용한다.
fill_mode
: 회전이나 가로/세로 이동으로 인해 새롭게 생성해야 할 픽셀을 채울 전략nearest
는 인접한 픽셀 사용constant
는 cval 매개변수 값 사용reflect
는 wrap 사용
그외 파라미터 설정
rescale
: 이미지의 픽셀 값을 조정featurewise_center
: 데이터 세트에 대해 입력 평균을 0으로 설정여부samplewise_center
: 각 샘플 평균을 0으로 설정 여부featurewise_std_normalization
: 데이터 세트의 표준으로 입력을 나눌지 여부samplewise_std_normalization
: 각 입력을 표준으로 나눌지 여부
랜덤하게 증식된 훈련 이미지 그리기
os.listdir
: 경로를 가져와 리스트형식으로 불러옴- 파이썬에서 튜플이나 리스트 2개를 더하면 하나의 튜플로 연결된다.
flow()
메서드는 배치 데이터를 기대하기 때문에 샘플 데이터에 배치 차원을 추가하여 4D 텐서로 만든다.
드롭아웃을 포함한 새로운 컨브넷 정의하기
- 적은 수의 원본 이미지는 새로운 정보를 만들어 낼 수 없고 단지 기존 정보의 재조합만 가능하다.
- 과대적합을 더 억제하기 위해 완전 연결 분류기 직전에
Dropout
층을 추가한다.
데이터 증식 제너레이터를 사용하여 컨브넷 훈련하기
flow()
또는flow_from_directory()
또는flow_from_dataframe()
함수로 Numpy Array Iterator 객체를 만들어줌
모델 저장하기
데이터 증식을 사용했을 때 훈련 정확도와 검증 정확도
- 다른 규제 기법을 더 사용하고 네트워크의 파라미터를 튜닝하면(합성곱 층의 필터 수나 네트워크 층의 수 등) 더 높은 정확도를 얻을 수 있다.
References
- 케라스 창시자에게 배우는 딥러닝
- 딥러닝 CNN, 개념만 이해하기
- 딥 러닝을 이용한 자연어 처리 입문 - 1) 합성곱 신경망(Convolution Neural Network)
- CS231n Convolutional Neural Networks for Visual Recognition
- [딥러닝/머신러닝] CNN(Convolutional Neural Networks) 쉽게 이해하기
- [딥러닝]CNN(Convolutional Neural Networks)(1)
- [Tensorflow 2.0] 합성곱 신경망: CNN
- [이미지 전처리]. ImageDataGenerator 클래스 : 이미지 제너레이터
- [ML] Tensorflow.keras의 flow_from_directory, flow_from_dataframe 사용법
- 3. Convolutional Networks / L2. Convolutional Neural Networks - Pooling Layers
댓글남기기