버전 만들기 / stage area에 대해 알아보기

|

버전 만들기 / stage area에 대해 알아보기

버전 만들기 (commit)

  • 의미있는 변화가 생기는 것을 버전(version)이라고 함.
  • 해당 작업이 완결된 상태만을 새로운 버전이라고 할 수 있음.
    • 단순 코드 수정은 새로운 버전으로 볼 수 없음
  • 해당 디렉터리의 코드가 자신의 것임을 알려주기 위해 이름 및 메일주소를 정의
    • git config --global user.name myname
    • git config --global user.email mymail@mail.com
  • git commit 을 쳐서 자신의 정보가 제대로 등록되었는지 확인
    • committer에 자신의 정보(이름, 메일)가 등록되어있는것 확인 가능
  • 밑에는 commit message를 적을 수 있음.
    • 주석 처리 된 부분을 제외한 부분에 메세지를 적어야 함.
  • git log는 누가, 언제, 무슨 내용(커밋 메세지)을 만들었는지에 대한 정보를 출력
  • 다음 버전을 작성 하려면, git 관리 대상으로 등록된 파일을 수정
  • 수정 된 파일을 git status로 확인 시 해당 파일이 붉은색으로 modified상태로 뜸
  • 다음에 git add filename로 다시 git에서 그 파일을 다시 등록해줘야 함.
    • 즉, git에 버전 관리를 시작 할때나(새 파일 생성) 새 버전을 생성할때도 git add filename 를 또 해줘야함.
    • git add filename 없이 그냥 git commit 시 커밋 불가
    • Commit 후 커밋 메세지 작성할 수 있는 창이 뜸.
  • git log를 치면 방금 커밋한 버전을 확인 할 수 있음.
  • 커널에서는 vim이 사용이 편하므로, 만약 nano 에디터로 실행 될 경우 git config --global core.editor “vim” 을 한 번만 쳐 주면 해결된다.

Stage area (중요!)

  • git은 commit전에 add를 꼭 해야 함
    • 그 이유는 선택적으로 파일을 버전에 포함시키기 위해서임.
  • f1.txt 파일과 동일한 f2.txt 파일을 생성.
    • cp f1.txt f2.txt
  • git status로 파일의 상태를 확인하면 새로 생성된 f2.txt 파일이 tracked되지 않는다 뜸
    • git add f2.txt로 새로 생성된 파일을 트랙하도록 설정
  • git commit 후 커밋 메세지 작성(version 3), 저장
  • git log로 커밋 된 결과를 확인하면 성공적으로 커밋 된 것을 확인 할 수 있음
  • 다음으로 f1.txtf2.txt 의 내용을 모두 다 수정
  • 이 상태에서 git status로 상태를 확인하면 두 파일이 modified 상태인것을 확인 할 수 있음
  • 여기서! git add f1.txtf1.txt파일만 트래킹 하도록 설정한 후, git status로 상태를 확인하면 f1.txt 파일만 초록색에 커밋 가능한 상태로 뜸
  • f2.txt는 커밋이 되지 않을것이라고 뜨며 하며 빨간색 modified 상태
  • 즉, git add filename로 트래킹을 할 수 있도록 등록 한 파일만 커밋이 되기 때문에 선택적으로 파일을 커밋 할 수 있음.
  • 이 상태에서 git commit으로 커밋 시 커밋 메세지를 작성 할 수 있고, 작성을 완료 하고 git log로 로그 내용을 살펴보면 f1.txt파일만 새로운 커밋 메세지로 변경사항이 반영 된 것을 알 수 있음.
  • git add filename를 하지 않은 f2.txt 파일은 git status로 상태 확인 시 커밋 되지 않은것을 알 수 있음.
  • 즉, git add filename를 해줘야 commit 대기 상태로 들어가 커밋이 가능하게 되는것임. 커밋 대기상태가 아니면 커밋 불가능.
  • 이렇게 git add filename로 커밋 가능 상태로 만들어주는것을 변경 파일을 ‘stage’에 올리는 것이고, stage에 존재하는 파일만 커밋 가능.
  • 정리하자면,
    • Stage: 커밋 대기 상태 파일들이 가는곳
    • Repository는 커밋 된 파일들이 존재하는곳

