😶 초록 (Abstract)

- 심층신경망은 학습시키기 더욱 어렵다.
- "residual learning framework"로 이전과 달리 상당히 깊은 신경망의 training을 쉽게하는 방법을 소개하고자 한다.
unreferenced함수 대신 layer input을 참조해 "learning residual function"으로 layer를 명시적으로 재구성하였다.
이런 잔차신경망(residual network)이 최적화하기 더욱 쉽고 상당히 증가된 깊이에서 정확도를 얻을 수 있다는 것을 보여주는 포괄적인(comprehensive) 경험적 증거를 제공한다.
- ImageNet dataset에서 VGGNet보다 8배 더 깊지만 복잡성은 낮은 152층의 잔차신경망에 대해 평가한다.
이런 잔차신경망의 앙상블은 ImageNet testset에서 3.57%의 오류를 달성했는데, 이는 ILSVRC-2015에서 1위를 차지했다.
또한 100층과 1000층을 갖는 CIFAR-10에 대한 분석도 제시한다.

- 깊이에 대한 표현은 많은 시각적인지작업에서 매우 중요하다.
우리의 매우깊은묘사는 COCO Object Detection dataset에서 상대적으로 28% 향상된 결과를 얻었다.
심층잔차신경망(Deep residual net)은 ILSVRC. &. COCO 2015 대회1에 제출한 자료의 기반으로 ImageNet감지, ImageNet Localization, COCO 감지, COCO segmentation 작업에서도 1위를 차지했다.

 

 

1. 서론 (Introduction)

Deep CNN은 image classification의 돌파구로 이어졌다.
심층신경망은 당연하게도 저·중·고수준의 특징을 통합하고, 분류기는 다층을 처음부터 끝까지 분류하며 feature의 "level"은 깊이가 깊어지면서 층이 쌓일수록 풍부해진다. (현재 신경망의 깊이는 아주 중요하다는 것이 정론이다.)

- Depth의 중요성에 대해 다음과 같은 질문이 발생한다: 더 많은 층을 쌓은 것 만큼 신경망을 학습시키기 더 쉬울까?
[
Is learning better networks as easy as stacking more layers?]
- 이 질문의 답을 위한 큰 장애물은 악명높은 gradient vanishing/exploding문제로 시작부터 수렴을 방해하는 것이다.
다만, 이 문제는 초기화를 정규화하거나 중간에 정규화층을 넣어 수십개(tens)의 층의 신경망이 역전파를 통해 SGD를 위한 수렴을 시작하는 방법과 같이 대부분 다뤄졌다.

Figure 1. Degradation Problem
[Degradation Problem]
- 더 깊은 신경망이 수렴을 시작할 때, 성능저하(degradation)문제가 노출되었다 : 신경망깊이가 증가하면 정확도가 포화상태가 되고, 그 다음에 빠르게 저하된다. 
- 이 문제의 예상치 못한 문제점은 바로 overfitting이 이 문제를 야기하지 않는다는 점인데, 적절한 심층모델에 더 많은 층을 추가하면 (우리의 연구결과처럼) 더 높은 training error가 발생한다.
위의 그림은 대표적인 예시이다.

- training 정확도의 성능저하는 모든 시스템이 optimize를 비슷한 수준으로 쉽게 할 수 없다는 것을 시사한다.
이를 위해 더 얕은 구조와 더 많은 층을 추가하는 더 깊은 구조를 고려해보자.

[Shallow Architecture. vs. Deeper Architecture]
더 깊은 모델에 대한 구성에 의한 해결책이 존재한다
 - 추가된 layer는 identity mapping이다.
 - 다른층은 학습된 얕은모델에서 복사된다.
이런 구조의 해결책심층모델이 얕은모델보다 더 높은 training error를 생성하지 않아야 함을 나타낸다.
하지만, 실험은 현재의 해결책은 이런구조의 해결책보다 비교적 좋거나 더 나은 해결책을 찾을 수 없었다.

cf. [Identity. &. Identity Mapping]
ResNet구조에서 Residual Block은 identity(= identity mapping) 을 말한다.
- 입력에서 출력으로의 전체 매핑을 학습하는 대신 입력을 약간 조정하는 방법을 학습을 진행한다.
- Identity Block은 Skip Connection이 Identity mapping을 수행하는 residual block의 일종이다.
- 즉, 변환없이 입력이 block의 출력에 직접 추가되는 것으로 Identity Block은 input의 차원을 유지시킨다.
- Identity Block은 Residual Networks에서 입력의 차원을 유지하면서 비선형성을 도입하는 데 사용된다.
이는 신경망이 더 복잡한 특징을 학습하도록 돕고 매우 깊은 신경망에서 발생할 수 있는 기울기 소실 문제를 방지한다.

이 논문에서, Degradation Problem을 "deep residual learning framework"를 이용해 다룰 것이다.
- 각 몇 개의 적층(stacked layer)이 원하는 기본적 맵핑에 직접 맞추기(fit)를 바라는 대신, 이러한 layer가 잔차맵핑에 적합하도록 명시적으로 허용한다.


