-
이번 강의에서는
-
가장 유명한 신경망 아키텍처 중 하나인
-
CNN에 대해 다뤄보고자 합니다
-
CNN은 이미지 프로세싱이나
자연어 처리 등에서 아주 잘 동작합니다
-
CNN은 이미지 프로세싱이나
자연어 처리 등에서 아주 잘 동작합니다
-
이게 이미지를 입력으로 받는
전형적인 CNN 아키텍처입니다
-
이게 이미지를 입력으로 받는
전형적인 CNN 아키텍처입니다
-
우선 이 이미지에 대해 합성곱을 하여
-
많은 특징맵을 만들어냅니다
-
그리고 이 합성곱으로부터 정보를 축소시키는
서브샘플링을 하고 나면
-
그리고 이 합성곱으로부터 정보를 축소시키는
서브샘플링을 하고 나면
-
그리고 이 합성곱으로부터 정보를 축소시키는
서브샘플링을 하고 나면
-
합성곱과 서브샘플링의 레이어들이 생깁니다
-
합성곱과 서브샘플링의 레이어들이 생깁니다
-
이 부분에서의 모든 정보는
선형 레이어로 연결되는데
-
이 부분에서의 모든 정보는
선형 레이어로 연결되는데
-
이 부분에서의 모든 정보는
선형 레이어로 연결되는데
-
이 선형 레이어는 완전 연결 레이어 또는
dense net이라고도 합니다
-
이 선형 레이어는 완전 연결 레이어 또는
dense net이라고도 합니다
-
전형적인 Softmax classifier와 같죠
-
이것들은 주어진 이미지의
레이블을 예측하는 값이 됩니다
-
이것들은 주어진 이미지의
레이블을 예측하는 값이 됩니다
-
그렇다면 합성곱이란 무엇일까요?
-
이렇게 귀여운 이미지가 하나 있다고
가정해 봅시다
-
가로 길이와 세로 길이가 있겠죠
-
이 경우에는 RGB색상도 있을테니
-
깊이는 3이 됩니다
-
만약 여러분이 간단한
Softmax classifier를 사용한다면
-
우리는 모든 픽셀 정보를
입력으로 사용하게 될 겁니다
-
우리는 모든 픽셀 정보를
입력으로 사용하게 될 겁니다
-
하지만 합성곱의 핵심 아이디어는
-
한 번에 아주 작은 부분의 이미지만 다루는 것입니다
-
한 번에 아주 작은 부분의 이미지만 다루는 것입니다
-
그래서 우리는 이미지보다 훨씬 작은 필터를 사용합니다
-
주로 패치라고 불리는
이미지의 작은 부분만을 다루게 됩니다
-
주로 패치라고 불리는
이미지의 작은 부분만을 다루게 됩니다
-
여기에 어떤 조작을 가하고나면
-
이 패치로부터 한가지 값을 얻어낼 수 있습니다
-
물론 이 필터는 전체 이미지를 다룰 것입니다
-
그래야 전체 이미지를 다 볼 수 있겠죠
-
한 번에 작은 부분만 본다는 것이
합성곱의 핵심 아이디어입니다
-
한 번에 작은 부분만 본다는 것이
합성곱의 핵심 아이디어입니다
-
한 번에 작은 부분만 본다는 것이
합성곱의 핵심 아이디어입니다
-
합성곱이 작은 이미지에서
어떻게 동작하는지 알아봅시다
-
가로세로는 3 x 3
깊이는 1 입니다
-
이게 우리의 이미지이구요
-
필터 사이즈는 우리가 정해야 합니다
-
2 x 2 필터를 준비하고
깊이는 이미지와 같게 설정합니다
-
2 x 2 필터를 준비하고
깊이는 이미지와 같게 설정합니다
-
2 x 2 필터를 준비하고
깊이는 이미지와 같게 설정합니다
-
자 이제 합성곱을 해보겠습니다
-
기본원리는
이 2 x 2 필터로 이미지를 보는 것입니다
-
기본원리는
이 2 x 2 필터로 이미지를 보는 것입니다
-
이미지에서 2 x 2 부분만 보면서
어떤 계산을 할 것입니다
-
이미지에서 2 x 2 부분만 보면서
어떤 계산을 할 것입니다
-
이미지에서 2 x 2 부분만 보면서
어떤 계산을 할 것입니다
-
그리고 필터를 움직입니다
-
이를 움직이는 정도를
스트라이드(Stride)라고 합니다
-
여기서는 스트라이드가 1이므로
-
우리는 필터를 1스텝씩
오른쪽으로 움직일 것입니다
-
우리는 필터를 1스텝씩
오른쪽으로 움직일 것입니다
-
그리고 어떤 연산을 하고나면
숫자 하나를 얻을 수 있습니다
-
이제 오른쪽으로는 필터를
더 이상 움직일 공간이 없으므로
-
아래로 움직이겠습니다
-
이것이 합성곱 동작방법입니다
-
그리고 여기서도 마찬가지로 합성곱을 수행하면
-
전체 이미지를 다 돌게 됩니다
-
그 결과로 2 x 2에 대해
4개의 숫자를 얻을 수 있는데
-
그 결과로 2 x 2에 대해
4개의 숫자를 얻을 수 있는데
-
이게 바로 합성곱의 출력입니다
-
이 필터로 합성곱 연산을
어떻게 하는지 알아봅시다
-
여기 픽셀값
1, 2, 3, 4, 5, 6, 7, 8, 9가 있습니다
-
여기 픽셀값
1, 2, 3, 4, 5, 6, 7, 8, 9가 있습니다
-
웨이트 값이 있는데요
-
웨이트는 보통 트레이닝 과정을 통해 변화하는데
-
일단 여기서는
-
이렇게 특정 값이 있다고 가정하겠습니다
-
제일 처음 우리가 할 것은
-
필터를 이용하여
작은 패치를 선택하는 것입니다
-
그리고 그 패치 안의 값들을
-
필터를 이용하여 계산하면
-
숫자값 하나가 생성됩니다
-
어떤 연산을 해야할까요?
-
여기서는 내적 연산이 필요합니다
-
w ・ x이죠
-
이것이 바로 우리가 연산하는 방법입니다
-
여기서는 W가 [0.1, 0.5, 0.3, 0.4]이고
-
X는 [1, 2, 4, 5]가 됩니다
-
X는 [1, 2, 4, 5]가 됩니다
-
내적을 구하기 위해 우리는 이 두 값을 곱하고
-
또 이렇게 두 값을 곱하는 방법을 반복합니다
-
그리고 곱해진 값들을 다 더합니다
-
예를 들어, 여기서는
-
0.1 x 1 = 0.1
-
0.5 x 2 = 1 이런식으로
-
여기는 1.2
-
여기는 2이죠
-
이제 이 값들을 모두 더하면
-
4.3이 됩니다
-
그래서 이 값은 4.3이 되는 것입니다
-
그래서 이 값은 4.3이 되는 것입니다
-
그래서 이 값은 4.3이 되는 것입니다
-
이제 윈도우를 여기로 옮겨보겠습니다
-
같은 방법으로, 필터를 이용해서
-
W・X를 계산합니다
-
우리는 이를 W의 역행렬에 X를 곱한 것으로
-
표현하기도 합니다
-
행렬곱셈을 하는 셈이죠
-
그러면 이 값을 얻을 수 있고
-
이 윈도우를 다시 다른 곳으로 움직이면
-
이 윈도우를 다시 다른 곳으로 움직이면
-
이제 여기 값을 얻을 수 있습니다
-
패딩을 추가하는 방법도 널리 쓰입니다
-
제로 패딩이라고 부르는데요
-
이미지 경계에 0 값을
이렇게 추가하는 방법입니다
-
이미지 경계에 0 값을
이렇게 추가하는 방법입니다
-
이렇게 하면 특징 맵의
출력을 바꿀 수 있는데요
-
예를 들어
-
같은 2 x 2 필터로
-
이미지의 이 부분을 봅니다
-
그 다음에는 이 부분을 보구요
-
마지막에는 이 부분을 보게 보게됩니다
-
그러면 이렇게 3개의 값을 얻겠죠
-
이렇게 아래 방향으로도 3개의 값을 얻을 수 있고
-
그 결과로 3 x 3의 특징맵이 생깁니다
-
이 애니메이션은
-
어떻게 합성곱이 동작하는지를 보여줍니다
-
이 사이즈의 필터로
-
이미지 전체를 순회하고
-
각 값을 계산하여
-
특징맵을 만듭니다
-
물론 여러 사이즈의 패딩을
고려해볼 수 있습니다
-
패딩 사이즈가 다르면
-
특징맵의 사이즈도 달라지겠죠
-
앞서 보여드린 예제에서
-
우리는 스트라이드 크기를 1로 설정했습니다
-
그래서 한번에 1칸씩 (필터를) 움직였죠
-
그래서 한번에 1칸씩 (필터를) 움직였죠
-
하지만 우리는 2칸씩 움직일 수도 있습니다
-
3칸씩 움직일 수도 있구요
-
이게 바로 스트라이드입니다
-
그럼 깊이가 있는 이미지는 어떨까요?
-
RGB 컬러 이미지를 예를 들면
-
깊이는 3이 됩니다
-
그렇다고 해도 기본 아이디어는 같습니다
-
유일한 차이는
-
같은 깊이의 필터를 사용한다는 것입니다
-
필터를 사용해서
-
우리는 이미지의 작은 부분만을 보게 되고
-
내적 연산을 계산합니다
-
여기서는 몇 번의 연산이 더 필요한데요
-
5 x 5 대신
-
5 x 5 x 3
그래서 75차원 내적 연산이 됩니다
-
이 숫자 하나를 계산하기 위해
종종 편향을 추가하기도 합니다
-
이 방법을 적용해서
-
이 숫자를 얻어냅니다
-
여기 32 x 32 사이즈의 이미지가 있고
-
5 x 5 사이즈의 필터가 있을 때
-
어떤 값이 출력될지 생각해봅시다
-
여기서 시작을 하면
스트라이드가 1이니까
-
한 번에 1칸씩 이동합니다
-
이렇게 몇 칸을 갈 수 있을지를 보면
-
바로 28칸입니다
여기서도 마찬가지로
-
1칸씩 총 몇 칸을 내려갈 수 있을지를 보면
-
여기서도 28칸입니다
-
이것이 활성맵 사이즈의 출력입니다
-
물론 여러 개의 필터를 적용할 수 있습니다
-
여기 우린 2개의 다른 필터를 갖고 있습니다
-
주로 두 필터는 다른 값을 갖습니다
-
두 필터는 다른 활성맵을 생성하구요
-
아주 많은 필터를 사용할 수도 있습니다
-
사용하는 필터의 개수가
-
생성된 활성맵의 깊이를 결정합니다
-
만약 6개의 필터를 사용한다면
-
깊이가 6인 활성맵이 생성됩니다
-
이 28이라는 값은
-
원본 이미지 사이즈와 필터의 사이즈에
의해서 정해집니다
-
비슷한 방법으로
우리는 여기에 또다른 합성곱 레이어를
-
적용할 수 있습니다
10개의 필터를 사용해서 말이죠
-
10개의 필터를 사용하면
-
출력의 깊이는 10이 됩니다
-
여기서 28 x 28 이미지에
5 x 5 필터를 사용하면
-
여기서 28 x 28 이미지에
5 x 5 필터를 사용하면
-
24 x 24 활성맵을 생성합니다
-
각 합성곱 레이어 이후에 풀링 레이어 또는
-
서브샘플링 레잉를 사용하기도 합니다
-
이 아이디어는 합성곱 레이어에서 생성된
정보의 양을 줄이는 것입니다
-
이 아이디어는 합성곱 레이어에서 생성된
정보의 양을 줄이는 것입니다
-
이 아이디어는 합성곱 레이어에서 생성된
정보의 양을 줄이는 것입니다
-
어떻게 하면 될까요?
-
이전 합성곱에서 생성된
특징맵 또는 활성맵이 있다고 가정해 봅시다
-
이전 합성곱에서 생성된
특징맵 또는 활성맵이 있다고 가정해 봅시다
-
이전 합성곱에서 생성된
특징맵 또는 활성맵이 있다고 가정해 봅시다
-
이 때, 앞서 설명한 필터 아이디를 사용할 것입니다
-
필터 사이즈는 2 x 2로 하여
-
이미지를 한번에 2 x 2 씩 볼 것입니다
-
이미지를 한번에 2 x 2 씩 볼 것입니다
-
이 때 맥스 풀링이 아주 널리 쓰입니다
-
이 패치에서
-
최댓값을 선택합니다
여기서는 6이네요
-
이 값을 복사해서
-
출력값으로 사용합니다
-
그리고 이 윈도우를 여기로 이동할텐데
-
얼마나 이동시킬 것인가는
-
스트라이드를 보면됩니다
2네요
-
그럼 윈도우를 2칸을 이동시켜서
-
그리고 최댓값을 찾아
-
이 값을 출력값으로 사용합니다
-
이것이 최댓값이고
이것이 최댓값이네요
-
맥스 풀링을 하면
-
이 출력이 생성됩니다
-
이 애니메이션은
-
맥스 풀링이 동작하는 원리를 보여줍니다
-
이 지역에서 최댓값을 선택하여
-
출력값으로 사용합니다
-
또한 평균 풀링같은 다른 연산 방법도 있습니다
-
이는 패치에서 평균값을 계산하는 방법입니다
-
우리는 CNN에서 합성곱이
어떻게 동작하는지를 알아보았습니다
-
서브샘플링이 무엇인지도 알아보았고
-
이것은 이전 강의에서 다룬
Softmax classifier와 똑같습니다
-
이것은 이전 강의에서 다룬
Softmax classifier와 똑같습니다
-
완전 연결 신경망과
지역 연결 신경망인 CNN의 차이는 무엇일까요?
-
완전 연결 신경망과
지역 연결 신경망인 CNN의 차이는 무엇일까요?
-
완전 연결 신경망과
지역 연결 신경망인 CNN의 차이는 무엇일까요?
-
완전 연결 신경망은
-
주어진 이미지에서
-
모든 정보를 읽어
-
입력으로 사용합니다
-
반면 CNN에서는
-
작은 사이즈의 필터들을 사용하며
모든 웨이트는 공유됩니다
-
이 작은 사이즈의 필터로
-
이미지 전체를 순회합니다
-
그 결과로
(지역 연결 신경망은)
-
더 나은 웨이트를 갖게되고
-
이미지를 다루는데 더 유동적입니다
-
이를 직접 구현해 봅시다
-
이 예제에서는
MNIST 데이터셋을 사용할 것입니다
-
두 합성곱 레이어과
-
하나의 완전 연결 레이어을 활용해 보겠습니다
-
합성곱 레이어에서는
-
Conv2d라는 API를 사용합니다
-
이 함수는 입력값으로 in_channels
out_channels, kernal_size를 받습니다
-
여기 예제에서는
-
이미지 색상을 하나만 사용하므로
-
in_channels 사이즈는 1이고
-
out_channels는 여러분이 원하는
출력 개수만큼 정할 수 있습니다
-
여기서는 10개의 출력을
-
생성하고 싶다고 칩시다
-
커널(필터) 사이즈는 앞과 마찬가지로
-
5 x 5로 설정할 수 있습니다
-
맥스 풀링은 더 간단합니다
-
한 번에 어느 사이즈로 볼 것인지
커널 사이즈만 정해주면 됩니다
-
한 번에 어느 사이즈로 볼 것인지
커널 사이즈만 정해주면 됩니다
-
이것은 어떻게 구현할까요?
-
이것은 Softmax classifier와 완전 동일합니다
-
하나의 Linear만 사용합니다
-
구현 방법을 알아봅시다
-
우선 클래스를 생성하고
-
생성자에서는 필요한 요소들을 정의합니다
-
예를 들어
-
여기 Conv2d에서는 in_channels로 1
-
out_channels로 10로
커널 사이즈는 5로 설정하였습니다
-
두 번째로, 앞에서 10개의 출력을 생성했기 때문에
-
여기서는 in_channels로 10을 설정합니다
-
그러니까 이 두 값은 반드시 같아야 합니다
-
20개의 out_channels을 만들 예정이고
-
커널 사이즈는 5로 설정하겠습니다
-
그리고 맥스 풀링을 정의하고
-
완전 연결 레이어를 정의합니다
-
forward 함수에서는 이 모든 것들을 연결합니다
-
x를 입력받아 합성곱 레이어를 거치고
-
맥스 풀링을 거쳐서 reLU에 넘깁니다
-
그리고 이 출력 x는 두 번째 레이어에서
-
다시 입력으로 사용되는 방식입니다
-
여기 20채널의 활성맵이 있습니다
-
여기 20채널의 활성맵이 있습니다
-
이를 flatten하여
선형에 맞게 변형하고 싶은데요
-
텐서를 단순하게 flatten하는 방법으로
-
여기서 view를 사용했습니다
-
이 입력 사이즈(in_size)를 flatten텐데
-
이것은 N 배치 사이즈가 됩니다
-
나머지는 자동으로 계산됩니다
-
이렇게 flatten 한것을
-
여기 완전 연결 레이어로 넘기면
-
최종 출력값이 생성되고
-
이것을 여기로
-
log_softmax로 넘깁니다
-
그러면 여기 들어가야 할 값은 무엇일까요?
-
이 모든 합성곱 과정을 거치고 나면
-
우리가 얻을 수 있는 사이즈는 무엇일까요?
-
이것은 중요한 질문입니다
-
주어진 이미지의 사이즈와 필터의 사이즈를 통해
-
하나씩 계산할 수는 있지만
-
확실하지 않다면
-
그냥 임의의 수를 사용하면 됩니다
-
그리고 그냥 프로그램을 실행하면
-
PyTorch는 에러를 발생합니다
-
에러는 64 x 320 사이즈의 행렬을
-
100 x 10 사이즈의 행렬과 곱하려고 하였으므로
-
미스매치가 발생했다는 내용입니다
-
flattening 이후에
-
우리가 얻은 값은 이것입니다
-
이 64는 배치사이즈 N이라 보면 되겠고
-
이것은 우리의 flatten 벡터
텐서 사이즈인 320입니다
-
그러면 여기 들어갈 알맞은 값은 무엇일까요?
-
이 두 숫자는 같아야 합니다
-
그러므로 여기 적절한 숫자는 320입니다
-
우리가 실제로 계산해 볼 필요없이
-
그냥 아무 숫자를 넣고 실행해보면
-
적절한 숫자를 찾을 수 있습니다
-
만약 텐서 사이즈를 알고 싶다면
-
여기서 그냥 x.size()를 출력해보면 됩니다
-
그러면 텐서 사이즈를 알 수 있습니다
-
이렇게 하면 모든 문제가 해결됩니다
-
나머지 부분도 동일합니다
-
우리가 Softmax classifer에서
트레이닝 한 방법과 동일합니다
-
우리가 Softmax classifer에서
트레이닝 한 방법과 동일합니다
-
그러면 이 결과를 얻을 수 있습니다
-
forward를 실행 하고 손실을 계산합니다
-
그리고 backword를 하고 update하면 됩니다
-
Epoch가 실행될 때마다 손실값은 작아집니다
-
그러면 98%의 정확도가 나오네요
-
앞 강의에서는 90%였는데
-
CNN을 이용하니 98%가 나오네요
-
훨씬 나은 결과입니다
-
이제 우리는 CNN을 이해하였으므로
-
더 많은 레이어를 연결할 수 있습니다
-
3개, 4개 이상으로요
-
완전 연결 레이어를 위해
많은 레이어를 사용할 수도 있습니다
-
연습문제로 이렇게 보다 깊은
네트워크를 구성해 볼 수 있습니다
-
연습문제로 이렇게 보다 깊은
네트워크를 구성해 볼 수 있습니다
-
또한 각 커널마다 다른 사이즈를 설정해보고
-
어떤 것이 더 잘 동작하는지
알아볼 수도 있습니다
-
다음 강의에서는
-
더 흥미로운 심화된 CNN 구조를
알아보도록 하겠습니다
-
더 흥미로운 심화된 CNN 구조를
알아보도록 하겠습니다