1월부터 SNU AI라는 딥러닝 논문 리뷰 그룹에 9기로 참여하게 되었다.

그룹에 워낙 대단하신 분들이 많고, 다들 한국 AI를 대표하시는 분들이 시라 지원서를 제출할 때 기대를 거의 안 했다.

사실 나 같은 루키를 받아주실 줄은 별 기대를 안 했는데, 정말 감사하게도 합격이 되었다!

정말 그룹에 참여하는 것 자체도 나에겐 엄청난 영광이고, 그룹에 초대해주셔서 정말 감사하게 생각하고 있다(이번 기수 대략 25분 중 학부생은 나밖에 없는 거 같다...)

 

현재까지 다른 분들의 발표를 3-4주를 들었는데, 너무너무 좋다. 다양한 딥러닝의 주제를 발표해주신다. 설명도 꼼꼼하고 이해하기 쉽게 해 주시고, 발표 내용도 너무 유익해서 너무 감사하게 듣고 있다. 한 번도 빠짐없이 미팅에 참여하고 성실하게 활동해서 다음 기수, 다다음 기수, 다다다음 기수까지 계속 활동을 하고 싶다.

 

어쨌든 나는 4주 차 발표(2월 16일)를 진행하였다. 주제는 EHR Data in DeepLearning이었고, 발표한 논문은 

2018년에 구글이 Nature 자매지에 발표한 'Scalable and accurate deep learning with electronic health records'이다. 

이 분야는 내가 예전부터 공부해보고 싶었던 분야기도 하고, 너무 재밌어 보이는 분야여서 발표 주제로 고르게 되었다. 

 

발표할 때 엄청 떨렸지만, 어찌어찌 잘 마무리 지은 것 같다. 발표를 들으신 분들이 이해가 잘 되고 재밌게 들으셨길 바라고 있다. 그리고 녹화를 한 동영상을 유튜브에 올렸는데(내 첫 유튜브 업로드이다!),

혹시 참고가 될까 하여 링크를 적어보려 한다.

 

발표 끝부분에 살짝 언급이 되었지만, 사실 우리나라에서 아직까지는 EHR, EMR을 딥러닝에 이용한 연구가 많이 발달되지 않다고 하다.

(미국 같은 경우에는 벌써 엄청 인기가 많다고 한다) 얼른 이 분야도 많이 발전이 되었으면 좋겠다! 내가 좋아하는 분야니까

 

www.youtube.com/watch?v=drRt5miYRv0&t=2015s

 

 

def get_pad_size(input_shape, filter_size, strides): #{
    w_input = input_shape[0] # width of input
    h_input = input_shape[1] # height of input    
    w_stride = strides[0] # stride of width
    h_stride = strides[1] # stride of height
    w_filter = filter_size[0] # width of filter
    h_filter = filter_size[1] # width of filter    
    
    output_w = np.ceil(w_input/w_stride)
    output_h = np.ceil(h_input/h_stride)    
    
    if (w_input % w_stride) == 0: #{
        w_pad = max(w_filter - w_stride, 0)
    #}
    else: #{
        w_pad = max(w_filter - (w_input % w_stride), 0)
    #}
    if (h_input % h_stride) == 0: #{
        h_pad = max(h_filter - h_stride, 0)
    #}
    else: #{
        h_pad = max(h_filter - (h_input % h_stride), 0)
    #}    
    
    pad_top = int(np.floor(h_pad/2))
    pad_bottom = int(h_pad - pad_top)
    pad_left = int(np.floor(w_pad/2))
    pad_right = int(w_pad - pad_left)
    
    return (pad_top, pad_right, pad_bottom, pad_left)
#}

간단하게 만들어보았다. tf/keras에서 convolution, pooling layer에서 그냥 padding='same'하면 알아서 padding size 계산해서 패딩을 해주긴 하지만, 가끔 직접 패딩사이즈가 어떻게 되는지 필요할 때도 있어서 padding size를 리턴해주는 함수를 만들어보았다.

 