- 우린 성능저하문제(Degradation Problem)를 보여주고 우리의 해결법을 평가하기 위해 ImageNet으로 포괄적인 실험을 진행하여 다음 2가지를 확인하였다.
 ① 극도로 깊은 잔차신경망은 최적화 하기 쉽다.
   - 단순히 층만 쌓는 상대적으로 "평범한(plain)" 신경망깊이가 증가하면 더 높은 training error를 보여준다.
 ② 우리의 심층잔차신경망은 깊이가 크게 증가하여 정확도를 쉽게 높였다.
이는 optimization의 어려움과 우리의 방법의 효과가 특정 dataset와 유사하지 않음을 시사한다.


- ImageNet Classification dataset에서 우리는 극도로 심층적인 잔차신경망에의해 우수한 결과를 얻었다.
우리의 "152-layer residual net"은 ImageNet에 제출된 가장 깊은 신경망이지만 VGG보다도 복잡성이 낮다.
앙상블은 ImageNet testset에서 3.57%의 top-5 error를 기록했으며 ILSVRC 2015 classification대회에서 1위를 차지했다.
극도로 깊은신경망은 서로다른 인식작업에서도 우수한 일반화(generalization)성능을 발휘해 다음같은 ILSVRC 및 COCO 2015에서 1위를 추가로 달성했다 : ImageNet detection, ImageNet localization, COCO detection, and COCO segmentation in ILSVRC & COCO 2015 competitions

 

 

 

 

2. Related Work

Residual Representations.
- image recognition에서, VLAD(Vector of Locally Aggregated Descriptors)는 dictionary에 관하여 잔차벡터에 의해 encoding되는 표현이며, Fisher Vector는 VLAD의 확률론적인 버전의 공식으로 만들어진다.
두가지 모두 image 회복 및 분류를 위한 강력한 shallow representation이다.
Vector 양자화(quantization)의 경우, 잔차벡터의 인코딩이 기존벡터 인코딩보다 더 효과적으로 나타났다.

cf) VLAD는 feature encoding을 위한 이미지처리기술로 Local Image feature를 고정길이벡터표현(fixed-length vector representation)으로 인코딩하는 것이다.
ResNet을 사용하는 일부과제에서 VLAD는 분류를 위해 최종 softmax층을 사용하는 대신, ResNet의 중간층에서 추출한 특징을 인코딩하는데 사용하여 더욱 세분화된 특징표현이 가능하다.

- 저수준의 비전에서 편미분방정식(PDE.,Partial Differential Equations)을 해결하기 위해 널리 사용되는 Mulit-Grid방법은 시스템을 여러척도(multiple scale)에서 하위문제(subproblem)로 재구성(reformulate)한다. 이때, 각 하위문제는 더 거친 척도와 미세한 척도사이에서 잔차해결(residual solution)을 담당한다.
Multi-Grid의 대안은 계층적 기본 딕셔너리의 조건화(hierarchical basis pre-conditioning)이다.
이는 두 척도 사이의 잔차벡터를 나타내는 변수에 의존하며 이런 해결법은 해결책의 잔차특성(residual nature)을 모르는 기존의 해결책보다 훨씬 빠르게 수렴하는 것으로 나타났으며 이런 방법은 좋은 재구성(reformulation)이나 전제조건(preconditioning)이 최적화를 단순화 한다는 것을 시사한다.



