【Paper】 Image Segmentation Using Deep Learning -A Survey [1]

Image Segmentation Using Deep Learning: A Survey 논문 리뷰 및 정리

(위성Segment) Segmentation Survey 논문 정리 1
논문 원본 : 2020 (cite:6) Image Segmentation Using Deep Learning: A Survey

추가로 공부해야 하는 내용

  1. Autoencoder
  2. LSTM

Abstract

  1. Image segmentation은 이미지 처리 및 컴퓨터 비전의 핵심이다.
  2. 이 논문에서는 Segmentation을 위해, 선구적인 기술들에 대한 Survey를 다룬다.
    • 예를 들어, 1. fully convolutional pixel-labeling networks, 2. encoder-decoder architectures, 3. multi-scale and pyramid based approaches, 4. recurrent networks, 5. visual attention models, and 6. generative models in adversarial settings.
  3. 각 모델에 대해서, 널리 사용되는 데이터셋을 사용해서, 유사성, 강점(장점), 성능을 비교한다.
  4. 마지막으로 독자들에게 유망한 미래 연구&공부 방향도 제시해준다.

Instruction

  1. image segmentation의 필요성(중요성):

    image segmentation은 시각적 이해 시스템(visual understanding system)에 있어 필수적인 요소이다.

    의료 영상 분석 (예 : 종양 경계 추출 및 조직 체적 측정), 자율 주행 차량 (예 : 탐색 가능한 표면 및 보행자 감지), 비디오 감시 및 증강 현실을 포함하여 광범위한 응용 사례에 있어 중요한 역할을 수행한다.

  2. image segmentation 연구에 활용된 알고리즘:

    과거 :

    • thresholding
    • histogram-based bundling
    • region-growing
    • k-means clustering
    • watersheds

    더 나아가:

    • active contours
    • graph cuts
    • conditional and Markov random fields
    • sparsity-based methods
  3. 최근 경향:

    Deep Learning을 이용한 image segmentation 모델들이 많이 나왔다.

  4. image segmentation의 종류?

    image segmentation은 semantic label에 대한 각 픽셀의 분류 문제(semantic segmentation) 혹은 개별 객체의 분할(instance segmentation)의 문제로 공식화 할 수 있습니다.

    • semantic segmentation는 모든 이미지 픽셀에 대해 일련의 객체 범주 (예 : 사람, 자동차, 나무, 하늘)를 사용하여 픽셀 수준 레이블링을 수행하므로 일반적으로 전체 이미지에 대한 하나의 label을 예측(predict)하는 이미지 분류보다 어려운 작업입니다.
    • instance segmentation은 이미지에서 관심있는 각 객체를 감지하고 묘사함으로써 semantic segmentation 범위를 더 확장합니다 (예 : 개인의 partitioning).
  5. 주요 기술 Contributions(특성, 계보)를 기준으로, 100개의 모델들을 다음 범주로 그룹화 할 수 있다.

    1) Fully convolutional networks

    2) Convolutional models with graphical models

    3) Encoder-decoder based models

    4) Multi-scale ad pyramid network based models

    5) R-CNN based models (for instance segmentation)

    6) Dilated convolutional models and DeepLab family

    7) Recurrent neural network based models

    8) Attention-based models

    9) Generative models and adversarial training

    10) Convolutional models with active contour models

    11) Other models

  6. 이 논문을 전체요약하면 다음과 같이 적을 수 있다.

    1) 2019년 이후의 100개 이상의 Segmentation 알고리즘을 10가지 범주로 그룹화 했다.

    2) 학습 데이터, 네트워크 아키텍처, Loss 함수, 학습 전략, 모델의 주요 특성(어떤 계보를 따르는가?)를 달리하여 만든 많은 모델들의 Review, 통찰력 있는 분석 결과를 제시한다.

    3) 2D, 3D를 포함한 20개의 인기 있는 segmentation 데이터 셋의 개요를 제공 한다.

    4) 이 모델들을 비교, 요약하여 앞으로의 Image segmentation의 몇가지 과제와 해결방향 그리고 잠재적 미래 방향을 제시한다.

  7. 이 논문을 각 파트를 전체요약하면 다음과 같이 적을 수 있다.

    1) Section 2 : 모든 모델의 Backbone이 되는 인기 있는 deep neural network architectures 개요 제공

    2) Section 3 : 100개 이상의 중요한 Segmentation 모델에 대한 포괄적 개요, 그리고 그들의 장점, 특성 제공

    3) Section 4 : 유명한 Segmentation Dataset의 개요와 각각의 특성을 검토

    4) Section 5.1 : Segmentation 성능 지표 검토

    5) Section 5.2 : 모든 모델들의 (위에서 설명한 성능 지표에 따른) 정량적 성능 검토

    6) Section 6 : Image sementation의 주요 과제와 해결방향, 향후 방향들을 검토

    7) Section 7 : 결론