인풋으로는 input_shape, filter_size, strides 가 들어온다. 모두 (width, height)을 가진 리스트이다. 

이때 padding = 'same'일 경우 padding size를 계산해서, 리턴해준다.

여름에 당차게 블로그를 잘 꾸며 보겠다고 호언장담을 했지만 역시나 오래가지 못했다...

학기가 시작되고 20학점 들으면서 일도 계속하니까 토플 공부도 못하고 있는데 블로그를 쓸 시간은 도저히 나지 않는 것이다ㅠㅠ

그러던 중 인공지능 관련 교양 과목을 하나 듣고 있는데, 인공지능 관련 보고서를 쓰는 과제가 있어서 내가 일하고 있는 분야인 Image Classification 관련 정리도 해볼 겸 주제를 'Image Classification 연구의 동향'으로 잡고 보고서를 썼다. 바빠서 보고서를 자세히는 못 쓰고 의식의 흐름대로 그냥 적어서 깊이 있게는 못 적고, 검토도 못해서 틀린 부분이 많을 수 있지만 그래도 내용을 여기에다도 올려보겠다.

 

 

Image Classification 연구의 동향

 

 

물체 인식, 음성 인식, 자연어 처리 최근 활용되고 있는 여러 인공 지능 응용 분야 중에서 현재까지 가장 많이 발전되고 가장 많이 다뤄지고 있는 분야는 당연 이미지 분류(Image Classification) 분야가 아닐까 생각합니다. 따라서 이번 보고서에서는 지금까지 이미지 분류 연구가 어떻게 발전되어 왔는지, 어떤 요소들이 이미지 분류 모델들을 성공적으로 발전하도록 이끌었는지 살펴보겠습니다.

 

 다소 정체되어 있던 이미지 분류 분야를 폭발적으로 각성시킨 모델은 Convolution 인공지능 모델에 사용하여 ImageNet Challenge(이미지 분류 연구를 위해 제공된 14million 이상의 학습 데이터, 1000개의 클래스를 가진 ImageNet 데이터를 사용하는 일종의 대회)에서 이전 결과들보다 훨씬 높은 정확도를 얻어낸 AlexNet(2012, https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf) 입니다. 

위와 같이 Convolution, Max Pooling, Dense 레이어를 활용한 AlexNet 이전까지의 Top 1 Accuracy 50.9%에서 63%, Top 5 Accuracy 73.8%에서 84.6%으로 획기적인 발전을 이뤄냈습니다. 이후 여러 다른 모델들이 AlexNet 발전시켜서 현재 가장 성능이 좋은 모델(FixEfficientNet-L2, 2020)가 Top 1 Accuracy 88.5%, Top 5 Accuracy 98.7% 정말 좋은 퍼포먼스를 보여주게 되었습니다. 이제 AlexNet으로부터 현재까지의 Image Classification 주요 모델들에 대하여 주요 특징과 발전 과정에 대하여 알아보겠습니다.

 

