【Paper】 Mask R-CNN 논문리뷰 동영상 공부

Mask R-CNN 논문리뷰 동영상을 보고 정리한 내용입니다.

논문 이름 : Mask R-CNN
동영상 링크 : Mask R-CNN
아래에 이미지가 없다면, 이미지가 Loading 중 입니다. 잠시만 기다려주세요

Mask R-CNN

img img img img img img img img img img img img img img img img img img img img img img img img img img

FCN이 해야하는 역할은 아래의 3개와 같다.

  • 하지만 Faster RCNN이 이 대부분을 도와준다.

img img img img img img img img img img img

Mask-RCNN에서 Faster-RCNN을 제외한 Mask Branch (Mask Architecture)은 어떤 모양일지 공부해보자.

  • Equivariance : Input이미지 크기에 따라 유동적으로 Output의 크기가 정해진다. Convolution 연산처럼
  • Invariant : Input이미지 크기가 뭔지 모르겠고 Fully connected layer에 들어가기 전에, 딱 정해진 사이즈가 되어야 한다.
  • Instance Segmentation에서는 Equivariance한 연산이 있는게 좋겠다.

img img img

  • Mask-RCNN Branch의 모습은 아래의 2가지 같은 것이 될 수 있다. (64번 슬라이드 참조)

img img img img img img img img

Fast-RCNN에서 사용하는 ROI Pooling의 모양은 다음과 같다.

  • 반올림을 하는 과정에서 정보손실(?)이 이루어진다.
  • 걍 정수로 자르는 과정에서도 정보손실(?)이 이루어진다.

img img img img img

Mask-RCNN에서 사용하는 ROI Align Pooling은 다음과 같다.

  • 아래 예시에서는 ROI pooling을 거쳐 2 x 2 X depth(256) 이 만들어져야 한다면…으로 가정한다.
  • Fater-RCNN에서는 보통 7 x 7 x depth(256) 이 만들어져야 하므로, 위와 비슷하게만 생각하면 충분히 쉽게 이해할 수 있다.
  • PPT 자료에는 “4등분하고 또 4등분”이라고 표현했다. 하지만 만약, 7 * 7 이 최종이 되도록 ROI Pooling이 이뤄진다면, “49등분하고 또 4등분”이 될 것이다.
  • PPT 자료에는 이 짓(2번째 4등분에 대한 weighted sum)을 16번(4x4)이라고 했지만, 실제에서는 196번(49x4)이 되겠다.
  • 아래 내용 요약 : Input-EachROI. output-7x7(nxn) Pooled Feature. nxn등분->각4등분->Bilinear interpolation->각4등분에 대해 Max Pooling->(nxn) Pooled Feature Map 획득.
  • 순서 정리(꼭 이 사이트 그림 참조)
    1. n x n 이 최종이 되도록 하는 ROI pooling을 하고 싶다.
    2. n x n 등분하고(등분하고 나온) 하나의 부분을 Cell이라고 하자. Cell에 대해 또, 1/3 2/3 등분을 하여, 일단! 총 4개의 점을 찍는다.
    3. 4개의 점에 대해서 Weighted Sum을 수행한다. Weighted Sum을 n x n x 4 번 수행한다.
    4. Weighted Sum을 하는 방법은 Bilinear interpolation 공식을 적용한다. (P : 해당 Point의 픽셀 값)
      • img
    5. (Max Pooling) 4개의 점에 대해서 가장 큰 값을 골라서 n x n 하나의 Cell에 적용한다.
    6. n x n ROI Align pooling이 적용되었고, 이렇게 만들어진 n x n x depth(256) Feature Map을 Classfication & Box regression + Mask Branch에 넣는다.

img img img img img img img img img img img img img img img img img img

【Algorithm】 무지의 먹방 라이브 - 카카오문제

프로그래머스 무지의 먹방 라이브 문제 풀이

문제링크 : 무지의 먹방라이브

문제 설명과 최소값 지우기 방법으로 직접 해보기

image image