Section 2: Overview of Deep Neural Networks

2.1 Convolutional Neural Network (CNNs)

  1. CNN은 주로 3 가지 유형의 layer로 구성된다.

    1) convolutional layer: 특징을 추출하기 위해 가중치 (kernel) (또는 필터)의 가중치 (kernel)가 있다.

    ii) nonlinear layer: 네트워크에 의한 비선형 함수의 모델링을 가능하게하기 위해 피쳐 맵에 활성화 함수를 적용한다. (보통 요소별로)

    iii) pooling layer: 특징 맵의 작은 이웃을 이웃에 대한 일부 통계 정보 (평균, 최대 등)로 대체하고 공간 해상도를 감소시킨다.

  2. 레이어의 단위는 로컬로 연결되어 있다.

    즉, 각 유닛은 이전 계층의 유닛의 수용 장으로 알려진 작은 이웃으로부터 가중 된 입력을 수신한다.

    다중 해상도 피라미드를 형성하기 위해 레이어를 쌓으면서 더 높은 레벨의 layer는 점점 더 넓은 수용 영역에서 기능을 학습합니다.

  3. CNN의 주요 계산 이점:

    레이어의 모든 수용 필드가 가중치를 공유하여 완전히 연결된 신경망보다 훨씬 적은 수의 매개 변수를 생성한다는 것이다.

  4. CNN 아키텍처:

    AlexNet // VGGNet // ResNet // GoogLeNet // MobileNet // DenseNet

2.2 Recurrent Neural Networks (RNNs) and the LSTM

  1. RNN은 음성, 텍스트, 비디오 및 시계열과 같은 순차적 데이터를 처리하는 데 널리 사용된다.

    여기서 주어진 시간 / 위치의 데이터는 이전에 발생한 데이터에 의존한다.

  2. RNN의 구조

    image

    각 타임 스탬프에서 모델은 현재 시간 Xi의 입력과 이전 단계 hi-1의 숨겨진 상태를 수집하고 목표 값과 새로운 숨겨진 상태를 출력한다.

  3. RNN의 한계점?

    RNN은 일반적으로 많은 실제 응용 프로그램에서 장기적인 종속성(long-term dependencies)을 캡처 할 수 없다. 이 때문에 gradient vanishing 또는 exploding 문제로 고통받는 경우가 많으므로 일반적으로 long sequences에 있어 한계점이 있다.

  4. 위와 같은 RNN의 한계점을 극복하기 위해 LSTM(Long Short Term Memory)이 등장하였다.

  5. LSTM 구조

    추가 내용 : 백업완료_2020.03\ML\CS231n 의 RRN 파일 참조

    image

    LSTM 아키텍처에는 메모리 셀로 들어오고 나가는 정보의 흐름을 조절하는 3 개의 게이트 (input gate, output gate, forget gate)가 포함되어 임의의 시간 간격에 걸쳐 값을 저장한다.

  6. input, forget states 및 다른 gate 사이의 관계는 다음과 같다.

    image

    • \(x_t \Subset R^d\) : time-step \(t\)의 input
    • \(d\) : 각 word의 feature dimension
    • \(\sigma\) : 요소별 시그모이드 함수 ([0,1])
    • \(\bigodot\): 요소별 곱셈
    • \(c_t\) : 메모리 셀 ( gradient vanishing/exploding의 위험을 낮추기 위함, 이를 통해 따라서 기존 RNN에서 실행 가능한 오랜 기간 동안 종속성 학습 가능)
    • \(f_t\) : forget gate (메모리셀을 reset 하기 위한)
    • \(i_t\) : input gate (메모리 셀의 input을 제어)
    • \(o_t\) : output gate (메모리 셀의 output을 제어)

2.3 Encoder-Decoder and Auto-Encoder Models