먼저 VGG16(2014, https://arxiv.org/pdf/1409.1556.pdf) 모델입니다. 

 

(사진 출처: https://neurohive.io/en/popular-networks/vgg16/)

이와 같은 구조를 가지며 71.5% Top 1 Accuracy, 90.1% Top 5 Accuracy 자랑하는 모델은 AlexNet과의 구현 차이는 없지만 단지 많은 layer(13개의 Convolution layer, 2개의 Dense layer) 사용하였을 얼마나 좋은 성능을 가질 있는가를 보여줍니다. 최근의 어마무시하게 거대한 딥러닝 모델들에 비하면  턱없이 작은 수준이지만, 그래도 이렇게 모델의 덩치를 키우는 것 만으로도 5% 이상의 정확도의 향상을 얻을 있다는 것을 보여준 모델이었습니다.

 

 

다음으로 ResNet(2016, https://arxiv.org/pdf/1512.03385.pdf) 대하여 알아보겠습니다. 여러가지의 변종된 모델들이 있지만 기본적으로 옆의 이미지와 같은 구조를 가지는 ResNet 75.8% Top 1 Accuracy, 92.9% Top 5 Accuracy(ResNet 50 기준) 가집니다. 기본적으로 기존의 VGG16 모델보다 많은 layer 사용하고 있고, 중요하게 모델에서는 기존의 모델들과는 다른, Residual Connection이라는 새로운 방법이 사용되었습니다. 그리고 Residual Connection 추후의 여러 모델들도 대부분 사용할만큼 다른 획기적인 방법이라고 있습니다. Residual Connection 방법에 대하여 간단히 설명하면, Convolution Block(convolution layer 2 이상 사용하는 일종의 단위) 인풋을 Block 아웃풋에 더하여 다음 Convolution Block 인풋으로 사용하는 것입니다. 어찌보면 그냥 단순히 기존의 아웃풋에 인풋을 더한 것일 뿐인데 어떻게 방법이 딥러닝 모델들을 획기적으로 발전시킬 있었는지 설명하겠습니다. AlexNet 등장으로부터 모델들은 점점 layer 늘리는 방향으로 발전이 되었고, 이런 방법이 어느 정도 성능을 향상시켜주었습니다. 하지만 계속 layer 늘렸을 어느 순간 성능이 향상되지 않는 현상을 사람들은 발견했습니다. 이유는 역전파를 사용하여 layer들을 학습시킬 , 모델이 깊어지면 깊어질수록 모델의 끝부분(prediction layer 가까운 부분) 모델의 처음부분(input layer 가까운 layer)들로 가면서 점점 기울기가 사라지는(0 가까워지는) gradient vanishing 현상이 심해졌기 때문입니다. 따라서 모델 초반부의 layer들은 제대로 학습이 되지 않았고, 현상은 모델이 깊어질 수록 심해졌습니다. 하지만 이렇게 Residual Connection 통해 블록의 인풋을 아웃풋에 더해주면, 계속해서 이전 블록의 정보를 다음 블록에도 포함시키는 것이므로 역전파를 이용하여 학습 초반부로 gradient 전해질 사라지지 않는 장점을 지니게 됩니다. 따라서 Residual Connection Convolution 이후의 다른 획기적인 방법이라고 생각합니다.

 

 

 다음으로 Inception(2014,  https://arxiv.org/pdf/1409.4842.pdf)모델에 대하여 알아보겠습니다. 78% Top 1 Accuracy, 94.1%

Top 3 Accuary(Inception V3 기준) 가지는 모델은, 일단 이전의 모델들보다 덩치는 커져서 모델의 구조 사진이 너무 커서 전체 이미지를 첨부하지는 못하지만 사진과 같은 Convolution Block 가지고 있습니다. 모델의 크기가 점점 커질수록 사람들의 고민이 생겼습니다. 파라미터가 너무 많아져서 훈련 시간이 너무 길어진다는 것이었습니다. 따라서 제안한 구조가 Inception V3 옆의 이미지와 같은 구조인데요, 1x1 컨볼루션, 파라미터의 개수가가 매우 작은 convolution 이용하여 컨볼루션을 해준 , 블록 내의 레이어들을 각각 다른 방법으로(3x3 convolution, 5x5 convolution, max-pooling )으로 따로 작업한뒤 element-wise 하게 더해줌으로써 하나의 아웃풋 레이어를 만드는 것입니다. 이를 통해 어찌보면 모델이 확장되고 커지고 다른 종류의 filter 크기를 사용하여 학습을 하여 보다 다양한 feature들을 뽑아 낼 있는 장점도 지녔고, 1x1 convolution으로 인하여 파라미터 개수도 줄이는 방법을 고안하게 됩니다. 마찬가지로 이런 구조도 추후의 모델에서 자주 사용되는 구조입니다.

 

마지막으로 Xception(2017, https://arxiv.org/abs/1610.02357) 모델에 대하여 알아보겠습니다. 79% Top 1 Accuracy, 94.5% Top 5 Accuracy 가지는 모델은, 마찬가지로 구조가 너무 커서 전체 이미지를 첨부하지는 못하지만 옆의 이미지와 같은 블록이 사용되었습니다. 가장 차이는 Separable Convolution(Depthwise Convolution + 1x1 Point wise Convolution) 사용하였다는 것 입니다. 마찬가지로 방법은 블록의 크기는 유지시키면서 훨씬 적은 수의 파라미터를 사용하였다는 것에 의미를 가질 있습니다. 일반적인 Convolution 아닌 Separable Convolution 사용할 때의 장점은, 밑의 이미지에서 보이는 것 처럼 인풋 채널의 수만큼의 커널이 각각 채널을 convolution 한다는 것입니다. 

 

 

일반적인 convolution 실행하면 아웃풋 레이어의 채널(예를들어 100개라고 하겠습니다) 수만큼의 커널이 인풋 레이어의 채널(예를들어 10개라고 하겠습니다)수를 각각 돌면서 convolution 하지만, ( 예에서는 100*10) Depthwise 단지 10개의 채널만큼만 convolution 하기에 계산양을 월등히 줄일 있습니다. 마찬가지로 이후에 1x1 컨볼루션을 사용하여 채널수만 늘려주면, 적은 파라미터를 사용하면서도 일반 convolution 사용했을 때와 똑같은 output shape 가질 있습니다.

 

 지금까지 AlexNet 포함하여 5개의 유명한 ImageNet Classification 모델에 대하여 간단히 알아봤습니다. 각각 독특한 특성과 구조를 가진 모델들이지만 전체적으로 공통된 발전 방향을 추구하고 있다고 생각합니다. 첫번째는 어찌됐든 모델의 덩치는 커져야 한다는 것이고, 동시에 그것으로 인한 단점들(많은 파라미터, 길어지는 학습시간) 줄이기 위해 노력하고 있다는 것입니다. 그리고 오버피팅을 줄이기 위한 Dropout, Batchnormalization 등의 방법, 그것들을 Convolution, Activation 등과 어떤 순서, 조합으로 사용해야 하는가의 등의 연구들도 진행되고 있다는 것을 있습니다. 

 

 또한 모델을 학습시키기 위한 Residual Connection 같은 창의적이고 혁신적인 새로운 아이디어들도 필요하다는 것을 있습니다. AlexNet Convolution으로 인해 이미지 분류 딥러닝 모델들이 폭발적으로 발전되었지만, 단계 더 Up하기 위해서는 단순히 모델의 크기를 늘리고 그에 따른 사소한 아이디어들을 더하는 것보다는 Convolution 처럼 엄청나게 획기적인 아이디어가, 그것이 Activation 적용되던, 규제 레이어에 사용되던 상관없고, 모델안의 어느 곳에서든 나타난다면 좋지 않을까 생각을 해봅니다. 단순히 파라미터 조절하고 train image augmentaion 하고 그런 것들 보다는, 다시 한 번 Convolution 능가하는 엄청난 아이디어가 나와서 이미지 분류 모델들을 획기적으로 발전시켜주면 좋겠다는 생각을 해봅니다. 

 

 

convolution layer을 포함하는 model을 직접 만들 때, convolution 후의 output shape을 이용하여 다음 레이어에 넘겨줘야 하는 경우가 있다. 내 기억에는 좀 더 간단하게 모델을 만들 수 있는 Keras 같은 경우에는 우리가 output shape을 계산해야 할 필요는 없지만(그냥 convolution layer을 계속 쌓으면 알아서 output shape을 계산해서 넘겨주는 것 같다), 더 deep 한 level을 건들 수 있는 tensorflow를 이용하여 model을 만들 때는, Convolution후의 shape을 코드를 짜는 사람이 직접 다음 레이어와 맞춰줘야 하는 경우가 많다.

 

그래서 convolution 후의 shape을 구하는 공식을 알아보려고 한다. 물론, convolution이 어떻게 계산되는지 잘 모르는 경우에는 직접 작은 예제(ex, 10x10 image, 2x2 filter, stride=1, padding =(1,1,1,1))등으로 한 번 output shape을 계산해 보는 것을 정말 추천한다! 필자는 직접 해봐서 공식을 유도해봤는데, 예전 수능 수학 공부하던 시절이 떠올라서 잠시나마 추억에 젖었었다. 하지만 매번 공식을 유도해서 output shape을 계산할 순 없으니! 공식을 알아보자. 이전에는 계속 까먹어서 매번 구글링을 해서 사용을 했지만(구글링 하면 쉽게 바로 나온다), 블로그도 시작한 겸 여기다가 구글링 해서 찾은 것을 그래도 적어보자 한다.

 

you can use this formula [(W−K+2P)/S]+1.

  • W is the input volume - in your case 128
  • K is the Kernel size - in your case 5
  • P is the padding - in your case 0 i believe
  • S is the stride - which you have not provided.

So, we input into the formula:

Output_Shape = (128-5+0)/1+1 Output_Shape = (124,124,40)

NOTE: Stride defaults to 1 if not provided and the 40 in (124, 124, 40) is the number of filters provided by the user.

[reference: https://stackoverflow.com/questions/53580088/calculate-the-output-size-in-convolution-layer]

 

한 번 더 정리해보자면, W는 image size다. image의 height, width가 다른 경우(정사각형이 아닌 경우) height과 width를 각각 W에 적용해서 구하면 된다. K는 kernel(filter라고 불리기도 한다) 사이즈이다. P는 얼마큼 패딩을 하는지를 의미한다. S는 스트라이드(필터를 몇 칸 씩 건너뛸 것인지)를 의미한다. 이 공식을 이용하여 output shape을 쉽게 구할 수 있다!

 

참고로, kernel을 움직이다가 rightmost, bottommost 쪽에 자투리가 남을 수도 있을 것이다. 그때는 padding='same' or padding='valid'(tf & keras 기준) 둘 중 어떤 방식을 사용했는지 체크하고 자투리에 적용하면 된다!(same과 valid가 어떻게 다른지 궁금하다면 구글링을 해보자! 나중에 시간이 나면 저 둘의 차이에 대해 포스팅을 해보겠다)

 

AI 업무를 하다 보면 다양한 model들을 사용하게 될 것이다. 

사용자가 직접 model을 만들 수도 있지만, Google, Facebook 같은 기업이나 여러 대학들, 혹은 개인이나 단체에서 이미 만들고 실험을 한 좋은 model들이 많다. 이렇게 만들어진 유명한 model들을 따라가다 보면, 현재 AI 트렌드가 어떤 식으로 변하고 있는지, AI를 발달시키기 위해 대단하신 분들이 어떤 세련된 방법을 고안하셨는지도 공부할 수 있다.

 

현재 나는 Image Classification 관련 업무를 하고 있어서, NLP와 Face Detection 같은 분야의 유명 model들은 대충 '아~이 model 유명하지. 아~이거 들어봤어' 정도의 얕은 지식만 가지고 있다. 그래서 당분간은 Image Classification Model들만 간단히 리뷰를 하려고 한다.

 

Model Review를 할 수 있는 다양한 방법들이 많은 것 같다. paper를 직접 읽던, 구글링을 통해 model structure를 살펴보던, 유튜브에서 model review 영상을 보던... 하지만 이곳에 내가 정리를 하려는 이유는, 저런 방법들을 통해서 model review를 한 직후에는 '아! 이 model 이제 완벽히 이해했어' 생각이 들지만, 3일 지나면 다 까먹기 때문이다...('separable convolution이 xception에 쓰였던가 inception에 쓰였던가 둘 다 다 쓰였던가...? 하필 모델 이름은 헷갈리게 왜 이렇게 비슷한거')

 

그래서 나만의 방식으로 여기다가 리뷰를 해서 이해한 것을 기록하고, 기억하고 싶다.

+ Recent posts