나의 고민 과정

  • Key point

    1. k초 직후 = 이미 k번 음식을 씹어 먹었다.
    2. 리스트 내부 최솟값 이용할 떄 처리 순서 :
    • 리스트 내부 원소 지우기
    • 나머지 모든 원소에 값 빼기
  • 질문

    1. index가 포함된 새로운 리스트를 만들 필요가 있을까?
    2. 튜플, 딕셔너리, set 무엇을 사용하는게 좋을까?
    3. list는 건들지 않고 k을 더하거나 뺴는 방법은 없을까?
    • 예를 들어, [3 2 2] —6초 직후–> [1 0 0]
      == [3 2 2]는 그대로 놔두고, k - 6 …??? 는 아닌것 같다.
      1. 최솟값 말고 다른 방법은 없을까?
    • 직접 해보면서 문제점을 찾아보자. –> 우선 나쁘지 않은 듯 하다.
      -> 이렇게 내가 컴퓨터다. 라는 마음으로 직접하면서 많이 배운다!!
    • 큐? 스택? 다이나믹? 정렬?
      1. 정렬을 이용하는 방법은 딕션? 튜플? 무엇을 이용하는게 좋을까?
    • 3번째 방법의 2번째 함수는 무조건 2000보다 작은 시간복잡도를 가지므로, 굳이 딕션이나 튜플을 이용하지 않아도 될 것같다.
    • 모든 수의 합을 구해, -1인지 아닌지를 가장 먼저 판별하는 행위는 2000의 시간복잡도를 가진다. 이것을 가장 앞에 추가하는게 과연 좋을까?
    • sort말고 len(food_times)의 시간복잡도를 가지는 방법이 없을까??
    • 굳이 sort하는 list를 또 만들어야 할까?? (공간 복잡도 최소화)
  • 해결방법(2번과 3번 이용)

    1. 정직하게 while문을 돌면서, 리스트의 원소들에 -1을 해가는 방법
    2. 리스크의 최솟값(가장 빨리 다 먹는 음식)을 찾는다=t
    • t * len(food_times)(=남은 음식 갯수) =< k 이면,
      • 최솟값을 찾는 행동 계속한다. reculsive하게…
    • else :
      • 최솟값을 찾는 행동 멈춘다.
    • 이 방법에는 Dictionary를 이용하는게 낫겠다.
    • 정확성 테스트 통과 but 효율성에서 시간 초과. 따라서 이 방법은 적절하지 않다.
      1. 정렬을 적극 이용하기 - 정렬만 최대 2000 * log(2000) = 2000 * 10 의 시간 복잡도.
    • 우선 food_times를 정렬한다.
    • 작은 수부터 k를 처리해 나간다.(처리하는 방법은 2번문제 해결법을 적극 이용한다)
    • k값의 연산은 하지만, 리스트 자체의 연산은 하지 않기 때문에 경과시간이 적을 듯 하다.

손코딩

2번째 해결방법을 이용한 풀이 (시간초과)

  • 2개의 함수를 만든다
    • Stop을 위한 함수
    • reculsive를 위한 함수 (최솟값을 찾는다)
  1. sum(food_times) =< k 이면, return -1
  2. food_times값을 value로 하여, 딕셔너리에 값을 채워 넣는다.
  3. while -> dick의 value 중 min값    VS    k 값 -> 크기 비교
    • if. min*원소갯수 =< k :
      • min인 원소 제거
      • 나머지 원소들의 value - min
      • k = k - min*원소갯수
    • else. min*원소갯수 > k :
      • (k % 원소갯수)의 그 다음 key 를 return

3번째 해결방법을 이용한 풀이 (통과!)

  • 2개의 함수를 만든다
    • cur_min, cur_pos 를 뽑아주는 함수
      • input : list, cur_pos, cur_min, n
      • cur_pos부터 cur_min보다 큰 수를 찾는다.
      • 큰 수를 찾았다면,return : cur_min 과 cur_pos
      • for 문을 돌아 n이 될 때까지, 보다 큰 수를 못찾았다면, cur_pos에 2001 return
    • cur_min보다 같거나 큰 수 중, (k)%n 번째 음식의 index를 찾아주는 함수.
      • input : food_times, (k)%n, cur_min
      • for 문을 돌면서, cur_min보다 같거나 큰 수가 나오면 (k)%n - 1을 한다.
      • -1을 하기 전에 (k)%n가 0이면, 그 때의 food_times의 index를 return한다.
  1. (-1을 return하는 경우가 필요한지는 실험을 통해 알아보자.)
  2. food_times를 sort한다.
  3. cur_min = list[0]; cur_pos = 0; n = len(food_times);
  4. while cur_min * n <= k :
    • diff라는 개념! food_times간의 차이 <- 실수해서 초반 오답 해결: 손코딩한거 직접 예제 돌려보자.
    • k, cur_min과 cur_pos를 갱신
    • cur_pos가 2001이면 -1 return하고 함수 종료
  5. 위의 while이 break되면, cur_min의 값보다 같거나 큰 수들 중, (k)%n 번쨰 음식을 찾는다.

코드

2번째 풀이 코드

def renew(m,dic,k) :
    # k값 갱신
    k = k - m*len(dic)
    keylist = []
    # dic 갱신
    for key, value in dic.items():
        if value == m :
            keylist.append(key)
        else :
            dic[key] = value - m
    for i in keylist:
        del(dic[i])

    return k

def solution(food_times, k):
    # 0
    if sum(food_times) <= k : return -1

    # 1
    dic  = {}
    for index, time in enumerate(food_times):
        dic[index+1] = time
    
    # 2
    while(1):
        m = min(dic.values())
        if m*len(dic) > k : break
        else : k = renew(m,dic,k)

    # 3
    answer = list(dic.keys())[k%len(dic)]
    return answer

if __name__ == "__main__":
    food_times = [3,1,2]
    k = 5
    print(solution(food_times,k))

3번째 풀이 코드

def cur_next(lis, cur_min, cur_pos, n, l):
    for i in range(cur_pos+1, l):
        if cur_min < lis[i]:
            return lis[i], i
    return -1 , l+1

def fine_index(food_times, m, cur_min) : 
    for index, Value in enumerate(food_times):
        if cur_min <= Value :
            if m == 0:
                return index+1
            else :
                m -= 1