image

  1. 인코딩 함수는 입력을 잠재 공간 표현(Latent Representation)으로 압축한다.
  2. 디코더 함수는 위에서 만든 Latent Representation을 이용해서 출력을 만들어낸다(예측한다).
  3. 여기서 Latent Representation는 입력의 주요한 feature들을 표현한 것이다
  4. Loss는 reconstruction loss라고 불리우는 L(y; y^)를 사용한다.
  5. NLP에서 많이 사용된다. Output이 초해상화된 사진, Segmentation 결과 등이 될 수 있다.

Auto-Encoder Models

  1. Input과 output이 동일한 특별한 경우에 사용한다. (즉 input과 같은 output 생성 원할 때)

  2. 2가지 종류가 있다.

    (1) SDAE (stacked denoising auto-encoder)

    • 가장 인기 있음. 여러개의 auto-encoder를 쌓아서 이미지 deNoising 목적에 많이 사용

    (2) VAE (variational auto-encoder)

    • Latent representation에 prior distribution(확률 분포)의 개념을 추가 시킨다.
    • 위의 확률 분포를 사용해서 새로운 이미지 y를 생성시킨다.

    ps. (3) adversarial auto-encoders

    • prior distribution와 유사한 latent representation를 만들기 위해 adversarial loss를 사용

2.4 GANs(Generative Adversarial Networks)

  1. 2개의 network 모델 : Generator(위조 지폐 제작사) VS Discriminator(경찰. 감별사)
  2. x : 실제 이미지/ z : 노이즈 이미지/ y : G가 생성한 이미지

image

  1. 초기 GAN 이후의 발전
    • (Mr. Radford) fully-connected network가 아니라, convolutional GAN model 사용
    • (Mr. Mirza) 특정 label 이미지를 생성할 수 있도록 class labes로 conditional된 GAN
    • (Mr. Arjovsky) 새로운 loss function 사용. y x의 확률 분포가 완전히 겹치지 않게 한다.
    • 추가 : https://github.com/hindupuravinash/the-gan-zoo

2.5 Transfer Learning

  1. 이미 학습된 모델은 이미지에서 the semantic information를 뽑아낼 수 있는 능력을 가지므로, 많은 DL(deep learning)모델들은 충분한 train data가 없을 수 있다. 이때 Transfer Learning이 효율적이다.

  2. 다른 곳에 사용되던 model을 repurpose화(우리의 데이터에 맞는 신경망으로 학습)시키는 것이다.

  3. Image segmentation에서 많은 사람들은 (인코더 부분에서) ImageNet(많은 데이터셋)으로 학습된 모델을 사용한다.

【Algorithm】불량 사용자 - 카카오 문제

프로그래머스 불량사용자 알고리즘 풀이

문제링크 : 불량사용자
주석을 참고해서 코드 이해에 도움을 받으시길 바랍니다.

풀이 코드

"""
Point
    - def(A) 내부에 다시 def(B)을 사용함으로써, 전역변수나 함수(B)의 많은 매개변수 사용을 줄였다.
    - banned_id 원소 하나 당, 매핑이 되는 user_id 하나를 골라낸다.
"""

def solution(user_id, banned_id):
    
    def check(b_id, user):
        """
        하나의 user_id와 b_id를 비교한다. 
        user_id가 b_id에 속하는 것이라면, return True.
        아니라면, return False. 
        """
        for s in range(len(b_id)):
            if b_id[s] != '*':
                if b_id[s] != user[s]:
                    return False
            elif b_id[s] == '*':
                continue
        else:
            return True

    def back(u, b):
        if b == N2: # Reculsivd Function의 Base condition이다. "user_id 하나와 banned_id 모두를 다 비교했다면."
            if u not in result:
                result.append(u[:]) # u를 copy by value해서 result 에 넣는다. **중요**
            return
        for i in range(N1): # user_id의 원소를 하나씩 살펴본다. 
            # 위에서 고른 user_id의 하나와, banned_id의 원소 모두와 비교해본다.
            if u[i] == 0 and len(banned_id[b]) == len(user_id[i]): # 중요한 전제 조건. 2 문자열의 길이가 같아야 한다. 
                if check(banned_id[b], user_id[i]) == True: # banned_id 원소 하나 당, 매핑이 되는 user_id 하나를 골라냈다면, 
                    u[i] = 1 # 위에서 매핑한 user_id임을 표기해논다.
                    back(u, b + 1) # 다음 banned_id 원소에, 매핑되는 user_id 하나를 골라낸다.
                    u[i] = 0 # 맨 처음부터 원상 복귀.

    # 1 : 변수 선언 및 정의
    answer = 0
    N1 = len(user_id)
    N2 = len(banned_id)
    u = [0 for ii in range(N1)]  # u[k]=1 는 user_id[k]가 banned_id 중 하나에 해당함을 의미한다. 
    result = [] # 가능한 u 배열의 경우와 수를 저장한다. 

    # 2 : reculsive 돌기 시작!
    back(u, 0)

    # 3 : 최종 결과 return.
    answer = len(result) # 입출력 예 1의 result = [[1,0,0,1,0] , [0,1,0,1,0]]. 즉 2가지 경우가 존재한다.
    return answer

