일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Pytorch Lecture
- c++
- object detection
- 영상처리
- 미디언 필터링
- pytorch
- TensorFlow
- 컴퓨터 비전
- 가우시안 필터링
- 모두의 딥러닝 예제
- c++공부
- 딥러닝
- 김성훈 교수님 PyTorch
- 파이토치 강의 정리
- 딥러닝 공부
- 딥러닝 스터디
- C언어 공부
- c언어
- pytorch zero to all
- 케라스 정리
- matlab 영상처리
- 해리스 코너 검출
- 팀프로젝트
- MFC 프로그래밍
- 파이토치
- 파이토치 김성훈 교수님 강의 정리
- tensorflow 예제
- 골빈해커
- 모두의 딥러닝
- c언어 정리
Archives
- Today
- Total
ComputerVision Jack
Aggregated Residual Transformations for Deep Neural Networks 본문
Reading Paper/Classification Networks
Aggregated Residual Transformations for Deep Neural Networks
JackYoon 2021. 12. 21. 09:55반응형
Aggregated Residual Transformations for Deep Neural Networks
Abstract
- 논문에서 소개하는 Network는 같은
Topology
에 대해 변형 시킨 Building Block 반복하여 설계하였다. 이 설계는 적은 Hyper-Parameter 통해서 동종의 Multi-Branch한 구조의 결과로 나타났다. - 앞에서 소개한 전략은 "Cardinality" (the size of the set of transformations) 새로운
Dimension
생성한다. 이 Dimension은 Depth와 Width Dimension 외에도 필수적인 요소이다. - 게다가
Capacity
위해 Network 깊고, 넓게 만드는 것 보다, Cardinality 증가 시키는 것이 더 효율적이다. 따라서 해당 Model = ResNeXt
Introduction
- 많은 Layer단이 존재할 수록 Hyper-Parameter 수가 증가하기 때문에, Network Architecture 설계하기에 어렵다.
- VGG-nets :
Stacking Building Blocks
이러한 규칙은 특정 데이터에 Hyper-Parameter가 과도하게 설정되는 것을 줄여 준다. - Inception :
Spit Transform Merge
해당 접근은 많은 Layer에 대한 Features 고려할 수 있지만, 연산 복잡성이 높다. - 해당 논문에서 VGG/ResNets의
repeating layers
전략을 채택하는 반면split-transform-merge
전략을 사용하여 쉽게 확장 가능한 구조를 제안한다. - Network의 Module은Low-Dimensional Embedding에서 변환을 수행하며, 출력은 덧셈으로 나오게 된다. 이 변환은 모든 같은 Topology 통합할 수 있다.
- 저자들은 Transformation 통합 방식이 기존 ResNet Module 보다 성능이 뛰어나며, 연산적 측면이나 모델 크기 면에서도 이점이 있음을 증명했다.
- 해당 방식은 Cardinarity 지칭하며, width 또는 depth 보다 중요하다. ResNeXt
Methods
Template
- 저자들은 VGG/ResNets의 Module 설계를 채택하면서, Networks는 Residual Block 쌓아서 구성하였다. 이 Block들은 같은 Topology 갖는다. 또한 VGG/ResNets 영감을 받아 간단한 2 개의 규칙들을 따르게 된다.
ⅰ 만약 같은 크기의 Spatial-map
생성한다면 같은 Hyper-Parameter(width and filter size) 갖는다.
ⅱ stride=2
인해 Spatial-map이 Downsample 된다면 Blocks의 Width 또한 Stride=2 연산을 진행한다.
- 두 번째 규칙은
FLOPs
관점에서 모든 Blocks는 같은 연산 복잡도를 갖는다. - 이러한 규칙들을 통해 Network 좁게 설계할 수 있으며 Key Factors에 집중할 수 있게 만든다.
Revisiting Simple Neurons
- Neural Networks의 간단한 뉴런은
inner product
수행되며, Fully-Connected와 Convolution의 기본 변환으로 수행된다. - 해당 연산은
splitting
,transforming
,aggregating
결합되어 진행된다.
ⅰSplitting : vector x 는 Low-Dimensional Embedding 나눠지며, 그림에서 subspace xi는 단일 Dimension 정의된다.
ⅱTransforming : Low-Dimensional Feature은 간단한 연산을 통해 변형된다. 해당 그림에서 w'*x
ⅲ Aggregating : 모든 Embedding 단계에서 변형된 값들을 취합한다. ∑
Aggregated Transformations
- 저자는 Elementary Transformation에 대해 Network에서도 사용할 수 있는 일반적인 함수로 변경할 수 있다고 생각하였다. Depth의 Dimension이 증가하는 "Network-in-Network와 대조적으로 "Network-in-Neuron"은 새로운 Dimension 확장을 가져온다.
$F(x) = ∑T_i(x)$
- Eqn(2)에 대해
C
는 통합되기 위한 Transformation 집합의 수가 된다. 즉Cardinarity
이다. Cardinarity
의 Dimension은 Transformation의 수를 관리할 수 있으며,Width
와Depth
의 Dimension 보다 효과적이고 필수적이라는 것을 증명했다.- Inception 및 Inception-ResNet Module과 달리 Multiple Path에 대해 같은 Topology 공유한다. 저자의 Module은 약간의 노력으로 각 Path들을 생성할 수 있다.
- Block의
Depth ≥ 3
때만 Topology에 대해 생산할 수 있다고 알린다. 만약 BlockDepth = 2
라면 Dense Module 같이 넓게 가져가면 된다.
Model Capacity
- ResNeXt는 Model의 연산과 Parameter 수를 유지하면서 정확도를 향상 시켰다. 이러한 과정은 실용적일 뿐만 아니라 중요하다. 왜냐하면 Model은 계층 구조에 따라 Parameter 갖기 때문에 이 진행은 Deep Network의 지표가 되기 때문이다.
- 따라서 Hyper-Parameter 최소화 하려고 노력하였다. 적정한
Width
찾고 그에 따른Cardinarity
찾았다. 그렇지 않으면 Input과 Ouput이 고립되는 현상이 발생할 수 있다.
import torch
from torch import nn
class ResNeXtStem(nn.Module):
def __init__(self, in_channels, out_channels):
super(ResNeXtStem, self).__init__()
self.conv = Conv2dBnAct(in_channels=in_channels, out_channels=out_channels, kernel_size=7, stride=2)
self.max_pool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
def forward(self, input):
output = self.conv(input)
output = self.max_pool(output)
return output
class ResNeXt_Block(nn.Module):
def __init__(self, in_channels, kernel_size, out_channels, stride=1, cardinarity=32):
super(ResNeXt_Block, self).__init__()
self.cardinarity = cardinarity
self.out_channels = out_channels
self.res_conv1 = Conv2dBnAct(in_channels=in_channels, out_channels=in_channels, kernel_size=1, stride=1)
self.group_conv = Conv2dBnAct(in_channels=in_channels, out_channels=in_channels, kernel_size=kernel_size, stride=1, dilation=1, groups=self.cardinarity)
self.res_conv2 = Conv2dBnAct(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=stride)
self.identity = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=stride)
def forward(self, input):
output = self.res_conv1(input)
output = self.group_conv(output)
output = self.res_conv2(output)
if input.size() != output.size():
input = self.identity(input)
output = input + output
return output
def get_channel(self):
return self.out_channels
class _ResNeXt50(nn.Module):
def __init__(self, in_channels, classes):
super(_ResNeXt50, self).__init__()
self.resnextStem = ResNeXtStem(in_channels=in_channels, out_channels=64)
# config in_channels, kernel_size, out_channels, stride, Cardinarity, iter_cnt
conv2_x = [128, 3, 256, 1, 3]
conv3_x = [256, 3, 512, 2, 4]
conv4_x = [512, 3, 1024, 2, 6]
conv5_x = [1024, 3, 2048, 2, 3]
self.layer1 = self.make_layer(conv2_x, 64)
self.layer2 = self.make_layer(conv3_x, 256)
self.layer3 = self.make_layer(conv4_x, 512)
self.layer4 = self.make_layer(conv5_x, 1024)
self.classification = nn.Sequential(
Conv2dBnAct(in_channels=2048, out_channels=1280, kernel_size=1),
nn.AdaptiveAvgPool2d(1),
nn.Conv2d(1280, classes, 1)
)
def forward(self, input):
stem= self.resnextStem(input)
s1 = self.layer1(stem)
s2 = self.layer2(s1)
s3 = self.layer3(s2)
s4 = self.layer4(s3)
pred = self.classification(s4)
b, c, _, _ = pred.size()
pred = pred.view(b, c)
return {'pred':pred}
def make_layer(self, cfg, pre_layer_ch):
layers = []
self.pre_ch = pre_layer_ch
input_ch = cfg[0]
for i in range(cfg[-1]):
if i == 0:
layer=ResNeXt_Block(in_channels=self.pre_ch, kernel_size=cfg[1], out_channels=cfg[2], stride=cfg[3])
else:
layer = ResNeXt_Block(in_channels=input_ch, kernel_size=cfg[1], out_channels=cfg[2])
layers.append(layer)
input_ch = layer.get_channel()
return nn.Sequential(*layers)
def ResNeXt(in_channels, classes=1000):
model = _ResNeXt50(in_channels=in_channels, classes=classes)
weight_initialize(model)
return model
if __name__ == '__main__':
model = ResNeXt(in_channels=3, classes=1000)
model(torch.rand(1, 3, 224, 224))
반응형
'Reading Paper > Classification Networks' 카테고리의 다른 글
Squuze-and-Excitation Networks (0) | 2021.12.28 |
---|---|
MobileNetV2: Inverted Residuals and Linear Bottlenecks (0) | 2021.12.24 |
Densely Connected Convolutional Networks (0) | 2021.12.23 |
MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications (0) | 2021.12.22 |
Deep Residual Learning for Image Recognition (0) | 2021.12.20 |
Comments