def solution(food_times, k):
    # 1
    lis = food_times[:]
    lis.sort()
    # 2
    cur_min = lis[0]
    diff = cur_min
    cur_pos = 0 # list 0부터 시작
    n = len(lis) # 남은 음식 수
    l = n # 처음 음식의 총 갯수
    # 3
    while diff*n <= k:
        k = k - diff*n
        temp, cur_pos = cur_next(lis, cur_min, cur_pos, n, l)
        if temp == -1 : return -1 # k가 충분히 커, 음식을 다 먹었을 경우.
        diff = temp - cur_min
        cur_min = temp
        n = l - cur_pos
        
    # 4
    cur_min = lis[cur_pos]
    answer = fine_index(food_times, k%n, cur_min)
    return answer

if __name__ == "__main__":
    food_times = [3,1,2,2,3,2]
    k = 13
    print(solution(food_times,k))

【Git】 README.md 작성 위한 Markdown 사용법 정리

(Git) README.md 작성 위한 Markdown 사용법 정리

주의사항
꼭!! 원문으로 참고하기 : https://junha1125.tistory.com/57?category=834508

Reference

  • https://post.naver.com/viewer/postView.nhn?volumeNo=24627214
  • https://eungbean.github.io/2018/06/11/How-to-use-markdown/

1. /n

이전 문단의 마지막을 그냥 enter만 하는게 아니라,

Spacebar를 2번하고, enter를 처야한다.

하지만 한 단락 띄기는 enter를 2번처서 완전히 분리시키도록 한다.

2. 제목

# 헤더 크기 (h1)

## 헤더 크기 (h2 –> 여기까지만 큰글 + 얇은 밑줄)

### 헤더 크기 (h3)

#### 헤더 크기 (h4)

##### 헤더 크기 (h5)

###### 해더 크기 (h6)

3. 목록


*

*

*

-

-

-

-

+

+

+

+

\1.

\1.

\1.

\1.

\1.

1.

2.

3.

1.

\2.

4. 이미지

이미지 a명

5. 링크

링크가 들어갈 내용

6. 코드

```LangagueName

~~~~~~~~~~

~~~~~~~~~~

```

```sh

~~~~~

```

7. 인용

여러 층으로 사용 가능

>

>

>>

>>>

8. 글 서식

기울기: * 내용 *

굵은 글: ** 내용 ** , __ 내용 __

줄 긋기: ~~ 내용 ~~

9. 표

First HeaderSecond Header

———— | ————-

Content cell 1Content cell 2
Content column 1Content column 2
Header OneHeader TwoHeader ThreeHeader Four

| ———- | :——— | :———-: | ———-: |

DefaultLeftCenterRight
Column 1Column 2Column 3Column 4

| ——– | :——: | ——– | ——– |

No spanSpan across three columns  

표 내부에서 줄 바꿈은 <\br>을 직접 입력.

10. 체크 박스

- [x] this is a complete item

- [ ] this is an incomplete item

- [x]] mentions,

11. 인라인 코드

’ 내용 ‘

12. 수평선

-–



13. 마크다운 서식말고 문자 그대로 이용(Escape)

*

-

+

코딩할 때 처럼 앞에 \추가

14. 이모티콘

:rocket: :metal: :octocat:

추가 검색 : [http://emoji-cheat-sheet.com]

15. 배지

[https://shields.io]

16. 수학 수식

Tex 으로 검색해서 찾아서 사용하면 된다.

$ 수학적 수식(문장 사이에 적기 가능) $ \[수학적 수식( 무조건 가운데 정렬)\] \[x + y = z\]

17. Struct

ㅂ + 한자 를 사용해 찾을 수 있다.

```

├──

├──

├──

└──

```


적은 것 같지만 잘 사용하면 이것만으로 충분하고, 이게 전부이다.

더 필요한 내용은 추가적으로 직접 더 찾아서 공부하도록 하자.

Typora

하지만 typora에서도 더 많은 좋은 기능을 제공한다. typora도 추가적으로 공부해보도록 하자.


Visual studio code

마크다운을 활동하는 방법이 Typora도 있지만, Visual studio code를 활용하는 방법도 있다. ‘.md’ 파일을 만들고 ctrl+shift+v 를 눌러 previewer를 같이 띄어놓음으로써 마크다운을 쓰고 난 직후의 모습을 바로바로 확인할 수 있다. 아무리 그래도 VScode는 Typora보다는 실시간성이 떨어지지만 적절히 사용한다면 충분히 좋은 마크다운 편집기라고 할 수 있다.

【Git】 Git Blog 만들기 순서

(Git) git blog 만들기 순서

Reference

  • https://www.youtube.com/watch?v=HlfvhkDuicc
  • https://jekyllrb.com/docs/installation/windows/
  • https://shryu8902.github.io/jekyll/jekyll-on-windows/

git 윈도우 버전 설치 2.26.0.windows.1

img

Ruby+Devkit 2.6.5-1 설치

Start Command Prompt with Ruby에서

->$ ridk install -> $ 1

img

c:\projects라는 폴더 만들고 -> 거기서 gem install bundler jekyll

-> jekyll new webapp

블로그를 만들고 싶다면, jekyll new my_blog!!

가 아니고 webapp과 my_blog는 폴더명일 뿐이다. jekyll new가 중요한 것이다.

img

$ jekyll serve를 써도 되고(블로그)

$ bundle exec jekyll serve(유투브)를 해도 되지만, 이게 더 안정적일 것 같다.

앞으로 jekyll 앞에는 꼭 bundle exec를 같이 쓰자!!

img

우선 여기까지

  1. git 설치 완료

  2. rudy설치 및 MSYS2 설치 완료

  3. jekyll bundle 설치 완료


Reference

  • https://mmistakes.github.io/minimal-mistakes/docs/installation/
  • https://github.com/mmistakes/minimal-mistakes

이런 저런 시도를 했는데 결론은 다음과 같았다.

  1. 새로 만든 [https://github.com/junha1125/junha1125.github.io]에 아무것도 넣지 않은 상태에서 minimal-mistakes의 파일을 모두 복사 붙여넣기 하여 가져온다.

  2. config의 theme와 remote_theme의 부분의 주석을 해제한다.

img

  1. 그리고 config 내부의 작가이름 이메일 블로그 이름 등 중요한 내용들을 바꾼다.

  2. $ jekyll new my_blog 를 하는 이유는 아무것도 theme가 없는 깨끗한 블로그를 만들기 위한 작업니다.

  3. (4)의 작업을 안해도 그냥 junha1125.github.io의 폴더에서 git 터미널을 실행하고 $ bundle exec jekyll serve 를 해도 정상적으로 서버가 열린다.

img

  1. 다음과 같이 localhost:4000에 들어가서 나의 블로그 상태를 확인할 수 있다.

img

  1. [https://junha1125.github.io/]까지 모든 변경사항이 적용되게 하고 싶다면, git add, commit, push를 하고 사이트에 접속하면 된다.

img


추후 공부 내용

  • 지금은 git을 필수적인 것은 완전히 익힌 상태이다. 하지만 정말 긴 미래에 git공부를 더 해야겠다면, youtube [https://www.youtube.com/watch?v=YQat_D1C-ps] 토크온강의를 참고 하자.
  • 역시 유투브… 괜히 google에서 “git blog 만드는 법” 같은거로 검색해서 하려니까 뭔가 잘 안된다.
  • https://www.youtube.com/watch?v=pGTdfWhgkrg
  • https://www.youtube.com/watch?v=eCv_bh-Ax-Q
  • https://www.youtube.com/watch?v=qWrcgHwSG8M
  • 이 사이트 차근차근 공부하자

강의 내용 정리1

[https://www.youtube.com/watch?v=pGTdfWhgkrg]

- Ruby를 설치하면, gem을 사용할 수 있다. gem과 jekyll은 미리 설치 잘 하기.

- bundle exec jekyll serve 를 하는 순간

img

[_post] 폴더에 있는 내용이 컴파일돼서 위와 같은 위치에, html(컴파일결과)가 생성된다.

- 아래와 같은 위치에, index.html 이 locallhost:4000 의 기본 페이지 기반이 된다.

img


강의 내용 정리2

[https://www.youtube.com/watch?v=WT0KRpNG–w]

이것을 이용해보겠다.

- http://jekyllthemes.org/themes/hydejack/

- zip[https://github.com/hydecorp/hydejack/releases] 다운 후, 내용물을 github.io에 모두 저장.

$ bundle install $ bundle exec jekyll serve

img

어느정도 완성했다 ^^


강의 내용 정리3

[https://www.youtube.com/watch?v=eCv_bh-Ax-Q]

- Vscode -> [markdown preview enhanced] Extension설치해서 아래와 같이 사용하면 편하다.

img

- 마크다운 강의가 있다. (이 부분은 pass. 이미지의 크기를 설정할 수 있는 명령어도 있으니 나중에 찾아보자)

기본 파일들

_config.yml : 모든 설정 파일

_posts : 폴더에 글들을 적어 놓는다

_pages : 개별 페이지 - about, 테마 등을 넣어서 관리

_includes : 글에 포함되는 개별 요소들

_layouts : 글의 양식 - 포스트나 페이지에 대한..

assets : css와 이미지 파일들

index.html : 표지

img


이것 저것 하다가 꾸역꾸역 만들었다.

차근차근 공부해 나가고 있는 중이다. 일단 중간과정 결과를 백업 해놓는다.

[테마 제공자에게 감사합니다. ]

junha1125.github.io-master (1).zip8.11MB

img

가장 마지막 a9af commit 자 자료.


새로운 카테고리 만들기 순서

  1. 폴더 만들기 /_posts/ ~~.md

  2. _featured_categories/.md

---
layout: list
title: <아무거나 가능 But foler name with Capa>
slug: <new folder name>
menu: true
permalink: /<new folder name>/
order: 1
sitemap: false
description: >
    지도학습 비지도학습 강화학습**^^**
# accent_color: rgb(38,139,210)
# accent_image:
#   background: rgb(32,32,32)
#   overlay:    false
---
  1. _config 수정하기
# Add links to the sidebar.
menu:
  - title:             <여기가 아무이름이나 다 됨>
    url:               /<New Folder Name>/
  1. 각 목차에 사용하는 게시물(md 파일)에 꼭 넣어야 하는 템플릿.
---
layout: post
title: Example Content III
description: >
  A page showing Hydejack-specific markdown content.
image: /assets/img/blog/example-content-iii.jpg
---

20.08.22 블로그 재 정검

오랜만에 들어와서 블로그를 업그레이드 하고 싶었다. 그래서 이것저것 확인하는 중 다음의 과정을 거쳤다. 그 과정을 혹시 몰라 기록해 놓는다.

  1. 다음과 같이 gemfile을 수정했다.
    image
  2. bundle exec jekyll serve를 하기 전에 빌드를 하란다. $ bundle install image
  3. 뭔가 버전이 엄청 안맞는다고 안된단다. 에러 메세지에 $ bundle update 를 하라고 해서 업데이트를 했다.
  4. 다시 bundle install 아주 잘된다.
  5. $ bundle exec jekyll serve
  6. _config.yml 파일에서 문제가 생긴다. 여기가 원래 주석이었는데 주석을 풀어놔서 그런가…..
    image

  7. 아하 이렇게 바꿔야 하는구나
    image

아주 문제없이 잘 된다. 기분이 아주 좋다.


【Pytorch】 Pytorch 튜토리얼 3 - pytorch로 딥러닝하기

(Pytorch) Pytorch 튜토리얼 3 - pytorch로

NEURAL NETWORKS 구성

"""
# nn 패키지를 사용한 신경망 생성

신경망의 학습 과정
1. 학습 가능한 매개변수(또는 가중치(weight))를 갖는 신경망을 정의합니다.
2. 데이터셋(dataset)을 이용해 아래의 과정을 반복한다.
3. 입력을 신경망에서 전파(process == forward)합니다.
4. 손실을 계산합니다.
5. 변화도(gradient)를 신경망의 매개변수들에 역으로 전파 -> d_Loss / d_parametar 를 구한다. 
6. 신경망의 가중치를 갱신합니다. weight = weight - learning_rate * gradient
"""
pass
import torch
import torch.nn as nn
import torch.nn.functional as F 
# F를 import하는 이유 : Implements forward and backward definitions of an autograd operation. 
class Net(nn.Module): # nn.Module 클래스를 상속하여 Net 클래스를 생성한다.
    def __init__(self): # para 없음
        super(Net,self).__init__()  # child class에서 parent class의 __init__ 내용들을 사용하고 싶다.
        self.conv1 = nn.Conv2d(1,6,kernel_size = 3)
        self.conv2 = nn.Conv2d(6,16,kernel_size = 3)
        
        self.relu = nn.ReLU()
        self.maxP1 = nn.MaxPool2d(kernel_size=2,stride=2)

        self.fc1 = nn.Linear(16*6*6, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x): # para에 x가 들어간다!
        '''[홈페이지 방법]
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        print(x.size()) # 1*6*15*15
        '''
        x = self.maxP1(self.relu(self.conv1(x)))
        # print(x.size()) # masP1의 stride가 1일 때. -> 1*6*29*29. // stride가 2일 때. -> 1*6*15*15 
        
        x = F.max_pool2d(F.relu(self.conv2(x)), 2) # maxpool은 정사각형이기 때문에 2만 넣어도 (2,2)로 인식한다.
        x = x.view(-1, self.num_flat_features(x))  # torch.Size([1, 16, 6, 6])  -> num_flat_feature를 하고 난 후의 x의 torch.Size([1, 576])

        # x = F.relu(self.fc1(x)) [홈페이지 방법]
        # print("num_flat_feature를 하고 난 후의 x의" , x.shape)
        x = self.relu(self.fc1(x)) 
        x = self.relu(self.fc2(x))
        x = self.fc3(x)
        return x

    def num_flat_features(self, x):
        size = x.size()[1:]  # all dimensions except the batch dimension (3차원이면 channel, 4차원이면 이미지 갯수)
        num_features = 1
        for s in size:
            num_features *= s   # 예를 들어 tensor sief (120, 6, 6) 라면, 6*6 = 36 을 return 한다.
        return num_features  

net = Net()
print(net)  # __init__ 에 정의한 내용이 나타난다. forward 아님! 

"""
forward 함수만 정의하고 나면, (변화도를 계산하는) backward 함수는 autograd 를 사용하여 자동으로 정의된다. 
모델의 학습가능한 매개변수들은 nn.Module 클래스의 parameters 매소드를 통해 확인할 수 있다.
"""
pass
Net(
  (conv1): Conv2d(1, 6, kernel_size=(3, 3), stride=(1, 1))
  (conv2): Conv2d(6, 16, kernel_size=(3, 3), stride=(1, 1))
  (relu): ReLU()
  (maxP1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (fc1): Linear(in_features=576, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)
params = list(net.parameters())
print(len(params))       # 10개에는 conv filter의 parameter, FC의 parameter, bias 등이 포함되어 있다. 자세한 건 나중에 더 자세히 알아보기
print(params[0].size())  # conv1's .weight
10
torch.Size([6, 1, 3, 3])
input = torch.randn(1, 1, 32, 32)
out = net(input)
print(out)

"""
*** NOTE 중요  ***
굳이 1*1*32*32의 이미지를 넣는 이유 : 
torch.nn 은 미니-배치(mini-batch)만 지원합니다. torch.nn 패키지 전체는 하나의 샘플이 아닌, 샘플들의 미니-배치만을 입력으로 받습니다.
만약 하나의 샘플만 있다면, input.unsqueeze(0) 을 사용해서 가짜 차원을 추가합니다.
"""
pass
num_flat_feature를 하기 전의 x의 torch.Size([1, 16, 6, 6])
num_flat_feature를 하고 난 후의 x의 torch.Size([1, 576])
tensor([[ 0.0136,  0.0084,  0.1542, -0.0920, -0.0778,  0.0385, -0.0898,  0.0524,
         -0.0445,  0.0961]], grad_fn=<AddmmBackward>)
net.zero_grad()  # 1. Sets gradients of all model parameters to zero.
out.backward(torch.randn(1, 10)) # # 2. Backpropa. 1*10 백터를 정규분포에서 랜덤한 값을 가져와 생성한 tensor.
# print(input.grad) -> None 이라고 나온다. 아직은 뭔지 모르겠으니 좀 더 공부해보자.


Loss Function

https://pytorch.org/docs/stable/nn.html#loss-functions

여기에 존재하는 다양한 loss functions 중에서 하나를 사용해보자.

MSEloss는 가장 단순한 mean-squared error Loss이다. (평균제곱오차)

input = torch.randn(1, 1, 32, 32)
out = net(input)  # 예측값
target = torch.randn(10)   # 정답값
# target = target.unsqueeze(1) -> tensor.size([10,1])
target = target.view(1,-1)
print("out의 사이즈 : {}  ==(같아야 한다) target의 사이즈 {}".format(out.size(), target.size()))

criterion = nn.MSELoss() # 이 loss function을 기준으로 삼겠다.
loss = criterion(out, target)
print("{} type, loss : {}".format(type(loss),loss))
out의 사이즈 : torch.Size([1, 10])  ==(같아야 한다) target의 사이즈 torch.Size([1, 10])
<class 'torch.Tensor'> type, loss : 1.5556150674819946

input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d

  -> view -> linear -> relu -> linear -> relu -> linear

  -> MSELoss

  -> loss
# 다음과 같은 방법으로, 최근에 한 마지막 연산들을 찾아갈 수 있다.
# 아래의 grad_fn 과 next_function은 torch document에도 없고 여기에만 있다... 
print(loss.grad_fn)  # MSELoss  // # 사용자가 마지막으로 이 변수를 만들 때 사용하는 Function을 참조한다. (기억해 놓는다.)
print(loss.grad_fn.next_functions[0][0])  # Linear
print(loss.grad_fn.next_functions[0][0].next_functions)  # ReLU
<MseLossBackward object at 0x000001915F1C0A88>
<AddmmBackward object at 0x000001915F1C0C88>
((<AccumulateGrad object at 0x000001915F1C0A88>, 0), (<ReluBackward0 object at 0x000001915F1C83C8>, 0), (<TBackward object at 0x000001915F1C8908>, 0))

오차(error)를 역전파하기 위해서는 loss.backward() 만 해주면 된다.

과거의 gradient를 없애는 작업이 필요한데( .zero_grad() ), 그렇지 않으면 gradient가 기존의 것과 누적되기 때문이다.
***

각 파라미터(가중치, 편향)에 대한 Loss 미분값을 알아내는 방밥

# 각 파라미터(가중치, 편향)에 대한 Loss 미분값을 알아내는 방밥

net.zero_grad()     # zeroes the gradient buffers of all parameters

print('conv1.bias.grad before backward')
print(net.conv1.bias.grad) # 이렇게 method를 사용하는 것도, 

loss.backward()

print('\nconv1.bias.grad after backward') # d_loss / d_bias_at-conv1
print(net.conv1.bias.grad)

print("\n bias 들의 실제 값 = ", net.conv1.bias)
conv1.bias.grad before backward
tensor([0., 0., 0., 0., 0., 0.])

conv1.bias.grad after backward
tensor([ 0.0211, -0.0160,  0.0067, -0.0190, -0.0056,  0.0125])

ias 들의 실제 값 =  Parameter containing:
tensor([-0.2747, -0.2196, -0.2772, -0.1524,  0.2187,  0.0836],
       requires_grad=True)

위에서 net.conv1.bias 는 그저 tensor이다. (https://pytorch.org/docs/stable/nn.html#conv2d 에서 확인가능 conv2d.weight도 사용 가능.)

그리고 grad는 torch.autograd.grad 를 이용한 것이다. (https://pytorch.org/docs/stable/autograd.html 에서 확인가능)

grad 함수 : xxx.grad에서 d_? / d_xxx 값을 tensor형태로 뱉어 준다.


가중치 갱신

확률적 경사하강법(SGD; Stochastic Gradient Descent)

# 아주 단순하게 가중치 갱신하는 방법
learning_rate = 0.01
# for를 돌아서, 내가 가진 모든 layers의 파라메터를 모두, 한번 갱신한다.
for i, f in enumerate( net.parameters() ):   
    print("{}번째 parameters 갱신 완료: {}".format(i+1, f.size()))
    f.data.sub_(f.grad.data * learning_rate)
     # 굳이 data method를 사용하는 이유는 모르겠다.
     # https://pytorch.org/docs/stable/tensors.html?highlight=sub_#torch.Tensor.sub_
    
# net.parameters를 이용해도 되고, 위에 처럼 net.conv1을 이용해도 좋다. print를 통해 알아보자.
print("\n", type(list(net.parameters())[0]), '\n', 
            type(list(net.parameters())[0].grad), '\n',
            type(list(net.parameters())[0].grad.data), '\n',
            list(net.parameters())[1].grad, '\n',
            list(net.parameters())[1].grad.data  )
1번째 parameters 갱신 완료: torch.Size([6, 1, 3, 3])
2번째 parameters 갱신 완료: torch.Size([6])
3번째 parameters 갱신 완료: torch.Size([16, 6, 3, 3])
4번째 parameters 갱신 완료: torch.Size([16])
5번째 parameters 갱신 완료: torch.Size([120, 576])
6번째 parameters 갱신 완료: torch.Size([120])
7번째 parameters 갱신 완료: torch.Size([84, 120])
8번째 parameters 갱신 완료: torch.Size([84])
9번째 parameters 갱신 완료: torch.Size([10, 84])
10번째 parameters 갱신 완료: torch.Size([10])

 <class 'torch.nn.parameter.Parameter'> 
 <class 'torch.Tensor'> 
 <class 'torch.Tensor'> 
 tensor([ 0.0211, -0.0160,  0.0067, -0.0190, -0.0056,  0.0125]) 
 tensor([ 0.0211, -0.0160,  0.0067, -0.0190, -0.0056,  0.0125])
# Optimizer를 사용해서 갱신하는 방법. https://pytorch.org/docs/stable/optim.html#algorithms -> 여기에 있는 가중치 갱신 알고리즘 사용할 것.
# 위의 과정이 optimizer.stop() 이라는 것 하나로 그대로 잘 동작한다.
import torch.optim as optim

# Optimizer를 생성합니다.
optimizer = optim.SGD(net.parameters(), lr=0.01)

# 학습 과정(training loop)에서는 다음과 같습니다:
optimizer.zero_grad()   # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()    # Does the update. 다양한 종류의 optimizer 들은 모두 자신만의 step method가 구현되어 있다.



【Algorithm】 [백준] 11047 동전 0

문제 링크 [https://www.acmicpc.net/problem/11047]

첫 제출 -> 시간초과

coins = []
answer = 0

n, k = map(int, input().split())
for i in range(n):
    coins.append(int(input()))

for i in range(n-1, -1, -1):
    if k >= coins[i]:
        while k >= coins[i]:
            k -= coins[i]
            answer += 1
    else: pass

print(answer)

정답 제출 (시간 : 60ms)

coins = []
answer = 0

n, k = map(int, input().split())
for i in range(n):
    coins.append(int(input()))

for i in range(n-1, -1, -1):
    if k >= coins[i]:
        num, k = divmod(k, coins[i])
        answer += num

print(answer)

배울 만한 코드 (나의 풀이와 크게 다른 건 없다) *(시간 : 52ms)*

N, K = map(int, input().split())

Coins = []
for i in range(N) : Coins.append(int(input()))


ans = 0
while K > 0 :
    coin = Coins.pop()
    ans += K // coin
    K %= coin

print(ans)

【Algorithm】 [프머] 코딩테스트연습/ 스택, 큐/ 쇠막대기

문제 사이트 [https://programmers.co.kr/learn/courses/30/lessons/42585]

손코딩

img

나의 코드

def solution(arr):
    start_stack = []
    answer = 0
    
    for i in range(len(arr)):
        if arr[i] == '(':
            start_stack.append(i)
        else:
            diff = i - start_stack.pop()
            if diff == 1:
                answer += len(start_stack)
            else:
                answer += 1
                
    return answer

좋은 코드

def solution(arrangement):
    answer = 0
    sticks = 0
    rasor_to_zero = arrangement.replace('()','0')

    for i in rasor_to_zero:
        if i == '(':
            sticks += 1
        elif i =='0' :
            answer += sticks
        else :
            sticks -= 1
            answer += 1

    return answer
    
***
    
def solution(arrangement):
    answer = 0
    stack = 0
    laseron = False
    for p in arrangement:
        if p == '(':
            laseron = True
            stack += 1
        else:
            if laseron==True:
                answer += stack-1
                laseron=False
            else:
                answer += 1
            stack -= 1

    return answer
    
    
***
    
    
def solution(arrangement):
    onLaser = 0
    total = 0

    for i in range(len(arrangement) - 1):
        if arrangement[i:i+2] == '((':
            onLaser += 1
        elif arrangement[i:i+2] == '))':
            onLaser -= 1
            total += 1
        elif arrangement[i:i+2] == '()':
            total += onLaser

    return total

【Python】 'torch' has no member error in VSCode, windows10 해결하기

(Python) ‘torch’ has no member error in VSCode, windows10 해결하기

img

이와 같은 간단한 코드에서, torch에 빨간 줄이 처지며 torch has no member ones 라는 에러가 뜨곤 했다.

(.py파일에만 이와 같은 문제가 발생한다. ipynb파일에는 발생하지 않는다.)

이 문제를 해결하기 위해 이 사이트를 참조해 해결했다.

[http://www.programmersought.com/article/9184357862/]

원래 나의 설정 모습

img

변경 후 설정 모습

img

이 path는 terminal (windows powershell) 을 이용했다.

img

【Python】 파이썬 자료구조와 알고리즘 - 교재 서평

[파이썬 자료구조와 알고리즘] 교재 정리 내용 입니다.


1. Immutable 과 mutable

[https://webnautes.tistory.com/1181] 이 사이트에 설정이 매우 자세히 나와 있다. 설명을 요약하자면 다음과 같다.

a = 1 // 변수 a와 1은 별개의 존재입니다.

여기서 a는 변수이고 1은 객체이다. 변수는 단순히 객체를 가리킬 뿐이다.

mutable 객체 : list, set, dict

객체를 생성한 후, 객체의 값을 수정 가능, 변수는 값이 수정된 같은 객체를 가리키게됨.

=연산자를 사용해 copy한 것은 얕은 복사이다. (copy by reference)

immutable 객체 : int, float, complex, bool, string, tuple, frozen set

객체를 생성한 후, 객체의 값을 수정 불가능, 변수는 해당 값을 가진 다른 객체를 가리키게됨.

=연산자를 사용해 copy한 것은 깊은 복사이다. (copy by value)

[그림은 이 사이트 참조 : https://ledgku.tistory.com/54]

2. float숫자끼리의 비교

다음과 같은 문제 때문에 함부로 비교하거나 빼면 안된다.

>> 0.2 * 3 == 0.6

False

>> 1.2 - 0.2 == 1.0

True

>> 1.2 - 0.1 == 1.1

False

이 문제를 해결하기 위해, unittest모듈의 assertAlomostEqual과 같은 메소드를 사용하는 방법도 있다.

하지만 이렇게 문제해결하는 것은 근본적 문제 해결이 아니므로 ‘최대공약수 찾기’와 같은 방법을 사용해야 할 것이다.

더 좋은 방법으로는 decimal 모듈을 사용하는 것이다. [from decimal import Decimal]

3. 숫자 연산에 필요한 메소드

divmod(x,y) : return (x//y, x%y)

rount(x,n) : return 소수점 n자리에서 반올림한 수 return

4. assert

assert 조건문 : 조건문의 결과가 True가 아니면 Error를 발생시킨다.

[https://wikidocs.net/21050]

5. 가장 기본적인 알고리즘 코드

\1. 진법 변환 :

\2. 최대공약수 :

\3. 소수 :

\4. numpy 패키지 :

공부를 위해 해당 페이지 참고 : [http://aikorea.org/cs231n/python-numpy-tutorial/#numpy]


**<이 책에="" 대한="" 나의="" 생각="">**

이 책은 코딩테스트를 위해 좋은 책은 아니다. 코딩 테스트를 준비하기 위해서는 차라리 고득점 킷을 풀어보고, 문제를 풀어보면서 ‘이러한 방법으로 풀면 좋다(완전탐석 DFS HEAP 등)’ 라는 것을 인터넷에서 찾아가며 공부하는 것이 훨씬 좋다.

대신 이 책은 면접을 위해 좋은 책이다. 그리고 파이썬을 통한 프로그램 개발자가 알아두면 좋은 책이다. 알고리즘을 개발하고 프로그램을 개발하는 사람이라면 기본적으로 알아두면 좋은 책이다.

하지만 웹 웹 개발자, 딥러닝 모델 개발자가 알아두면 좋은 책인가? 그건 아니다. 이러한 개발자들은 다른 사람들이 만들어 놓은 모듈을 잘 이용하는 것이 더 중요하다.

따라서 지금 이 책을 공부하는 것은 때가 아니다. 우선 코딩테스트 준비를 완벽하게 하고 난 후에, 어느 정도 여유가 생기고, 공부해야겠다는 생각이 들면, 공부하는 것이 좋을 듯 하다.

이 책에는 몇가지 중요한 메소드(맴버함수)들이 소개되지만, 어차피 책을 통해 공부한다고 한들 무조건 까먹고 나중에 당연히 검색을 해야한다. 따라서 지금 책을 읽어 메소드들을 머리속에 암기하려는 행동보다는 코딩테스트를 준비하면서 유용했던 메소드들을 차근차근 공부하고 기억해나가는 것이 더 좋을 듯 하다.

따라서 지금 이 책은 한 동안 읽지 않으려고 한다. 대략 4개월 정도 후에 공부할 필요성이 느껴진다면 그 때가서 공부를 해야겠다. 지금은 맨 위에서 말했던 대로, [1. 고득점 킷 2. 코딩테스트 기출을 풀면서 몰랐던 이론과 구현법 공부.] 를 해야겠다.

Pagination


© All rights reserved By Junha Song.