if __name__ == "__main__":
    user_id = ["frodo", "fradi", "crodo", "abc123", "frodoc"]
    banned_id = ["fr*d*", "abc1**"]
    print(solution(user_id, banned_id))
    pass


"""
Reculsive 흐름도 
[1, 1, 0, 0, 0]
[1, 0, 1, 0, 0]
[0, 0, 0, 1, 0]
[1, 0, 0, 0, 1]
[0, 0, 0, 0, 0]
[0, 1, 1, 0, 0]
[0, 1, 0, 1, 0]
[0, 1, 0, 0, 1]
[0, 0, 0, 0, 0]
[0, 0, 1, 1, 0]
[0, 0, 1, 0, 1]
[0, 0, 0, 0, 0]
[0, 0, 0, 1, 1]
[0, 0, 0, 0, 0]
"""

참고할 만한 다른 사람 코드

"""
우선 와일드카드가 포함된 문자(banned_id)로 가능한 모든 user_id의 idx를 추출한다.
이를 가지고 완전 탐색 방법을 이용하여 답을 구한다
"""

import re

def solution(user_id, banned_id):
    possible_id = []   # 각 banned_id로부터 가능한 user_id들의 index들이 저장될 배열
    cases_arr = []     # 모든 정답들을 저장할 배열
    len_banned_id = len(banned_id)  #

    def calc_cases_idx(id): # 가능한 모든 경우의 수를 추출하는 함수
        id+="$"
        regex = re.compile(id.replace('*', '.'))
        matches = [i for i, string in enumerate(user_id) if re.match(regex, string)]
        return matches
    
    def recSolution(n, arr): #현재 몇번째 banned_id인지, 어떠한 user_id들이 선택되었는지에 대한 배열
        if n == len_banned_id:
            arr.sort()
            if arr not in cases_arr:
                cases_arr.append(arr)
                return 1
            else:
                return 0
        rec_answer = 0
        for num in possible_id[n]:
            if num not in arr:
                rec_answer += recSolution(n+1, arr + [num])
                
        return rec_answer
    
    for i in range(len(banned_id)):
        possible_id.append(calc_cases_idx(banned_id[i]))
    print(possible_id)
    
    
    return recSolution(0, [])

【위성Segment】 Segmentation Survey 논문 작성 목표로, 읽을 논문 정리

(위성Segment) Segmentation Survey 논문 작성 목표로, 읽을 논문 정리

1. Awesome segmentation

(1) Paper & Git

  1. Awesome semantic segmentation : (6.2k stars) semantic segmentation 논문들 모두 정리 + Git 코드 정리
  2. Awesome-segmentation : (8 stars) semantic segmentation은 위의 사이트와 동일. instance segmentation도 추가 되어 있음.
  3. Awesome-satellite-segmentation : (1.3k stars) List of satellite image training datasets
  4. Really-awesome-semantic-segmentation : semantic-segmentation에 관한 Survey papers도 있다.

(2) Code

  1. awesome-semantic-segmentation-pytorch : (1k stars)Semantic Segmentation과 관련된 (살짝 과거) 기술들을 모아서 코드화 시켜놓았다. 다 읽고 정독하면 좋을 듯 하다. On PyTorch (include FCN, PSPNet, Deeplabv3, Deeplabv3+, DANet, DenseASPP, BiSeNet, EncNet, DUNet, ICNet, ENet, OCNet, CCNet, PSANet, CGNet, ESPNet, LEDNet, DFANet)
  2. semantic-segmentation-pytorch : (3.1k stars) 최근 Segmentation 기술들을 코드화 시켜놓았다. Pytorch implementation for Semantic Segmentation/Scene Parsing on MIT ADE20K dataset

2. Survey paper - segmentation

(1) 위의 Really-awesome-semantic-segmentation 에 있는 논문들