Github 공부 시작 / 설치 및 환경 만들기

|

Github 공부 시작/설치 및 환경 만들기

  • 평소에 github를 다루긴 하지만 제대로 공부해서 다루진 않았다.
  • 보통은 사용하는 명령어들만 사용해서 별로 불편함을 느끼진 못했다.
    • git clone address 라던가 git submodule update —init —recursive같은..
  • 코드가 복잡해질수록 버전관리의 필요성을 느끼게 된다.
  • 따라서 생활코딩의 ‘지옥에서 온 git’이라는 강좌로 공부를 시작해보려 한다.
    • (https://opentutorials.org/course/2708/15242)

설치 방법

  • sudo apt-get install git으로 설치 가능
  • 설치 후 커맨드라인에 git이라고 친 후 git 관련 명령어가 뜨면 설치 된 상태

프로젝트 환경 만들기

  • mkdir folder_name: 폴더 생성
  • cd folder_name: 해당 폴더로 이동
  • git init: 해당 디렉터리를 git의 저장소로 만듦
    • 해당 디렉터리에서 작업을 진행하겠다는것을 git에 알려주는 역할
  • 완료 시 .git폴더가 생성 됨
    • 안에는 버전 관련 정보들이 담겨있게 됨

git이 관리할 대상으로 파일 등록

  • 관리 할 파일에 대해서 git add filename 으로 git이 파일을 추적하도록 명령함
  • git status로 프로젝트 폴더의 상태를 확인 할 수 있음
    • 앞으로 해당 파일의 버전이 관리가 됨

190111 백준 알고리즘 문제풀기

|

Baekjoon 알고리즘 문제풀기

[2292] 벌집

문제

views
  • 위의 그림에서 입력으로 주어진 숫자까지 가는 최단거리를 출력하는 프로그램을 작성
  • 예시
    • 13 입력 시 3
    • 58 입력 시 5
  • 점화식을 세워서 풀었다.
    • 육각형의 4시방향 숫자는 1, 7, 19, … 이므로, $a_{n+1}=6\times(n-1)+a_{n}$ 의 관계를 보인다.
    • 계차수열 $b_{n}$은 $b_{n}=a_{n+1}-a_{n}=6n$ 으로 정의된다.
    • 따라서,
      • $a_{n}=a_{1}+\sum_{k=1}^{n-1}b_{k}=1+\sum_{k=1}^{n-1}6k$
      • $a_{n}=1+6\sum^{n-1}_{k=1}k = 1+6\frac{(n-1)\times n}{2}$
      • $a_{n} = 1+3(n-1)\times n$
      • ∴ $a_{n}= 3n^{2}-3n+1$
  • 이를 이용하여 풀이를 하면 아래와 같다.

정답

num = int(input())

def find_num(n):
    cnt = 0
    if n==1:
        return 0
    else:
        while True:
            cnt += 1
            r_p = 3*pow(cnt,2)-3*cnt+1
            r_n = 3*pow(cnt+1,2)-3*(cnt+1)+1
            if n>r_p and n<=r_n:
                return cnt
cnt = find_num(num)
print(cnt + 1)

190110 백준 알고리즘 문제풀기

|

Baekjoon 알고리즘 문제풀기

[11654] 아스키 코드

문제

  • 입력받은 문자를 아스키코드표의 10진수 형태로 출력

  • ord(chr(문자))는 문자 하나를 입력받아 아스키코드표의 10진수 형태로 출력해준다.
  • 반대로 chr(ascii number)를 입력하면 숫자를 문자로 변환해준다.

정답

char = input()
print(ord(str(char)))

[10809] 알파벳 찾기

문제

  • 단어가 입력된 경우, 단어에 포함된 알파벳이 위치하는 index를 출력하고, 단어에 포함되지 않은 알파벳의 경우엔 -1을 출력한다.

  • 더 간단하게 푸는 방법이 있을 듯 한데.. 너무 복잡하게 풀어낸 것 같다.

정답

a = str(input())

alphabets = []
result = []
for j in range(26):
    alphabets.append(chr(97+j))
    result.append('-1')

for j in range(len(a)):
    for i in range(len(alphabets)):
        if alphabets[i]==a[j]:
            if result[i]=='-1':
                result[i] = str(j)
for j in range(len(result)):
    print(result[j], '',end='')
print('')

[2675] 문자열 반복

문제

  • 입력 된 테스트 케이스만큼의 각 문자 반복 횟수와 문자열을 받고, 반복횟수만큼 문자열 각 자리를 반복해서 출력

정답

a = int(input())

for j in range(a):
    n, k = map(str, input().split())
    #print(n, k)
    for i in range(len(k)):
        for p in range(int(n)):
            print(k[i], end='')
    print('')

[1157] 단어 공부

문제

  • 알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성
  • 대문자와 소문자를 구분하지 않음

  • ord(chr)를 사용하여 아스키 코드로의 변환 후 32 증감으로(ascii index) 대소문자 변환을 함
  • list.count(member)를 이용하여 해당 리스트에 해당 member가 존재하는지 갯수 확인
  • max(list)를 사용하여 해당 리스트의 최댓값을 확인

정답

a = list(str(input()))

for j in range(len(a)):
    if ord(a[j])<91:
        a[j] = chr(ord(a[j])+32)
a = sorted(a)
alphabets = sorted(set(a))
result = []
for j in range(len(alphabets)):
    result.append(a.count(alphabets[j]))
if len(result)==1:
    print(chr(ord(alphabets[0])-32))
elif result.count(max(result))>1:
    print('?')
else:
    print(chr(ord(alphabets[result.index(max(result))])-32))

[1316] 그룹 단어 체커

문제

  • N개의 단어에 존재하는 모든 문자에 대해서, 각 문자가 연속해서 나타나는 경우만을 찾는 프로그램을 제작
  • 예시
    • ccazzzzbb는 c, a, z, b가 모두 연속해서 나타나므로 그룹 단어
    • kin kin도 k, i, n이 연속해서 나타나므로 그룹 단어
    • aabbbccb는 b가 떨어져서 나타나기 때문에 그룹 단어가 아님
  • string.find(chr)chr문자를 string의 왼쪽에서부터 찾은 후, index를 반환한다.
  • string.rfind(chr)chr문자를 string의 오른쪽에서부터 찾은 후, index를 반환한.

정답

def find_group(l):
    temp = []
    s = ''
    result = []
    for j in range(len(l)): # 입력 된 list를 string형태로 변환
        s += l[j]
    for j in range(len(s)): # 변환 된 string에 왼쪽부터 loop를 돌며
        l = s.find(s[j])    # l: 해당 문자(string의 j번째 문자)가 가장 왼쪽에서 나오는 순번
        r = s.rfind(s[j])   # r: 해당 문자(string의 j번째 문자)가 가장 오른쪽에서 나오는 순번
        temp = []           # temp 변수 초기화
        for i in range(l, r+1): # string에서 l부터 r 사이에
            temp.append(s[i])   # 존재하는 문자들을 temp에 이어 붙인 후
        if temp.count(s[l])==len(temp): # 만약 l과 r 사이에 s[l](최 좌측 문자)과 동일한 문자만 들어있다면
            result.append(True) # 그룹 문자이므로 True
        else:   # 그렇지 않다면
            result.append(False)    # 그룹 문자가 아니므로 False
                                    # for loop을 돌면서 문자별로 전체 단어에 대해서 수행
    if False in result: # 만약 하나의 False만 존재하더라도 그룹 문자가 아니므로 counting되면 안됨
        return 0
    else:   # False가 하나도 없다면 그룹 문자이므로 counting 되도록 1 return
        return 1

n = int(input())
cnt = 0
for j in range(n):
    a = list(str(input()))
    if len(set(a))==len(a): # 입력된 단어가 모두 다른 문자로 구성된 경우
        cnt += 1 # 그룹 단어
    else: # 그렇지 못한 경우
        cnt += find_group(a) # 그룹 단어인지 판별 후 그룹 단어로 카운팅
print(cnt)

[2908] 상수

문제

  • 두 수를 입력받고, 입력 받은 두 수를 각각 거꾸로 읽은 후 대소를 비교하여 큰 수를 출력
  • 예시
    • 734과 893을 입력 받았을 때, 수를 437과 398로 거꾸로 인식한 후 대소를 비교하여 두 수중 큰 수인 437을 출력한다.

정답

a, b = map(str, input().split())

a_r = ''
b_r = ''

for j in range(len(a)-1, -1, -1):
    a_r += a[j]
for j in range(len(b)-1, -1, -1):
    b_r += b[j]
if int(a_r)>int(b_r):
    print(a_r)
else:
    print(b_r)

[5622] 다이얼

문제

  • 입력된 문자열을 조건에 따라 숫자로 변환 한 후, 주어진 조건에 따른 다이얼 누르는 시간을 계산하여 출력
  • 조건
    • 1~9, 0의 숫자는 각각 전화기의 숫자배열대로 나뉘어짐
    • 입력은 대문자로 이루어진 영어단어
    • 단어의 각 문자에 알맞는 숫자로 변환 후 1~0 순서로 구성된 전화 다이얼 누르는 시간을 계산
    • 각각 1은 2초, …. 0은 11초가 걸림

정답

a = list(str(input()))
numbers = []
for j in range(len(a)):
    b = ord(a[j])
    if b>ord('Z'):
        numbers.append(0)
    elif b>ord('V'):
        numbers.append(9)
    elif b>ord('S'):
        numbers.append(8)
    elif b>ord('O'):
        numbers.append(7)
    elif b>ord('L'):
        numbers.append(6)
    elif b>ord('I'):
        numbers.append(5)
    elif b>ord('F'):
        numbers.append(4)
    elif b>ord('C'):
        numbers.append(3)
    elif b>64:
        numbers.append(2)
    else:
        numbers.append(1)
result = 0
for j in range(len(numbers)):
    if numbers[j]==0:
        result += 11
    else:
        result += (int(numbers[j])+1)
print(result)

[2941] 크로아티아 알파벳

문제

  • 아래의 문자표를 보고, 문자열을 크로아티아 문자열로 변경 후 크로아티아 문자의 갯수를 센다.
views
  • 상당한 노가다성 문제이다.
  • 중간에 길이가 3짜리인 문자가 있어서 IndexError때문에 try:, except IndexError:continue를 사용하여 해결하였다.
  • 리스트 내의 빈 칸을 제거하는 list = [x for x in list if x]로 문제를 쉽게 풀 수 있었다.

정답 1

 a = list(str(input()))
for j in range(len(a)-1):
    if a[j]=='c':
        if a[j+1]=='=':
            a[j] = 'c='
            a[j+1] = ''
            j += 1
        elif a[j+1]=='-':
            a[j] = 'c-'
            a[j+1] = ''
            j += 1
    elif a[j]=='d':
        try:
            if a[j+1]=='-':
                a[j] = 'd-'
                a[j+1] = ''
                j += 1
            if a[j+1]=='z' and a[j+2]=='=':
                a[j] = 'dz='
                a[j+1] = ''
                a[j+2] = ''
                j += 2
        except IndexError:
            continue
    elif a[j]=='l' and a[j+1]=='j':
        a[j] = 'lj'
        a[j+1] = ''
        j += 1
    elif a[j]=='n' and a[j+1]=='j':
        a[j] = 'nj'
        a[j+1] = ''
        j += 1
    elif a[j]=='s' and a[j+1]=='=':
        a[j] = 's='
        a[j+1] = ''
        j += 1
    elif a[j]=='z' and a[j+1]=='=':
        a[j] = 'z='
        a[j+1] = ''
        j += 1
    else:
        continue
a = [x for x in a if x]
print(len(a))
  • 미리 크로아티아 문자를 정의하는 dictionary를 만들어 더 쉽게 풀 수 있다.

정답 2

a = input() # string 형식으로 입력을 받고
dics = ["c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z="] # 크로아티아 문자가 저장된 dictionary 안에서
for key in dics:   # 각 key 값에 대해(c= 부터 차례대로 z=까지)
    a = a.replace(key, "_") # key값과 동일한 문자를 _로 대체
print(len(a)) # 결과 출

MobileNetV2- Inverted Residuals and Linear Bottlenecks

|

MobileNetV2: Inverted Residuals and Linear Bottlenecks

Original paper: https://arxiv.org/abs/1801.04381

Authors: Mark Sandler, Andrew Howard, Menglong Zhu, Andrey Zhmoginov, Liang-Chieh Chen (Google Inc.)

Introduction

  • Neural Network(NN)의 정확도를 향상시키는 것은 컴퓨터의 연산량에 직결적으로 연결된 문제(성능이 좋을수록 더 많은 연산량 요구)
  • 대부분의 NN은 제한된 성능에서 FLOPs와 같은 indirect metric computation complexity를 고려
    • Direct metric computation complexity: Memory access cost, platform 특성에 의존하는 속도
  • 본 논문에서는, FLOPs를 떠나 direct metric을 평가해 효율적인 네트워크 구축을 위한 구조를 제안(ShuffleNet V2)
    • 메모리 연산에 효율적인 Inverted Residual Block을 제안
  • Inverted Residual Block
    • Input으로 low-dimensional compressed representation을 받아 high-dimension으로 확장시킨 후, depthwise convolution을 수행
    • 이렇게 나온 feature를 다시 linear-convolution을 통해 low-dimensional 정보로 만듦.
  • 이러한 Module(Inverted Residual Block) 덕분에 Memory 사용량이 줄어, mobile design에 최적화 됨

Depthwise Separable Convolution

  • 일반적인 convolution 연산의 경우, 3개의 채널에 대해 3x3의 공간방향의 convolution을 수행 시 1개의 채널이 생성 됨.
views
Standard convolution
  • Depthwise separable convolution의 경우, 일반적인 convolution 연산과 달리 공간/채널(깊이)을 따로 연산
    • 채널별로 convolution 연산 후, 이를 1x1 convolution 연산으로 채널 간(깊이 방향) 연산을 수행
views
Depthwise separable convolution / 공간 방향의 convolution
views
Depthwise separable convolution / 채널(깊이) 방향의 convolution
  • 두 연산방법간의 연산량 차이는 아래와 같음.
    • Input: $h_{i}\times w_{i}\times d_{i}$ 크기의 Tensor
    • Output: $h_{i}\times w_{i}\times d_{j}$ 크기의 Feature map
    • Kernel size: $k\times k$
    • Sandard convolution의 연산량: $h_{i}\times w_{i}\times d_{i}\times d_{j}\times k\times k$
    • Depthwise separable convolution의 연산량: $h_{i}\times w_{i}\times d_{i}\times (k^{2}+d_{j})$
    • 즉, Standard convolution에 비해 $\frac{1}{d_j}+\frac{1}{k^2}$배 만큼의 연산량 감소 효과가 있음.
    • $3\times 3$컨벌루션 연산 시 약 8~9배 가량의 연산량 감소 효과

Linear Bottleneck

  • 각 layer에서 focusing하는 feature들은 조금씩 다름.
  • Conv 연산으로 feature map에 담긴 정보를 전체 채널을 따져 고려하면, 결국 중요한 정보는 몇 몇 manifold에 존재.
    • 이것을 다시 low-dimensional sub-space로 만들 수 있음.
  • 즉, feature map에 존재하는 모든 값들이 의미있는 정보를 나타내지 않고, 의미있는 정보를 나타내는 값은 특정 부분에 몰려있거나 전체에 여러 영역에 걸쳐 나타날 수 있다는 것을 의미.

  • MobileNet V1에선 이런 manifold를 low-dimensional sup-space로 만듦
    • MobileNet V1의 Width-multiplier를 이용해 채널을 조정하는 것
  • 이러한 방법으로 어떤 manifold of interest 부분이 entire space가 될 때까지 차원을 축소 시킬 수 있음
    • 의미있는 정보와 의미 없는 정보가 담긴 정보량들에 대해, 의미없는 정보를 버리고 의미있는 정보만이 남도록 정보가 존재하는 차원을 줄이고, 이로 인해 메모리의 효율성이 좋아지는것을 의미
  • 하지만, 차원을 줄이는 과정(Sub-space로 엠베딩 시키는 과정)에서 쓰이는 ReLU와 같은 비선형 함수에 의해 문제가 발생
    • 만약 ReLU를 지난 출력이 S인 경우, S가 non-zero라면, S에 맵핑 된 input의 각 값은 선형변환 된 것.
    • 하지만, 0 이하의 값은 버려져 정보의 손실이 발생하게 됨.(쓸모있는 정보가 손실 됨)
      • 즉, 입력되는 채널의 정보를 activation space에 전부 담지 못하는 현상이 발생됨
    • 이를 방지하고자 channel reduction이 아닌 channel expansion을 이용
    • 채널을 확장시키는 경우, 채널의 깊이가 깊어져 low-dimensional sub-space로 embed해도 비선형 변환(ReLU)에 의한 정보의 손실이 적어짐.

    • 또한, 연산량을 줄이기 위해 1x1 convolution로 과도하게 압축하다보니 여기에서도 정보손실이 발생
    • 1x1xL을 convolution filter의 개수, M을 linear transform W의 열(row) 개수라고 할 때,
      • M<L: 출력값이 필터보다 작은 channel pooling의 경우 정보손실 발생
      • M>=L: 출력값이 필터보다 크거나 같은 channel expansion의 경우에는 정보가 보존됨
    • 하지만 M<L인 경우 입력 X의 manifold 차원수가 충분히 작으면 (X가 sparse) M<L의 1x1 conv 필터를 갖고도 X의 정보를 보존 할 수 있다.
  1. Manifold of interest 부분이 ReLU(비선형 변환)를 거친 후에도 Non-zero volume를 갖는다면, linear transformation에 해당
    • Linear transformation은 정보손실이 없다.
    • 즉, 차원수가 충분히 큰 space에서 ReLU를 사용하면 정보가 손실될 가능성이 크게 줄어든다.
  2. Input manifold가 input의 low-dimensional sub-space에 놓여있다면, ReLU가 input manifold에 대해 완전한 정보의 보호가 가능해짐
  • 만약 Manifold of interest가 low-dimension이라 가정하면, convolution block에 linear bottleneck layer를 삽입해 이를 capture 할 수 있게 됨.
    • ReLU(비선형 변환)의 정보의 손실을 방지할 수 있음

Inverted Residuals

views
(a) Residual block (b) Inverted residual block
  • Resudual block과 비슷하나, 반대의 구조를 띔
    • Resnet의 Residual block은 bottleneck 이후 채널을 축소시키지만, 본 논문에서 제시하는 Inverted Residual Block은 bottleneck 이후 채널을 확장시킴
  • Bottleneck이 필요한 정보를 모두 갖고있고, expansion layer는 tensor의 비선형 변형과 같은 역할만 하기에 bottleneck 사이를 연결하는 구조로 사용됨.
  • Residual block은 채널이 큰 특징맵끼리 연결되어 있으나, Inverted Residual Block은 bottleneck 끼리 연결
  • Shortcut 연결은 Resnet처럼 gradient 전파를 효율적으로 하기 위함임.
  • Inverted 구조는 메모리 사용측면에서 효율적

Inverted Residual Block Structure

views
Inverted Residual Block basic structure
  • 기본적인 구조는 위와 같음.
    • t: Channel expansion parameter
    • ReLU6 사용. Mobile 환경에서는 ReLU6가 더 연산/메모리측면에서 효율적이라고 사용한다던데…
  • 연산량의 차이
    • Input size: $h\times w\times d’$, kernel size: $k$, output channel: $d’’$
    • Bottleneck convolution
      • $h\times w\times d’\times t\times (d’+k^{2}+d’’)$
      • $=(k\times w\times d’\times t\times d’)+{ h\times w\times d’\times t\times (k^{2}+d’’)}$
      • $(k\times w\times d’\times t\times d’)$: Reduction
      • ${ h\times w\times d’\times t\times (k^{2}+d’’)}$: Expansion (DW convolution)
      • 실제 연산량은 extra term에 의해 더 많아보이나, 실제로는 오히려 적음
views
MobileNet V2, ShuffleNet 과의 연산량 비교
  • MobileNet V2와 ShuffleNet간의 연산량을 비교할 때, MobileNet V2의 연산량이 더 적음을 알 수 있음

정리

  • Real Image를 input으로 받았을 때 네트워크의 어떤 레이어들을 Manifold of interest라고 한다면, input manifold를 충분히 담지 못하는 space에서 ReLU를 수행하면 정보의 손실이 발생한다.
  • 하지만 차원수가 충분히 큰 space에서 ReLU를 사용하면 정보가 손실될 가능성이 크게 줄어든다.
  • 저차원 데이터에 conv 층을 적용하면 많은 정보를 추출 할 수 없다.
  • 따라서 더 많은 데이터를 추출하기 위해 저차원의 압축된 데이터를 압축을 먼저 풀거(차원 확장) conv 층을 적용시킨 다음 projection층을 통해 데이터를 다시 압축시키는 과정을 거친다.
  • 위의 일련이 과정이 바로 Inverted Residual Block이 하는 일이다.
  • 마지막 ReLU 함수를 지나기 전에 Channel expansion을 해서 input manifold를 충분히 큰 space에 담아 놓고, ReLU를 적용시킴으로써 정보 손실을 최소화한다. 여기서 더 나아가서 Linear Bottleneck을 마지막에 두지 말고 앞으로 가져와 Expansion -> Projection 구조 + Shortcut connection을 사용한다.

Memory efficiency inference

  • Inverted Residual block의 bottleneck layer은 memory를 효율적으로 사용 할 수 있게 해줌
  • Memory의 효율적 사용 문제는 Mobile application에서 매우 중요함

Experiment

views
  • Parameter의 수, 연산량이 증가하나 정확도가 크게 개선되는 것을 확인 할 수 있음
views
  • SSD Lite는 SSD의 prediction layer를 depthwise separable convolution으로 바꿔 파라미터의 수/연산량을 획기적으로 줄인 구조
    • Model size가 작아짐
views
  • 정확도 측면에서 기존 방법에 비해 competitive한 결과를 보이나, 파라미터의 수/연산량 비교시 훨씬 효율적인 모델임을 알 수 있음

Conclusion

  • Linear bottleneck, Inverted residual block을 이용해 MobileNet V1을 개선함.
  • SSD Lite의 경우, YOLO V2보다 연산량, 파라미터의 수를 획기적으로 줄임.
    • 매우 효율적인 구조
  • 논문에서 제안한 convolution block을 exploring 하는것이 향후 연구의 중요한 방향이 될 것임.

  • [참고 글]

Sandler, Mark, et al. “Mobilenetv2: Inverted residuals and linear bottlenecks.” 2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition. IEEE, 2018.

http://eremo2002.tistory.com/48

http://hugrypiggykim.com/2018/11/17/mobilenet-v2-inverted-residuals-and-linear-bottlenecks/

https://medium.com/@sunwoopark/slow-paper-mobilenetv2-inverted-residuals-and-linear-bottlenecks-6eacaa696b54