Shorcut Connections
- Shorcut Connection을 유도하는 이론 및 실습은 오래 연구해왔다.
MLP training의 초기실습은 신경망 입력에서 출력으로 연결된 선형층(linear layer)를 추가하는 것이다.
몇몇의 중간층이 gradient vanishing/exploding을 다루기 위해 보조분류기(auxiliary classifier)에 "직접연결"된다.
GoogLeNet(https://chan4im.tistory.com/149)에서, "Inception"층은 shortcut 분기와 몇개의 더 깊은 분기로 구성된다.

- 우리의 연구가 진행될 때 동시에, "highway networks"는 gating function이 있는 shortcut연결을 제시하였다.
이 gate는 parameter가 없는 identity shortcut과 달리 data에 의존하고 parameter를 갖고 있다.
gate shortcut이 "closed"(= 0에 접근할 수록) "hightway networks"의 layer는 non-residual function을 나타낸다.
 대조적으로, 우리의 공식은 항상 잔차함수를 학습한다.
우리의 identity shortcut은 결코 "closed"되지 않고 학습해야할 추가 잔차함수와 모든 정보가 항상 통과한다.
게다가 highway network는 깊이가 극도로 증가(100개 이상의 층)하여도 정확도의 향상을 보여주지 않았다.

 

 

 

3. Deep Residual Learning

3.1. Residual Learning

 

 

3.2. Identity Mapping by Shortcuts

 

 

3.3. Network Architectures

Plain Network
  - plain 신경망의 토대는 주로 VGGNet의 철학에서 영감을 받았다. (Fig.3, 왼쪽)
  - conv.layer는 대부분 3x3 filter를 사용하며, 2가지의 간단한 설계방식을 따른다.
    ① 동일한 크기의 특징맵출력에 대하 layer는 동일한 수의 filter를 갖는다.
    ② 특징맵 크기가 1/2(절반으로 줄)이면, layer당 시간복잡성을 유지해야 하기에 filter수가 2배가 된다.
  - 우린 stride=2인 conv.layer에 의해 직접 downsampling을 수행한다. 
  - 신경망은 Global AveragePooling과 Softmax가 있는 1000-way Fully-Connected로 종료된다.
  - weight-layer의 총 개수는 그림3의 중간과 같은 34개이다.

 Residual Network
  - 위의 plain신경망을 기반으로, 우리는 신경망을 counterpart residual 버전으로 바꾸는 Shortcut Connection(그림 3, 오른쪽)을 삽입한다.
  - Identity shortcuts(Eqn. (1))은 입력과 출력이 동일한 치수일 때 직접 사용할 수 있다(그림 3의 실선 shortcuts).

  - 차수가 증가하면(그림 3의 점선 shortcuts), 우리는 두 가지 옵션을 고려한다:
    ① shortcut은 차원을 늘리기 위해 추가적으로 0개의 항목이 패딩된 상태에서 Identity mapping을 계속 수행합니다.
        이때, 추가적인 매개 변수를 도입하지 않습니다;

    ② Eqn. (2)의 Projection shortcut은 차원을 일치시키는 데 사용된다(1×1 convolutions로 수행).

  - 두 옵션 모두에서 shortcut은 두 가지 크기의 특징맵 통과 시, stride=2로 수행된다.


 

 

3.4. Implementation

- [AlexNet, VGGNet]의 실험을 따라서 구현을 진행하였다. [https://chan4im.tistory.com/145, https://chan4im.tistory.com/146]
- scale augmentation[VGGNet]을 위해 [256, 480]로 random하게 샘플링, resize를 진행하였다.
- 224x224 crop은 랜덤하게 image에서 샘플링되거나 [AlexNet]처럼 픽셀 당 평균값의 차를 이용한 horizontal flip을 진행하였으며 정석적인 color augmentation은 [Alexnet]방식을 이용했다.

- Batch Normalization을 채택하여 BN논문[https://chan4im.tistory.com/147]에서 나온 것 처럼 Conv.layer 직후, activation이전에 사용을 해주었다.
- ReLU논문[https://chan4im.tistory.com/150]에서 처럼 weight를 초기화하고 모든 기본/잔차신경망을 처음부터 training한다.

- mini-batch size가 256인 SGD(weight decay=0.0001. &. momentum=0.9)를 사용하며, learning rate는 초기값이 0.1로 시작해 학습정체현상 즉, error plateaus(
SGD는 Plateau에 취약함)가 발생하면 10씩 학습률을 나누어 준다.
모델은 최대 60 x 10^4 iteration으로 training된다.
- [Batch Normalization]논문에 근거하여 Dropout은 배제하고 실험을 진행한다.


- 실험시, 비교분석을 위해 standard 10-crop testing을 채택하며[AlexNet], 최상의 결과를 위해 [VGG, Delving Deep into Rectifiers]논문처럼 Fully-Convolutional형태를 채택한다.
또한, 여러 척도에서의 score를 평균(average)하는데, 이때 image의 크기는 짧은쪽이 {224, 256, 384, 480, 640}에 오도록 조정된다.

 

 

 

4. Experiments

4.1. ImageNet Classification


 Plain Networks.
  - 먼저 18층, 34층 plain신경망을 평가한다. [34-layer plain net (Fig.3.중간), 자세한 구조는 아래 표1을 참조.]




 - 표 2의 결과는 더 깊은 34-layer plain net이 더 얕은 18-layer plain net보다 더 높은 val_Error값을 갖음을 보인다.

이유를 밝히기 위해 그림 4(왼쪽)에서 training과정 중 발생한 training/validation error를 비교한다
위 그림에서 우리는 성능저하문제(Degradation Problem)을 발견했다.
18-layer plain net의 solution space가 34-layer plain net을 대체함에도 불구하고 34-layer plain net은 전체적인 training절차에 걸쳐 높은 training error를 갖는다.


- 우린 이런 최적화 어려움이 gradient vanishing으로 인한 가능성은 낮다고 주장한다.
이런 plain신경망은 순전파신호가 0이 아닌 분산값을 갖도록 보장하는 Batch Normalization으로 훈련된다.
우린 또한 역전파된 기울기가 BN과 함께 healthy norm을 나타내는 것을 확인했다.
그래서 순전파와 역전파의 신호들이 사라지지 않는다.
(실제로 34-layer plain net은 표 3에서 보이듯 여전히 경쟁력있는 정확도를 달성하기에 solver가 어느정도 작동하는 것을 보여준다.)
우린 deep plain신경망이 기하급수적으로 낮은 수렴률을 가질  수 있어서 training error감소에 영향을 미친다고 추측한다.





 Residual Networks.
다음으로 18 및 34-layer residual nets (ResNets)을 평가한다.
근간이 되는 구조는 위의 plain신경망과 동일하며 그림 3(우측)처럼 3x3 filter의 각 쌍에 shortcut connection을 추가한다.
첫 비교(표2와 그림4,오른쪽)에선 모든 Shortcut에 identity mapping을 사용하고 차수를 늘리기 위해 zero-padding을 하기에 [option A], plain에 비해 추가적인 parameter가 없다.

[표 2와 그림 4에서 얻은 3가지 주요 관찰결과]
① 먼저, 잔차학습으로 상황이 역전된다.
  - 34-layer ResNet은 18-layer ResNet보다 2.8%낫다.
  - 더 중요한 점은, 34-layer ResNet이 상당히 낮은 training error를 나타내기에 validation dataset으로 generalization, 즉 일반화가 가능하다는 점인데, 이는 성능저하문제가 이 설정에서 잘 해결되었기에 깊이증가를 이용해 정확성의 이득을 얻을 수 있다는 점을 시사한다.

② 둘째로, plain신경망과 비교해 34-layer ResNet은 표 2처럼 top-1 error rate를 3.5% 감소시키며 성공적으로 감소된 training error를 보여준다. (그림 4에서 오른쪽  vs. 왼쪽)
이 비교는 극도로 심층적인 신경망에 대한 잔차학습의 효과를 검증해준다.

③ 마지막으로, 18-layer plain/ResNet이 비교적 정확하지만 (표 2), 18-layer ResNet은 더 빨리 수렴한다는 것에 주목하자.(그림 4에서 오른쪽  vs. 왼쪽)
  - 여기서 18-layer처럼 신경망이 "지나치게 깊지 않은" 경우, 현재의 SGD solver는 여전히 plain신경망에 대해 좋은 해결책을 찾는다.
  - 이 경우, ResNet은 초기단계에서 더 빠른 수렴을 제공해 최적화를 완화해준다.




Identity. vs. Projection Shortcuts.
  - parameter가 없는 identity shorcut은 training에 도움이 된다는 것을 보여주었으므로 다음으로는 projection shortcut(Eqn. (2))에 대해 조사한다.
표 3에서는 3가지 옵션을 비교한다.
(A) zero-padding shortcut은 차수를 늘리기 위해 사용된다.
  - 이때, 모든 shortcut은 parameter가 없다(표 2 및 그림 4의 오른쪽)

(B) projection shortcut은 차수를 늘리기 위해 사용된다.
  - 이때, 다른 shortcut은 identity이다.

(C) 모든 shortcut은 projection이다.

- 표 3은 3가지 옵션 모두 plain보다 낫다는 것을 보여준다. 이때, B가 A보다 약간 더 낫고 C가 B보다 약간 낫다. (C > B > A)
우린 이에 대해 A의 zero-padding차원이 실제로 잔차학습을 갖지 않기 때문이며 (B > A인 이유)
13개의 많은 projection shortcut에 의해 도입된 추가적 매개변수 때문이라 본다. (C > B인 이유)
그러나 A/B/C사이 작은 차이는 성능저하문제해결을 위해 Projection Shortcut이 필수적이지는 않다는 것을 시사한다.
메모리/시간복잡성과 모델크기를 줄이기 위해 이 논문의 나머지 파트에서는 C를 사용하지 않는다.
identity shortcut은 아래에 소개된 Residual Architecture의 복잡성을 증가시키지 않기에 더욱 중요하다.




 Deeper Bottleneck Architectures.

 [50-layer ResNet]
  - 우리는 34-layer net
의 각 2층 block3-layer bottleneck block으로 대체하여 50-layer ResNet(표 1)을 생성한다.
  - 우리는 차수를 늘리기 위해 option B를 사용한다.
  - 이 모델에는 38억 개의 FLOPS가 있습니다.


 [101-layer ResNet. &. 152-layer ResNet]
  - 우리는 더 많은 3-layer blocks(표 1)을 사용하여 101층 및 152층 ResNets를 구성한다.
  - 놀랍게도 깊이가 크게 증가했지만 152층 ResNet(113억 FLOP)은 여전히 VGG-16/19(153억/196억 FLOP)보다 복잡성이 낮다.
  - 50/101/152-layer ResNets는 34-layer보다 상당히 정확하다(표 3 및 4). 
  - 우리는 성능저하를 관찰하지 않기에 상당히 증가된 깊이에서 상당한 정확도 향상을 이뤘다.
  - 깊이의 이점은 모든 평가 지표(evaluation metric)에서 확인할 수 있다(표 3 및 4).


cf. FLOPs
컴퓨터의 성능을 수치로 나타낼 때 주로 사용되는 단위이다. 초당 부동소수점 연산이라는 의미로 컴퓨터가 1초동안 수행할 수 있는 부동소수점 연산의 횟수를 기준으로 삼는다.







Comparision with  State-of-the-art  Method.
  - 표 4에서 이전의 최고의 단일 모델 결과와 비교하였는데, 우리의 근-본 34층 ResNets는 매우 경쟁력 있는 정확도를 달성했다.
  - 152층 ResNet은 단일 모델에서 top-5 error rate에서 4.49%를 갖는다.
  - 이 단일 모델 결과는 이전까지의 모든 앙상블 결과를 능가한다 (표 5).


  - 깊이가 다른 6개의 모델을 결합하여 앙상블을 형성하였는데, testset에서 top-5 error가 3.57% 였다(표 5).
  (제출 당시, 앙상블 기법은 152층 모델 두 개만 포함하였으며
ILSVRC 2015에서 1위를 차지했다.)

 

 

4.2. CIFAR-10  and  Analysis

- 우리는 10개의 클래스에서 5만개의 traininset과 1만개의 test image로 구성된 CIFAR-10 dataset에 대해 더 많은 연구를 수행했다.
우리는 training set에 대해 훈련되고 testset에 대해 평가된 실험을 결과로 제시한다.
우리는 극도로 심층적인 신경망의 동작에 초점을 맞춘다.
최첨단 결과를 추진하는 것에는 초점을 맞추지 않기에 다음과 같이 단순한 구조를 의도적으로 사용한다.


- plain/residual architecture는 그림 3(가운데/오른쪽)의 형태를 따른다.
신경망의 입력은 픽셀당 평균의 차(per-pixel mean subtracted)의 32x32 이미지이다.
첫 번째 층은 3×3 convolution이며
그 후 크기가 각각 {32, 16, 8}인 특징맵에서 3×3 convolution을 가진 6n layers의 적층 후 각 특징맵 크기에 대해 2n layer를 사용한다. 이때, filter수는 각각 {16, 32, 64}개이다.
sub-sampling은 stride=2인 convolution에 의해 수행된다.

신경망은 Global AveragePooling, 10-way FC.layer 및 softmax로 종료되며 총 6n+2개의 적층된 weight 층이 있다.
다음 표는 Architecture를 요약한 것이다:
Shortcut Connection 사용시, 한 쌍의 3x3 layer(총 3n개의 shortcut)에 연결된다.
이 dataset에서 (option A을 포함한)모든 경우에 identity shortcut을 사용한다.
따라서 Residual Model은  Plain Model과 depth, width. &. parameter수가 정확하게 동일하다.



- weight decay=0.0001과 momentum=0.9을 사용하고 가중치 초기화 및 Batch Normalization을 사용하지만 Dropout은 사용하지 않는다. (이때, 가중치 초기화는 https://chan4im.tistory.com/150를 따른다.)
이 모델들은 2개의 GPU에서 128의 mini-batch로 훈련된다.
learning rate=0.1의 학습 속도로 시작해 32000과 48000 iteration에서 10으로 나눈다.
64000번의 iteration에서 45k/5k로 나뉜 train/validation의 값이 결정되기에 training을 종료한다.

training을 위해 [Supervised Net.,https://arxiv.org/abs/1409.5185]에 소개된 간단한 Data Augmentation을 따른다.
각 면에 4개의 pixel이 padding되며
32x32 crop은 padding된 이미지 혹은 horizontal flip 중 무작위로 샘플링된다.
test를 위해 원본 32x32 이미지의 single view만 평가합니다.




- 20, 32, 44 및 56 층 신경망으로 이어지는 n = {3, 5, 7, 9}을 비교한다.
그림 6(왼쪽)은 Plain 신경망의 작동을 보여준다.
깊은 Plain 신경망은 깊이가 증가하면서 어려움을 겪고, 더 깊이 들어갈 때 더 높은 train error를 보인다.
이런 현상은 ImageNet(그림 4, 왼쪽) 및 MNIST([42] 참조)에서의 현상과 유사하여 이러한 최적화의 어려움이 근본적인 문제임을 시사한다.


그림 6(가운데)은 ResNets의 동작을 보여준다.
또한 ImageNet 사례(그림 4, 오른쪽)와 유사하게 ResNets는 최적화 어려움을 극복하고 깊이가 증가할 때 정확도가 향상됨을 보여준다.



- 110층 ResNet으로 이어지는 n = 18을 추가로 탐구한다.
이 경우, 우리는 초기의 learning rate=0.1이 "수렴을 시작하기"에 약간 너무 크다는 것을 발견했다.
따라서 training error가 80%미만이 될 때까지 낮은 학습률인 0.01로 사전 training을 진행한 후(약 400 iteration) 0.1로 다시training을 계속한다.
나머지 training schedule은 이전과 동일하며, 이 110층 신경망은 잘 수렴된다(그림 6, 중간).
FitNet[https://arxiv.org/abs/1412.6550] 및 Highway[https://arxiv.org/abs/1505.00387](표 6)와 같은 깊고 및 얇은 신경망보다 parameter수가 적지만, 최첨단 결과(6.43%, 표 6) 중 하나를 얻었다.


 Analysis of Layer Response.
  - 그림 7은 layer response의 표준 편차(std)를 보여준다.
이때, response는 BN 이후 및 기타 비선형성(ReLU/추가) 이전의 각 3x3 layer의 출력이다.
ResNets의 경우, 이 분석은 잔차 함수의 response강도를 나타낸다.

- 그림 7은 ResNet이 일반적인 응답보다 일반적으로 더 작은 응답을 가지고 있음을 보여준다.
이런 결과는 잔차 함수가 비잔차 함수보다 일반적으로 0에 가까울 수 있다는 기본 가정(3.1절)을 뒷받침한다.

- 또한 그림 7의 ResNet-20, 56 및 110의 비교에서 입증된 바와 같이 더 깊은 ResNet이 응답의 크기가 더 작다는 것을 주목하자.
즉, 더 많은 층이 있을 때, ResNets의 각각의 층은 신호를 덜 수정하는 경향이 있다.



 Exploring Over 1000 layers.
  - 공격적으로 1000개 이상의 층을 쌓는 깊은 모델을 탐구한다.
위에서처럼 훈련된 1202층 신경망으로 이어지는 n = 200을 설정한다.
우리의 방법은 최적화 어려움을 보이지 않고, 이 103층 신경망은 training error < 0.1%를 달성할 수 있다(그림 6, 오른쪽).
test error는 여전히 상당히 양호합니다(7.93%, 표 6).


- 그러나 그러한 공격적 심층모델은 여전히 미해결 문제가 있다.
이 1202층 신경망 test 결과는 우리의 110층 신경망 결과보다 나쁘지만, 둘 다 비슷한 training error를 갖는다.
우린 이런 현상이 "Overfitting"때문이라 주장한다.

- 1202층 신경망은  작은 dataset에 대해서는 불필요하게 클 수 있다(19.4M).
이 dataset에서 최상의 결과를 얻기 위해 maxout / dropout 같은 강력한 정규화가 적용된다.

본 논문에서는, 최적화의 어려움에 초점을 맞추지 않기에 maxout/dropout을 사용하지 않는다. 
설계에 따라 깊고 얇은 구조를 통해 정규화를 적용하지만 더 강력한 정규화와 결합하면 결과가 개선될 수 있다.

 

 

4.3. Object Detection on  PASCAL  and  MS COCO

- 우리의 방법은 다른 인식과제에서도 일반화 성능이 좋다.
- 표 7과 8은 PASCAL VOC 2007과 2012 [5] 및 COCO에 대한 Object Detection의 기준결과를 보여준다.
- 우리는 Detection방법은 Faster R-CNN을 사용한다.
이때, VGG-16을 ResNet-101로 대체하는 개선 사항에 관심을 두고 주목한다.
두 모델을 사용하는 Detection의 구현(부록 참조)은 동일., 결과물은 더 나은 신경망에 귀속된다.

- 가장 주목할 만한 것은 까다로운 COCO dataset에서 COCO의 표준 metric인 (mAP@[.5, .95])이 6.0% 증가하여 28%의 상대적 개선을 얻었는데, 이는 오직 learned representation 때문이다.

- 심층 ResNet을 기반으로 ILSVRC 및 COCO 2015 대회에서 여러 트랙에서 1위를 차지했습니다:
ImageNet Detection, ImageNet Localization, COCO Detection 및 COCO Segmentation.

- 자세한 내용은 부록에 기재.

 

 

 

 

 

😶 부록 (Appendix)

A. Object Detection. Baselines

• PASCAL VOC
  -
• MS COCO
  -

 

B. Object Detection Improvements

• MS COCO
  -

• PASCAL VOC
  -

• ImageNet Detection
  - 

 

C. ImageNet Localization

  -

  -

 

 

 

 

 

🧐 논문 감상_중요개념 핵심 요약

"Deep Residual Learning for Image Recognition"
심층 신경망에서 gradient vanishing problem을 해결하는 심층 ConvNet을 위한 새로운 구조를 소개하는 연구 논문으로 이 논문은 ResNet이라는 심층 합성곱 신경망을 위한 새로운 아키텍처를 제안한다.

 

 

[핵심 개념]

1. Problem
- 이 논문은 네트워크 깊이가 증가함에 따라 신경망의 정확도가 포화되거나 저하될 수 있는 기울기 소실 문제로 인해 매우 깊은 신경망을 훈련하는 것이 어렵다는 점을 강조했다.
  [Degradation Problem]
 - 더 깊은 신경망이 수렴을 시작할 때, 신경망깊이가 증가하면 정확도가 포화상태가 되고, 그 다음에 빠르게 저하된다. 
 - 이 문제의 예상치 못한 문제점은 바로 overfitting이 이 문제를 야기하지 않는다는 점인데, 적절한 심층모델에 더 많은 층을 추가하면 더 높은 training error가 발생한다.

2. Solution
이 논문은 기본 맵핑을 직접 학습하는 대신 잔차 함수(residual functions)를 학습하는 잔차 학습(residual learning)이라는 새로운 접근 방식을 제안했다.
이 접근 방식은 신경망이 identity mapping을 학습할 수 있도록 skip connection을 사용하는 residual block을 통해 구현된다.

cf. [Identity. &. Identity Mapping]
ResNet구조에서 Residual Block은 identity(= identity mapping) 을 말한다.
- 입력에서 출력으로의 전체 매핑을 학습하는 대신 입력을 약간 조정하는 방법을 학습을 진행한다.
- Identity Block은 Skip Connection이 Identity mapping을 수행하는 residual block의 일종이다.
- 즉, 변환없이 입력이 block의 출력에 직접 추가되는 것으로 Identity Block은 input의 차원을 유지시킨다.
Identity Block은 Residual Networks에서 입력의 차원을 유지하면서 비선형성을 도입하는 데 사용된다.
이는 신경망이 더 복잡한 특징을 학습하도록 돕고 매우 깊은 신경망에서 발생할 수 있는 기울기 소실 문제를 방지한다.

[Shortcut Connection]
- skip connection이라고도 불린다.
- 층의 입력과 이후 층의 출력 사이에 추가함으로써 ResNet은 층을 우회하고 입력을 이후 계층으로 "직접 전달"할 수 있습니다.
- 이를 통해 네트워크는 잔차 함수를 학습할 수 있으므로 매우 깊은 신경망의 훈련이 가능하다.
- 또한 여러 conv.layer와 기존의 입력을 블록의 출력에 추가하여 신경망이 identity mapping을 학습할 수 있게 해준다.
이를 통해 training의 정확성 및 속도를 향상시킬 수 있다.

[Residual learning]
이 논문은 원하는 기본 매핑을 직접 학습하는 대신 레이어 입력을 참조하여 잔차 함수를 학습하는 잔차 학습의 개념을 도입했다.
이 접근 방식은 gradient vanishing을 피할 수 있어서 심층신경망훈련을 허용한다.

[Residual blocks]
ResNet은 여러 conv.layer와 기존의 입력을 블록의 출력에 추가하는 skip connection으로 구성된 잔차 블록(residual block)을 사용하여 구축된다.
이를 통해 신경망은 잔차 함수를 학습할 수 있으므로 매우 깊은 신경망의 훈련이 가능합니다.



3. Bottleneck Architecture
- ResNet 구조는 매우 깊은 잔여 블록 스택(예: 152개 층)으로 구성되며 정확도를 유지하면서 계산을 줄이는 bottleneck설계를 사용한다.
- 논문에서는 세 개의 층으로 구성된 병목 구조를 소개했으며 이 세 층을 Add를 이용해 더한다.
① channel수를 줄이기 위한 1x1 conv.layer
② feature 학습을 위한 3x3 conv.layer
③ channel수를 다시 늘리기 위한 또 다른 1x1 conv.layer


cf. Pre-activation
이 논문을 응용한 ResNetV2는 사전 활성화(pre-activation)에 대한 개념을  도입했다.
 - BatchNormalization 및 ReLU를 각 conv.layer 이후가 아닌 이전에 적용한다.
 - 이를 통해 training performance를 개선하고 매우 깊은 신경망에서의 overfitting을 줄여주었다.



5. Results
- ResNet은 훨씬 더 깊은 신경망으로 이전 방법을 능가해 ImageNet dataset의 classification작업에서 최첨단 성능을 달성했다.
- 또한 ResNet은 Objcet Detection 및 Semantic Segmentation과 같은 다양한 dataset 및 작업에서 더 나은 일반화 성능(generalization performance)을 달성했다.

- 이때, 초기의 learning rate=0.1이 "수렴을 시작하기"에 약간 너무 크다는 것을 발견하였기에
 training error가 80%미만이 될 때까지 낮은 학습률인 0.01로 사전 training을 진행한 후(약 400 iteration) 0.1로 다시training을 진행하였다.

전반적으로 ResNet 논문은 딥러닝과 특히 컴퓨터 비전 영역에서 많은 최신 모델의 핵심 구성 요소가 된 매우 깊은 ConvNet의 훈련을 가능하게 하는 새로운 구조를 제안하는 혁신적인 성과를 이룩하였다.

 

 

 

 

 

🧐  논문을 읽고 Architecture 생성 (with tensorflow)

import tensorflow as tf
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, GlobalAveragePooling2D, Dense, ReLU, BatchNormalization, ZeroPadding2D, Activation, Add

def conv_bn_relu(x, filters, kernel_size, strides=1, padding='same'):
    x = Conv2D(filters, kernel_size, strides=strides, padding=padding)(x)
    x = BatchNormalization()(x)
    x = ReLU()(x)
    return x

def identity_block(x, filters):
    shortcut = x
    x = conv_bn_relu(x, filters, 1)
    x = conv_bn_relu(x, filters, 3)
    x = conv_bn_relu(x, filters * 4, 1)
    x = Add()([x, shortcut])
    x = ReLU()(x)
    return x

def projection_block(x, filters, strides):
    shortcut = conv_bn_relu(x, filters * 4, 1, strides)
    x = conv_bn_relu(x, filters, 1, strides)
    x = conv_bn_relu(x, filters, 3)
    x = conv_bn_relu(x, filters * 4, 1)
    x = Add()([x, shortcut])
    x = ReLU()(x)
    return x

def resnet(input_shape, num_classes, num_layers):
    if num_layers == 50:
        num_blocks = [3, 4, 6, 3]   
    elif num_layers == 101:
        num_blocks = [3, 4, 23, 3]   
    elif num_layers == 152:
        num_blocks = [3, 8, 36, 3]

    conv2_x, conv3_x, conv4_x, conv5_x = num_blocks

    inputs = Input(shape=input_shape)
    x = ZeroPadding2D(padding=(3, 3))(inputs)
    x = conv_bn_relu(x, 64, 7, strides=2)
    x = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(x)

    x = projection_block(x, 64, strides=1)
    for _ in range(conv2_x - 1):
        x = identity_block(x, 64)

    x = projection_block(x, 128, strides=2)
    for _ in range(conv3_x - 1):
        x = identity_block(x, 128)

    x = projection_block(x, 256, strides=2)
    for _ in range(conv4_x - 1):
        x = identity_block(x, 256)

    x = projection_block(x, 512, strides=2)
    for _ in range(conv5_x - 1):
        x = identity_block(x, 512)

    x = GlobalAveragePooling2D()(x)
    outputs = Dense(num_classes, activation='softmax')(x)

    model = tf.keras.Model(inputs, outputs)
    return model




model = resnet(input_shape=(224,224,3),  num_classes=200, num_layers=152)
model.summary()

 

Model: "ResNet152"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to                     
==================================================================================================
 input_24 (InputLayer)          [(None, 224, 224, 3  0           []                               
                                )]                                                                
                                                                                                  
 zero_padding2d_10 (ZeroPadding  (None, 230, 230, 3)  0          ['input_24[0][0]']               
 2D)                                                                                              
                                                                                                  
 conv2d_4159 (Conv2D)           (None, 115, 115, 64  9472        ['zero_padding2d_10[0][0]']      
                                )                                                                 
                                                                                                  
 batch_normalization_4158 (Batc  (None, 115, 115, 64  256        ['conv2d_4159[0][0]']            
 hNormalization)                )                                                                 
                                                                                                  
 re_lu_540 (ReLU)               (None, 115, 115, 64  0           ['batch_normalization_4158[0][0]'
                                )                                ]                                
                                                                                                  
 max_pooling2d_23 (MaxPooling2D  (None, 58, 58, 64)  0           ['re_lu_540[0][0]']              
 )                                                                                                
                                                                                                  
 conv2d_4161 (Conv2D)           (None, 58, 58, 64)   4160        ['max_pooling2d_23[0][0]']       
                                                                                                  
 batch_normalization_4160 (Batc  (None, 58, 58, 64)  256         ['conv2d_4161[0][0]']            
 hNormalization)                                                                                  
                                                                                                  
 re_lu_542 (ReLU)               (None, 58, 58, 64)   0           ['batch_normalization_4160[0][0]'
                                                                 ]                                
                                                                                                  
 conv2d_4162 (Conv2D)           (None, 58, 58, 64)   36928       ['re_lu_542[0][0]']              
                                                                                                  
 batch_normalization_4161 (Batc  (None, 58, 58, 64)  256         ['conv2d_4162[0][0]']            
 hNormalization)                                                                                  
                                                                                                  
 re_lu_543 (ReLU)               (None, 58, 58, 64)   0           ['batch_normalization_4161[0][0]'
                                                                 ]                                
                                                                                                  
 conv2d_4163 (Conv2D)           (None, 58, 58, 256)  16640       ['re_lu_543[0][0]']              
                                                                                                  
 conv2d_4160 (Conv2D)           (None, 58, 58, 256)  16640       ['max_pooling2d_23[0][0]']       
                                                                                                  
 batch_normalization_4162 (Batc  (None, 58, 58, 256)  1024       ['conv2d_4163[0][0]']            
 hNormalization)                                                                                  
                                                                                                  
 batch_normalization_4159 (Batc  (None, 58, 58, 256)  1024       ['conv2d_4160[0][0]']            
 hNormalization)                                                                                  
                                                                                                  
 re_lu_544 (ReLU)               (None, 58, 58, 256)  0           ['batch_normalization_4162[0][0]'
                                                                 ]                                
                                                                                                  
 re_lu_541 (ReLU)               (None, 58, 58, 256)  0           ['batch_normalization_4159[0][0]'
                                                                 ]                                
                                                                                                  
 add_1150 (Add)                 (None, 58, 58, 256)  0           ['re_lu_544[0][0]',              
                                                                  're_lu_541[0][0]']              
                                                                                                  
 re_lu_545 (ReLU)               (None, 58, 58, 256)  0           ['add_1150[0][0]']               
                                                                                                  
 conv2d_4164 (Conv2D)           (None, 58, 58, 64)   16448       ['re_lu_545[0][0]']  



...


conv2d_4312 (Conv2D)           (None, 8, 8, 512)    2359808     ['re_lu_741[0][0]']              
                                                                                                  
 batch_normalization_4311 (Batc  (None, 8, 8, 512)   2048        ['conv2d_4312[0][0]']            
 hNormalization)                                                                                  
                                                                                                  
 re_lu_742 (ReLU)               (None, 8, 8, 512)    0           ['batch_normalization_4311[0][0]'
                                                                 ]                                
                                                                                                  
 conv2d_4313 (Conv2D)           (None, 8, 8, 2048)   1050624     ['re_lu_742[0][0]']              
                                                                                                  
 batch_normalization_4312 (Batc  (None, 8, 8, 2048)  8192        ['conv2d_4313[0][0]']            
 hNormalization)                                                                                  
                                                                                                  
 re_lu_743 (ReLU)               (None, 8, 8, 2048)   0           ['batch_normalization_4312[0][0]'
                                                                 ]                                
                                                                                                  
 add_1199 (Add)                 (None, 8, 8, 2048)   0           ['re_lu_743[0][0]',              
                                                                  're_lu_740[0][0]']              
                                                                                                  
 re_lu_744 (ReLU)               (None, 8, 8, 2048)   0           ['add_1199[0][0]']               
                                                                                                  
 global_average_pooling2d_6 (Gl  (None, 2048)        0           ['re_lu_744[0][0]']              
 obalAveragePooling2D)                                                                            
                                                                                                  
 dense_6 (Dense)                (None, 200)          409800      ['global_average_pooling2d_6[0][0
                                                                 ]']                              
                                                                                                  
==================================================================================================
Total params: 58,780,744
Trainable params: 58,629,320
Non-trainable params: 151,424
__________________________________________________________________________________________________

+ Recent posts