여기 있는 논문들은 semantic-segmentation를 어디에 사용했는가 가 중심인듯 하다.

(2) Google Scholar

(3) DBpia

  • 한글 Survey(조사) 논문은 없다.

3. Survey paper - satellite segmentation

(1) satellite segmentation 대회 주요 논문

(2) satellite survey 논문

  • 논문이 없다.

(3) satellite segmentation 연구 논문

4. PS

  1. 논문 읽는 방법 : 논문 읽는 방법
    • 하나의 논문은 3 pass 과정을 거쳐서 3번은 훑어야한다.
      • 논문의 전반적인 아이디어 이해
      • 디테일을 제외한 논문의 내용 이해
      • 깊은 이해
    • Literature Survey

step1

제목, abstract, introduction, 각 섹션의 제목, Conclusion

step2

논문에 더욱 집중해서 읽어라
증명과 같은 세세한 것들은 무시해라
핵심을 써내려가라
그림, 다이어그램, 그리고 다른 삽화들을 주의 깊게 살펴보아라. 특히나 그래프에 신경을 써서 보아라

step3

가장 중요한 것은 논문을 가상으로 재 실험해보는 것이다

【26살-Git Blog】- Git Page로 안녕하세요 / Blog 오류 참고

(26살) - Git Page로 안녕하세요

2020-04-17 인사, 일기

원래 나는 가끔 다른 곳에 공부한 내용들이나 나의 이야기를 글로 작성해왔다.
2020-04 이전에 올려진 게시물은 원래 다른 블로그에 작성한 글이다.

  1. 네이버 블로그
  2. Tstory 블로그

가끔 내가 Blog를 작성해왔던 이유는, 내가 공부하고 활동한 흔적을 남기기 위함이었다.

2학년 후반 산학장학생과 장학재단의 장학생 등 8곳 정도에 지원을 했었다. 대부분 서류합격은 했지만 꼭 면접에서 떨어져 결국엔 모든 곳에서 지원을 받을 수 없었다. (운이 좋아 3학년 초반에 한국장학재단의 국가이공계장학생이 되긴했지만..)

그때의 충격이 생각보다 컸다. 나도 나름 대학생때 열심히 공부했는데.. (학점이 거의 만점이었기에.. ) 라는 생각을 많이 했다. 하지만 면접관 분들이 시선은 학점만 높고 활동은 안한 학생. 어쩌면 사회성이 떨어지는 학생을 바라보는 시선이었다.

그 후 학점이 전부가 아니라는 것을 절실히 깨닫고, 내가 하고 싶은 공부를 하고, 최대한 어떤 모임이나 동아리에서 프로젝트를 진행하며 살아왔다. 그리고 그렇게 살아왔다는 증거이자 흔적을 남기고 내가 공부하는 내용을 최대한 정리해서 올려놓자. 라는 마음으로 생각날 때 마다 블로그에 글을 올려 놓았다.

이제 인공지능&자율주행 쪽으로 진로를 완전히 정한 만큼. 깃을 이용해 나의 공부 내용, 연구 노트, 나의 프로젝트와 활동들에 대한 이야기를 적어놓으려고 한다.^^

연구노트로 매일매일 공부한 내용을 글로 올리기 때문에, 글의 내용이 작성자만 알아볼 수 있는 내용으로 채워질 수도 있지만, 최대한 성실하고 친절하게 내용을 정리할 계획입니다. 이 깃 블로그 페이지를 방문해주신 모든 분들 모두모두 항상 건강하고 행복하시길 바랍니다. ^^

오류 및 주의사항

Tstory에 올려놓았던 게시물을 그대로 복붙해서 가져오다보니 다음과 같은 문제가 생겼다.

$ sudo docker start <Contain ID>

이와 같은 글에서
$ sudo docker start 이 처럼 <> 가 안보이는 현상이 일어난다. Blog 포스트 말고, Git 공식 홈페이지에서 찾아보면 <>가 보이는데도 불구하고 말이다.

따라서 해결방법 :

  • 다음에 게시물을 작성할때는 꼭 아래와 같이 작성해야 겠다
  • 이전 게시물(Tstory 복붙)을 보고 공부하다가 뭔가 이상하다 싶으면 Git 공식 홈페이지에 가서 원본 .md파일을 읽어봐야 겠다.
$ sudo docker start \<Contain ID>

【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

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


Pagination


© All rights reserved By Junha Song.