728x90

백트래킹 문제를 연습하다 백준 문제 1987문제를 시간복잡도를 만족시키지 못하여 골머리를 썩던 중 문제점을 하나씩 찾기 시작했다. 집합 관계(포함 관계)의 문자열을 처리하기 위해 컴퓨터는 사실 10진수로 다시 변환하여 저장한다는 것을 깨닫고 문자열 대신 숫자로 표현하는 방법을 찾기로 했다.

그러다 찾은게 비트마스킹이라는 방법인데, 집합관계를 비트단위로 표현한 값들로 처리할 수 있게 도와주는 방법이다. (참고 : https://mygumi.tistory.com/361)

간략히 설명하면 0부터 5까지 다음 집합 A = {1,2,5}에 속한 숫자만 골라내기 위해 1,2,5를 비트단위로 변환 후 0부터 5까지의 비트 단위과 1,2,5 비트단위와의 교집합을 통해 존재하는지 안하는지 확인할 수 있는 방법이다.

위의 예를 들면

# 1,2,5 를 비트단위로 표현하자면 0부터 시작하는 파이썬은 100110이 되어야한다.
a = [1,2,5]
bit_a = 0
for value in a:
    tmp += 1 << x

print(x)
# 38
print(bin(x))
# '0b100110'

a에 있는 원소의 합을 bin으로 처리하게 되면 다음과 같이 예상대로 100110이 나오게 된다. 따라서 0부터 5는 000001, 000010, 000100, ... , 100000이 될 것이고 각자 100110과의 교집합을 통해 없으면 0 있으면 1로 표현할 수 있도록 포함관계를 나타내면 가능하다는 뜻이다.

for i in range(6):
    if tmp & 1 <<i :
        print(i)
# 1
# 2
# 5

그럼 이제 원래의 문제의 코드로 넘어가서 풀어보도록 하자, 본래 시간복잡도에서 걸린 코드는 다음과 같다.

r, c = map(int, input().split())
pan = [input().strip() for _ in range(r)]

answer = 0
dx, dy = [1,-1,0,0], [0,0,1,-1]

def find(now, cnt, status):
    global answer, dx, dy

    x,y = now

    if  pan[x][y] in status :
        answer = max(cnt, answer)
        return 

    status += pan[x][y]

    for i in range(4):
        nx, ny = x + dx[i], y + dy[i]

        if nx < 0 or nx >= int(r) or ny < 0 or ny >= int(c):
            continue
        cnt += 1
        find([nx,ny], cnt, status)
        cnt -= 1
find([0,0], 0, "")
print(answer)

비트마스킹을 할 수 있는 부분이 보이는가?

if  pan[x][y] in status :
    answer = max(cnt, answer)
    return 
#...
    if nx < 0 or nx >= int(r) or ny < 0 or ny >= int(c):

이 두 부분이 문자열로 구성되어있는 것을 비교연산자를 사용하기 때문에 병목이 생기는 구간일 수 있다. 따라서 우린 이걸 비트마스킹으로 변환해서 풀어보고자 하면 다음과 같은 코드로 작성될 수 있을 것 같다.

r, c = map(int, input().split())
pan = [input().strip() for _ in range(r)]

answer = 0
dx, dy = [1, -1, 0, 0], [0, 0, 1, -1]

def find(x, y, cnt, bitmask):
    global answer
    answer = max(cnt, answer)

    for i in range(4):
        nx, ny = x + dx[i], y + dy[i]

        if 0 <= nx < r and 0 <= ny < c:
            idx = ord(pan[nx][ny]) - ord('A') 
            if not (bitmask & (1 << idx)):    
                find(nx, ny, cnt + 1, bitmask | (1 << idx)) 

initial_bitmask = 1 << (ord(pan[0][0]) - ord('A'))
find(0, 0, 1, initial_bitmask)
print(answer)

실제로 시간 계산을 해봐도 0.00048 sec > 0.00040 sec 개선이 되었다 (물론 하나의 백준 예제 case에 대해서만 측정). ChatGPT에게 물어봐도 int()와 ord()의 변환 과정 에서의 시간 복잡도도 차이가 많이 큰걸로 보인다. 신이 말하기로는 다음과 같은 차이가 있다고 한다.

[!int()와 ord()의 차이]
int()ord() 함수의 시간 복잡도는 다음과 같습니다.

  1. int() 함수:
    • int(x) 함수는 문자열 x를 정수로 변환합니다. 여기서 시간 복잡도는 문자열의 길이에 따라 달라집니다. 일반적으로 문자열의 길이가 n일 때, 이 함수의 시간 복잡도는 O(n)입니다.
    • 이는 각 문자에 대해 10진수 값을 계산하고 이를 합산하는 과정이 필요하기 때문입니다. 문자열의 각 문자를 순회하면서 해당 문자의 10진수 값을 계산해야 하므로, 문자열의 길이에 비례하는 시간이 소요됩니다.
  2. ord() 함수:
    • ord(c) 함수는 단일 문자 c의 유니코드 값을 반환합니다. 이 함수는 항상 단일 문자에 대해서만 작동하므로 시간 복잡도는 상수 시간, 즉 O(1)입니다.
    • 단일 문자의 유니코드 값을 반환하는 작업은 매우 단순하여, 입력 길이에 관계없이 일정한 시간이 소요됩니다.

따라서, int() 함수는 변환할 문자열의 길이에 따라 시간 복잡도가 O(n)인 반면, ord() 함수는 상수 시간 O(1)을 가집니다.

728x90
poetry add $(cat requirements.txt)

 

pip install -r requirements.txt를 하게되면 pip으로 라이브러리 다운로드 하지만

라이브러리 의존성을 생각하면서 다운로드 하기위해 poetry를 사용하여 requirements에 있는 라이브러리를 다운로드 하려니 그런 기능을 지원을 하지 않는다.

 

따라서 터미널 상 명령어를 bind해주면 될 것 같아 | 를 사용하여 해결해보니 잘 안되었다. 

역시나 스택오버 플로우는 신이라 해결방법을 떡하니 알려주어서 사용해보니 정상적으로 설치가 완료 되었다.

https://stackoverflow.com/questions/62764148/how-to-import-an-existing-requirements-txt-into-a-poetry-project

 

How to import an existing requirements.txt into a Poetry project?

I am trying out Poetry in an existing project. It used pyenv and virtual env originally so I have a requirements.txt file with the project's dependencies. I want to import the requirements.txt file...

stackoverflow.com

 

'CS' 카테고리의 다른 글

개인 서버 만들기 (1)  (0) 2023.03.30
728x90

우문현답, 어리석은 질문에 대응하는 현명한 답을 뜻하는데 근래에 질의응답 상황들을 유심히 보면 어리석은 질문에 답변을 생각할 시간이 아까워 질문자를 무시하거나 의도와 다른 TMI 또는 질문 자체를 무시하는 경우를 종종 보았습니다. 현대에 현답을 주는 사람은 어리석은 질문이라도 무시하지 않고 엄청난 사고 끝에 질문자의 부족한 부분을 채워줄 수 있는 현명한 답변을 해 줄 수 있는 사람이 아닐까 싶습니다.

하지만 현답을 해주는 사람을 찾기는 너무나도 어려울 것 같으니 궁금해진 건 두 가지입니다. "어떤 질문이 어리석은 질문인가?", "현문을 하는 사람은 어떨까?"입니다.

  • 어리석은 질문

    제가 생각했을 때 질문은 절대적이진 않다고 생각했습니다. 이 뜻은 누구에겐 어리석을 수 있지만, 누구에겐 당연하거나 한 번도 생각하지 못할 수 있다고 생각했습니다. 그러니 현답이 나올 수 있는 조건부는 한 번쯤 생각해 보고 스스로에게라도 답변해 본 경험의 여부가 아닐까 싶습니다. 그럼 범용적으로 어리석지 않은 질문을 하는 방법은 무엇이 있을까요..?

    저는 최근 질문을 던질 때 상대방이 의도에 맞지 않는 답변이 나올 때나, 내가 원하는 방향대로 인터뷰가 진행되지 않는다고 빈번히 느꼈습니다. 상대방의 역량을 의심하면서 매번 저에 대한 의구심을 갖지 않다가 문득, 유독 나한테 이런 일이 일어난다는 것은 나에게 잘못이 있지 않을까 싶었습니다. 하지만 내부의 문제점을 찾기는 너무 어려워 주로 어떤 답변이 나를 힘들게 하는지 파악하고자 했습니다.

    의식하며 질문을 해보니 주로 돌아오는 반문은 보통 "어떤 이유에 의해 이 질문을 하는지?" 또는 "질문의 의도를 모르겠다."였습니다. 이런 반문을 들을 때 항상 어떤 이유에 의해 질문을 했는지 말씀드리고 다시 물어보면 원하던 답변을 얻을 수 있었습니다. 사람마다 다르겠지만 제 질문의 문제점은 내가 알고 있는 것도 상대방이 당연히 알고 있을 것이란 착각에 질문의 배경을 툭 잘라놓고 질문을 하는 것이었습니다. 

    처음으로 질문의 한자를 풀어보았는데 "바탕 질"에 "물을 문"이라는 뜻은 어떤 환경이나 주요 부분이 같이 공유된 상태(바탕)에서의 묻는(물을) 말이 아닐까 싶었습니다. 따라서 어디서부터 모르고 어떤 환경에 놓였는지에 대한 공유가 완성되고야 질문에 접근할 수 있다고 느꼈습니다. 앞으로 당연한 생각보단 질문을 하기 전 자가점검을 통해 어디서부터 설명해 드리고 질문을 던져야 할지에 대한 고민을 하는 역량을 기르도록 노력해야겠다는 생각이 생겼습니다. 

 

  • 현문을 하는 사람

    산업공학을 전공하면서 5 why에 대한 공부를 한 경험이 있습니다. 말 그대로 현상 파악을 위해 발생하게 된 원인을 "왜?"라는 물음에 다섯 번 반복해 나가면 문제의 근본원인에 도달할 수 있다는 뜻입니다. 같이 전공한 친구와의 잡담 중에 5 why를 실제로 해봤을 때 단순히 왜라는 질문을 5번 하는 것은 비효율적이라고 생각했습니다. 하나의 일화는 다음과 같습니다.

    A: "취업이 하고 싶다."
    B: "왜 취업을 하고 싶어?"

    A: "개발이 이론 상과 현업과 얼마나 다른가에 대한 경험 + 모델을 제품으로 발전시키는 현업과정을 경험하기 위해"
    B: "왜 얼마나 다른지 알고 싶어?"

    A: "내가 쌓아온 역량이 올바른 방향인지 알기 위해서"
    B: "왜 너가 만든 모델을 평가하고 싶어 하지?"

    A: "평가를 해야 에러분석이 가능하니까"
    B: "왜 에러분석을 해야 하는가?"

    A: "올바른 방향을 위한 방향성 확립 + 내 개인데이터만 쌓이면 편향적이니까 객관적인 데이터가 필요하니까"
    B: "왜 객관적인 데이터가 필요함?"

 

여기서 저는 질문에 대한 답변을 멈췄습니다. 우선 5번이 넘어가기도 했으며 질문이 단순히 제 근본적인 문제를 해결하고자 던진 질문이 아니라 그냥 장난 삼아 던진 질문이란 것을 느끼게 되었습니다.

어떤 질문을 받던 그 질문에 대한 의도를 파악하여 대답을 해야 되는데 경험상 단순히 묻는 질문에는 어떠한 건설적인 대화가 이어지지 않았습니다. 이 경험을 통해 저는 현명한 질문은 대화를 "연속적"으로 이끌 수 있는 본질적인 물음 이어야 한다고 생각했습니다. 자연어처리(Natural Language Processing; NLP)를 공부하면 사람의 발화를 Sequence라고 부를 때가 많습니다. 말 그대로 대화체 또는 Text는 연속적인 성질을 내재하고 있음을 알 수 있는데요, 그러기 위해선 같은 상황과 조건에서 대화하고 있음을 확인하는 질문을 던지는 질문이 우선된다고 느꼈습니다. "지난번에 시킨 건은 어떻게 되었나요?" 보단 "지난주에 부탁한 100건에 대한 데이터 형태소 분석결과는 어떻게 되었나요?"라는 구체적인 질문을 사용할 때 더 빠르고 효율적인 회의가 진행됐음을 느꼈습니다.



두 주제를 다루면서 저는 "구체적인 진단형(Diagnosis) 질문"을 하는 습관을 들이는 것이 앞으로 현문을 할 수 있는 방법의 하나라고 생각했습니다. 지금 어디까지 모르고 우리가 무엇을 이야기하는지에 대한 주제를 맞춰(Align) 연속적인 공간을 만들고 다음 진짜로 궁금한 질문을 구체적으로 묻는 것이 대화의 시작이 아닐까 싶습니다. 

아직은 3개월밖에 되지 않았기에 섣부른 생각일 수 있고 과대해석이 존재할 수 있습니다. 하지만 그만큼 물 경력이 되고 싶지 않은 부족한 신입이기 때문에 어떤 생각으로 프로젝트에 임했는지 기록하여 더 발전하고, 글을 공유하여 다른 분들의 경험을 받아들여 방향성을 잡고 싶습니다.

평소에 여러분은 어떻게 질문을 하시나요? 또는 질문에 의해 어려운 점은 없었나요?

 

728x90

2023년 회고

  1. 네이버 부스트캠프 졸업

사실 22년 9월부터 시작이였지만, 2월까지 진행되는 프로그램이기에 23년 첫 단추를 부트캠프원들과 함께했습니다. 1,2월은 파이널 프로젝트 수행을 주로 하면서 업스테이지와 DocVQA 과제를 무난히 끝낸 상반기였고 이후 폭풍같은 이력서 제출이 이어졌습니다. 돌이켜 보니 실력이 너무 없던 터라 같이 수행한 팀원들에게 더 기여할 수 있도록 도와줬어야 했는데 그러지 못하여 매우 아쉽긴 했습니다.

 

모쪼록 부스트캠프 수료는 상상을 구현할 수 있는 힘을 길러주었고 현재도 아이디어를 빠르게 구현하여 소소하지만 작은 결과라도 보여줄 수 있는 실력이 생긴건 부스트캠프 덕분이라고 매번 생각하게 되는 과정이였습니다. 하지만 성장한 개인의 성장과는 다르게 사회에서의 기준은 엄격했습니다. 번번히 서류를 탈락하며 끝끝내 얻은 면접기회도 매번 탈락하였습니다.

 

상반기의 서류 탈락은 27회에 면접 탈락은 8회 코딩테스트 탈락은 5회로 생각보다 많은 실패 경험을 겪었습니다. 이 때 저는 연구경험이 매우 부족하고 석사졸업이지만 논문 경험이 적었던 탓에 경쟁력이 없다고 생각하여 논문을 작성하는 경험을 갖고자 노력했습니다.

 

  1. EMNLP 2023 논문 참여

고맙게도 저와 같이 연구를 해보고자 했던 친구가 생겨 같이 합을 맞춰볼 수 있는 시간을 가지게 되었습니다. 6월 게재를 위해 3개월간 수많은 아이디어 변경과 보름의 작성기간을 가지고 시간을 정말 불태웠다고 말할 수 있었습니다. 하지만 연구의 세계는 단순히 흥미와 노력만으로는 의미가 없었습니다. 정말 그냥 잘해야합니다. 또한 논리가 탄탄해야하며 그 논리에 따른 실험 설계를 잘해야하고 설계에 따른 결과가 잘 나와야합니다. 같이 작성한 친구와 친구의 회사 팀장님의 도움 덕분에 가장 실력이 없었지만 연구 참여에 적극적으로 참여할 수 있었고 결과적으로 한 편의 깔끔한 논문이 생성되었습니다.

 

제출 결과는 사실 광탈 ^^ 입니다. reject의 메인사유는 영어 표현의 부족함이였습니다.

While the idea and direction were overall recognized as exciting and interesting, the soundness of the current paper should be improved


마이크로소프트와 Meta에서 보내준 리뷰였기에 떨어졌지만 매우 소중한 의견이였으며 영어 표현이나 논리적 표현에 대해 부족함을 느끼며 내가 하고싶은 실험을 위해 어떤 실험을 해야하는지도 계획적으로 세워야한다는 점을 크게 깨달았습니다.

 

 저는 역시 한번에 무언가를 성공한 경험이 없습니다. 이쯤되면 정말 지겹기도 하겠지만 저는 실패를 통해 배움이 더 크다고 생각하기로 햇습니다. 21년동안 회피하고 포기하며 살았는데 지금까지도 무언갈 쉽게 포기하며 살기엔 30살이라는 책임이 더욱 커진 것 같습니다. 사실 지금까지도 생각없었는데 회고를 하면서 24년에는 정말 한번 논문을 게재해보고 싶다는 목표가 생겼습니다. 이러한 이유 때문에 회고를 해야하는 이유가 생기는 것 같습니다.

 

8월부터 9월까지는 다시한번 저를 돌아보는 시간을 가지며 취업준비를 천천히 준비했습니다.

 

  1. 이번엔 다르다.. 서류합격률 100%!!

 이번 취업준비는 논문을 쓸 당시 논리적인 글쓰기와 어떤걸 표현해야하는지 깨달아서 그런지 이력서와 포트폴리오 작성이 손쉬웠습니다. (물론 paper works 경험이 제일 큰 한 몫 한 것 같습니다.) 제 이력서를 다시 보니 제가 하고싶은 말이 많았습니다. 누가 제 글을 볼진 모르겠지만, 23년 하반기 서류합격률 100% 달성하면서 느낀 건 "제가 말하고 싶은 바는 별로 중요하지 않습니다". 저를 흥미있게 볼 수 있도록 프로젝트 수행을 위해 제가 고민해온 결과를 작성해야 합니다. 이말은 즉슨, 단순히 프로젝트의 결과만 나열해서는 모든 사람들과 차별성이 없다는 뜻입니다.

 

 이력서는 정말 3분내로 갈림나기 때문에 자신이 해온 모든 것을 3분 스피치로 나타낼 수 있도록 잘 구성해야합니다. 여기서 이제 더 보여주고 싶고 내가 더 잘한 부분을 강조하고 싶은건 그제서야 나타나는 "포트폴리오"라는 친구에 모든 것을 기입하는 것입니다.

 

 그렇게 구성하고 나니 구글부캠( 하반기에 소셜네트워킹 삼아 Google ML Bootcamp 2023에 참여했습니다.)에서 이력서 컨펌에서도 매우 긍정적인 피드백이 와서 개인적으로 너무 만족스러운 취준기간을 보냈습니다. 물론 면접에서 탈락은 3회 겪었지만, 이 탈락 경험은 회고를 해보니 확실히 제가 못한 부분이 많아 보충하고 나니 면접 또한 합격률이 매우 높았습니다.

 

 덕분에 저는 NLP 연구원으로 한 스타트업에 재직중에 있으며 10월부터 일을 시작했기 때문에 저의 2023년의 회고는 여기서 마무리가 됩니다.

 

  1. 글을 쓰기 싫은 사나이..

저는 사실 기록에 익숙한 사람은 아닙니다. 2023년부터 작성하기 시작했는데 회고를 작성하기 시작한 이유는 24년에 목표를 세우려는 과정에서 23년엔 무엇을 목표했었는지 돌이켜봐야 더욱 현실성 있는 목표를 잡을 수 있다고 생각했기 때문입니다. 23년엔 정말 무리한 계획을 많이했습니다. 만다라트 기준으로 수행률이 30%정도 밖에 안되는 것 같습니다...

 

그중에서도 가장 맘에드는 성공사례는

  1. 꾸준히 운동하기
  2. 취업하기
  3. 이력서, 포트폴리오, 자소서 합격포맷 만들기
    입니다.

이 다음은 제가 일을하면서 의사전달과 발표를 너무 못하는 것을 알아서 ai 또는 논문 리딩 발표를 하여 제가 생각한 의사와 사람들이 이해하기 쉽도록 발표할 수 있는 능력을 동시에 기를까 생각합니다. 또한 2024 논문 한편 게재와 재미있게 운동하기 우선 3가지를 현실적으로 잡아볼까 합니다.

 

만다라트를 재작성하며 위 3가지를 실천하기 위해 서브 목표들을 설정하려고 했으나 아직은 계획적인게 불편한 나머지 너무 뒷전으로 던져버렸습니다.. 회사에서 맡고있는 프로젝트가 끝난 후 다시 한번 고려해보는 시간을 가질 것 같습니다.

 

아직도 저는 부족하지만 채울 수 있는 부분이 있다는 건 참 좋은일 아닐까요? 팀원들과 같이 지내면서 지금도 지키는 룰인 "세상에 멍청한 질문은 없다."가 지켜지기 위해선 답변자는 어떠한 질문도 멍청하지 않으니 성심성의껏 대답해 주는 것 입니다. 그 이유는 부족한 부분을 확인하기 위함이라고 생각했는데요, 제가 만약 이해할 때까지 설명이 가능하다면 저에게 부족한 부분이 아니라고 판단할 수 있을 것 입니다. 반대로 설명이 어려우면 저도 사실 모르는 것일수 있겠지요. 이걸 생각하며 저의 2024년도의 메인 신념은 남에게도 질문을 할 수 있지만 스스로에게 항상 질문을 하고 대답을 할 수 있는 내면의 견고함인 것 같습니다.

728x90

TL;DR

  • Chain of X 시리즈 중 Document를 보고 Multi-step Reasoning을 시도하였다.
  • CoD 방식은 정보 정확성이 낮은 문서와 모르는 질문에 대해서도 Robust하게 답변한다.
  • 리트리빙 이후 질문에 대한 passage 정제가 매우 필요해 보인다.

Intro

요즘 Retrieval-augmented language models (RALMs)들은 다음과 같은 문제가 있다.

  1. 관련 없는 데이터에 대한 검색을 할 경우 고유한 지식을 간과하여 질문과 관계없는 답변을 배출한다.
  2. 정보에 대한 평가가 이루어지지 않기 때문에 정확한 답변을 제공하기 위해 내재적 지식과 검색된 지식 모두에서 적절한 지식을 보유하고 있는지 평가하는 데 어려움을 겪는 경우가 많습니다.

따라서 우리는 정보를 제공할 수 없을 시, "제공할 수 없음"으로 배출하는 과정을 겪어야한다.

이러한 과정을 겪을 수 있도록 우리는 Chain-of-Noting(CoN)을 제안. 따라서 Noise와 관련성 없는 문서 확인 그리고 unknown 시나리오에 대해 Facing할 수 있도록 방법을 제안.

  1. Noise Robustness: The ability of a RALM to discern and disregard noisy information present in irrelevant retrieved documents, while appropriately leveraging its intrinsic knowledge.
  2. Unknown Robustness: The capacity of a RALM to acknowledge its limitations by responding with “unknown” when given a query it does not have the corresponding knowledge to answer, and the relevant information is not found within the retrieved documents.

따라서 평가를 3가지 방향으로 잡고 진행하는데, 데이터는 ODQA(TriviaQA), WebQ, RealTimeQA를 사용

  1. overall QA performance using DPR-retrieved documents
  2. noise robustness, assessed by introducing noisy information to the system
  3. unknown robustness, evaluated through queries not covered in the LLaMa-2 pre-training data, i.e., real-time questions.

Method

  1. Note Design
      1. Retrieved document(RD)에 정답에 대한 다이렉트 정보가 있는 경우
      2. RD에 정답에 대한 정보가 애매하게 있는 경우
      3. RD에 정답에 대한 정보가 아예 없거나 관련이 없는 경우3가지 format에 대한 데이터 생성

  • Data generate
    • ChatGPT를 활용하여 생성
    • NQ 에서 1만개 랜덤샘플링하여 지정 프롬프트를 사용하여 note 생성
  • Training
    • LLaMa-2 7B을 사용
    • 일반적인 Loss를 사용할 시 input size가 너무 길어 수렴이 안됌 => Weighted Loss on Notes and Answers전략을 사용
      • 시간을 기준으로 (?) 실제 정답 y에 대한 NTP수행 50%, 나머지 50%는 모든 document가 들어간 input에 대한 y의 NTP 수행

실험

Unknown성능을 제외하고 NQ, TriviaQA, WebQ 세가지 Benchmark dataset을 활용하여 측정, Unknown은 RealTimeQA를 사용한다.

그리곤 전체 QA에 대해서 한번, noise와 unknown에 대해서 한번 실험을 통해 결과를 보여준다.
noise와 unknown 측정 시, 관련 없는 문서를 추출하기 위해 노이즈의 비율을 r이라고 notation하자면
$k \cdot r$ 이 관련없는 문서의 비율이다. 이 갯수를 채울때 까지 iter돌려서 list로 받는다.

  1. QA 성능
    • NQ, TriviaQA, WebQ 3가지 task의 EM, F1스코어로 측정
  2. Noise 성능
    • 리트리빙 된 문서를 하나 제거한 후, 관련없는 top k 1개 문서와 완전 랜덤 wiki 문서 하나를 추가한 성능을 비교한다.
    • 노이즈가 많으면 할루시네이션이 엄청나다는 것을 알 수 있지만, CoN으로 학습된 모델은 비교적 덜 영향을 받는 것으로 보여진다.
    • ![[Pasted image 20231121142801.png]]

  1. Unknown 성능

728x90

실패할 용기

21살 대학교 1학년까지 어떤일이든 최선을 다해본적이 없었습니다. 어떤 일이든 잘하는 모습만 보여주고 싶었고 실패를 딛고 일어날 자신이 없었기 때문입니다. 그러니 자연스레 끈기라는 속성이 저에게는 전혀 찾아볼 수 없었습니다. 수리, 영어 1등급 맞고 성적을 유지할 자신이 없어 공부를 안해버리고, 미술을 배우다 어느정도 실력이 쌓이자 내가 못하는 기법을 배울때 쯤 그만두는 등 다양한 시도는 했지만 뭐하나 잘한다고 할 수 있는게 없었습니다. 그렇게 20년간 애매한 삶을 살다 애매한 대학을 가서 학교 적응에 실패하여 학사경고를 받고 군대에 들어가게 됩니다.

 

체대생 친구와 동반입대를 하고 군대라는 조직 특성상 끝까지 열심히 하지않으면 도태되기 때문에 친구와의 잦은 비교를 통해 자존감의 바닥을 보게 됩니다. 중도 포기를 할까 고민할 때쯤 평소라면 귓등으로도 안들었을 "누구나 하는 겁니다!"라는 말에 갑자기 발작했습니다(발작버튼 on). 좋은 모습만 보여주고 싶었던 내가 그 "누구나"도 안될 순 없었습니다. 적어도 평균은 하자는 생각에 군대에 있는 동안엔 "안해봤던 걸 하고 해왔던 것을 안 해보자"라는 도전 정신이 생기게 되었습니다. 먹기 싫던 아침도 꾸역꾸역 집어 넣고 하기 싫은 체력 단련도 누구보다 앞서서 달리고 훈련 같은 것도 항상 먼저 도전하였지만, 번번히 뒤쳐지고 실패를 많이 했습니다.

 

운이 좋게 이런 노력과 도전정신을 주변에서 알아주셔서 처음엔 폐급으로 낙인찍혀 있던 저를 선임들도 챙겨주시고, 타 소대 선임들도 알아주셔서 꼭 잘하고 성공하는 것만이 알아주는 건 아니구나 라는 생각을 가졌습니다. 그렇게 군대내에서 실패에 대한 적응을 완벽히 마친 후에 "앞으로 나가서 뭘 해야할까?"에 대한 오만가지 생각을 가지게 되었습니다.

 

주변을 둘러보며 워싱턴 대학, 서울대생 , 23살 자영업자, 영화감독 등 정말 다양한 분포의 사람들을 만나고 제 옆의 친구조차 체육이라는 하나의 분야에 열정을 쏟아 부은 사람이란걸 깨달았습니다. 제가 지금부터라도 열정을 쏟아부을 수 있는 것은 책을 읽는 것뿐이여서 "4차 산업혁명"이라는 책을 읽으며 AI에 관심을 갖게 되고 처음으로 공부를 하고싶다는 실패해도 괜찮다는 마음으로 5:00에 일어나 새벽연등으로 공부를 하여 수능을 준비하게 됩니다.

 

공부... 좋아하세요?


드라마 같이 성공할 것 같았던 제 진심이 담긴 수능은 보란듯이 실패로 돌아갔습니다. 사실 3년 그보다 더한 시간을 꾸준히 해온 사람들을 이기기란 쉽지 않았을지도 모릅니다. 하지만 공부하는 법을 터득했기 때문에 호기롭게 학점관리와 학교 생활을 열심히 하게되었습니다.

피지컬만 믿고 농구를 처음 접하던 강백호가 서태웅이라는 천재를 만났을 때 엄청난 한계를 깨닫지만 다시 마음을 잡고 농구를 시작해도 따라잡지 못한 엔딩 같았습니다. 하지만 자신만의 무기를 발견하고 그 노력을 기반으로 선발에 선 강백호처럼 저도 학술제를 참여하게 되면서 저만의 무기를 발견하게 됩니다.

 

저는 적용을 잘합니다. 시험에도 적용하는 문제가 나오지 않냐~ 라고 생각할 순 있지만 저는 실생활에서 정말 문제였던 점을 파악하여 다양하게 시도를 해보는 것을 잘합니다. 실제로 서브웨이가 막 생겼을 무렵 1:1 제조 프로세스로 생기는 대기열이 시간낭비라고 생각하여 앱을 만들어 주문은 앱으로 받게 하고 직원은 제조만 하게 되면 얼마나 개선이 될지 확인하는 프로젝트를 진행했습니다.

 

이 프로젝트를 하면서 커리큘럼에도 없는 공부를 하며 밤새 문제를 해결하고 있는 저를 발견할 수 있었습니다. 공부란 것이 처음으로 재밌었고 이렇게만 공부한다면 결과가 어떻든 남는 장사라고 생각했습니다. 기대에 보답하듯 보란듯이 대상을 수상하며 깨달은 것은 저는 현상에 적용하여 실제로 얼마나 효과가 있는지를 데이터로 확인하고 싶었던 것입니다!! 앞으로의 진로를 저는 현상에 대한 "연구"를 해야겠다고 결심했습니다.

 

어서와~ 연구는 처음이지?

낮은 학점과 지방권 대학 출신이었지만 정말 필요로 할 법한 3가지 연구주제를 내세운 연구계획서와 학술제 대상 프로젝트 포트폴리오 두 서류를 가지고 대학원에 입성하게 됩니다. 너무 운이 좋았습니다, 제가 교수였다 해도 절 뽑을 이유가 전혀 없었기 때문에 어떤 것을 하든 잠자는 시간이라도 줄여가며 노력할 준비가 되어있었습니다. 하지만 대학원은 엄청난 노오오오오오오력 가지고는 대화가 안통하는 공부계의 야생이였습니다.

 

논문을 읽을줄만 알았지 세미나를 통해 이 논문을 보고 어떤 문제점을 발견하고 접근이 왜 용이한지 질문을 하지 못하여 개인 연구에 대한 실마리를 찾을수가 없었습니다. 또한, 이론을 통해 실제로 적용해보기가 마음만큼 쉽지 않았습니다. 학부시절 프로젝트야 "응~ 발표만 하면 그만이야~"지만 성과를 내야하는 현실 문제는 끊임 없이 교수님을 납득시키고 피드백을 수용해야만 합니다. 이러한 과정으로 한발자국 성장할 수 있었지만, 2년이란 기간은 그렇게 길지 않았습니다.

다른 연구실은 논문도 여러번 게재하고 다양한 외부활동을 이어나갔지만, 저는 실력도 안되고 논문을 쓰기는 커녕 하루에 한편 읽기도 벅찼습니다. 하지만 오기로 공부를 시작한 저.... 실패에서 크게 배우자는 마인드로 머신러닝 공모전을 보이는 족족 참가하여 필사도 해보고 코드도 바꿔가며 무식하게 따라해보고 결과물에 대해 분석도 해보고 할 수 있었던 것은 다 해봤던 것 같습니다. 단기간동안 감을 찾기 위해 정말 평균 5시간 자면서 2년을 보냈습니다. (실제로 건강이 매우 나빠져 위궤양 판정도 받고 백신 부작용으로 응급실도 실려가면서 잔병치레를 다해봤던거 같습니다... 무식하게 공부하면 안된다는 것을 늦게 깨달았습니다..! ㅜㅜ)

 

그 결과 공모전 2회 수상과 졸업논문 작성으로 졸업까지 성공했지만, 솔직히 졸업논문의 퀄리티가 호기롭게 생각했던 연구의 수준까지 미치지 못해 매우 큰 아쉬움만 남기고 대학원 시절을 마무리 했습니다. 이때 저는 연구하는 방법과 논문을 작성하는법 그리고 자기를 객관적으로 판단하는 방법을 배웠던 것 같습니다. 그렇기에 매우 부족했던 CS와 Engineering 역량을 쌓기 위해 추가적인 공부를 할 수밖에 없다 판단하였습니다.

 

Adapt or Die!

적응하지 못하면 도태됩니다. 제목은 영화 "머니볼"에서 빌리빈 역할을 맡은 브래드 피트의 한 대사입니다. 찰스 다윈의 진화론에서 나온 어구를 3단어로 줄여 말해버리는 저 대담함에 지금도 마음에 남아있는 명언입니다. 빌리 빈은 엄청난 야구 유망주이지만 객관적이지 못하고 단 한번의 선택 실수로 야구 선수의 삶으로는 실패를 하게 됩니다. 하지만 그는 야구 구단장으로 적응하여 구단을 20연승이라는 업적을 달성시키는 엄청난 서사가 영화 머니볼에 담겨있습니다.

 

드래프트냐.. 장학금 스탠포드 대학교냐 고민했던 빌리 빈처럼 저는 여기서 제가 무엇을 하고 싶은지에 따라 부스트캠프를 다닐지 말지를 정해야하는 인생에서 2번째로 가장 고민되는 선택의 기로라고 생각했습니다. 문득 공부를 좋아하게 된 계기를 생각해보니 저는 AI를 하고 싶었었습니다..! 그 이유는 사람들의 평소 니즈(Data)를 기계가 자동으로 판별하여 편의를 제공해주는 혁신적인 기술이라는 설명에 감동을 얻었기 때문입니다. 따라서 모델을 개발하여 사람들의 data를 통해 편의를 제공해주는 개발자가 되고 싶은 마음에 꼭, Must 엔지니어링 역량을 강화해야한다고 판단했습니다.

 

그러기 위해선 빠르게 발전하고 연구되고 있는 AI 생태계에 적응하여 살아남아야만 했습니다. 하지만 현실은.. 취업준비, 코딩테스트 준비, 논문 읽기, 모델링, CS 지식 등등... 정말 할 것이 너무나도 많고 시간은 부족했습니다. 하지만 어쩌겠습니까... Adapt or Die.. 적응하기 위해 영화 머니볼에서 나온 방식처럼 부족한 부분만 우선 채워 승리로 가는 공식에 필요한 변수들만 고려했습니다.

 

제 기준에선 CS와 엔지니어링 역량이 가장 부족하다 생각하여 부스트캠프 AI Tech를 선택했기 떄문에 알고리즘 공부와 모델링을 위한 논문 리딩 후 구현하기를 루틴화 시키기로 하였습니다. 하지만 여느 컴공과 사람들이나 너무 세상에 똑똑한 사람들의 루틴대로 하루에 3-4개씩 코딩테스트 문제풀이와 논문을 읽을 순 없기에 3명의 주전 선수의 평균 출루율과 비슷한 저평가된 3명의 선수를 충원하듯, 저도 1일 1문은 풀되 다른 사람의 문제 풀이 코드 리딩과 논문을 읽고 그치는 것이 아닌 논문을 읽고 저만의 생각과 문제점을 항상 생각하며 읽기 시작하였습니다.

 

물론 1일 1코테의 습관은 제대로 들이지 못했지만, 코드 리뷰하는 습관이 생겨 레퍼런스를 참고하여 저만의 코드를 작성하는데에 매우 적합해졌습니다. 덕분에 커리큘럼이 빡빡한 부스트캠프에서도 잘 적응할 수 있었습니다. 제가 습관들인 루틴의 진가는 너무나도 잘 발휘되면서 갖가지 디버깅을 빠른 시간내에 해결하여 팀원들과의 좋은 성적을 내고 원하는 지식을 쌓으며 성사리 수료하게 되었습니다.

 

부실한 기초공사..!

수료 이후 취뽀에 바로 성공할 것이라는 엄청난 기대와는 다르게 탈락의 쓴 맛을 너무나도 많이 보게 됩니다. 서류도 탈락해보고.. 코테도 탈락해보고.. 면접도 탈락해보고.. 준비를 그렇게 해봤지만 예상대로 흘러가지 않았습니다. 오히려 최악의 최악으로 30회 이상의 서류탈락을 맛보고 20회 이상의 면접 탈락을 맛보았습니다.

 

이쯤되면 이젠 더이상 스펙의 문제가 아니라 제 자신의 문제라고 생각했습니다. 하지만 어떤 걸 해야 해결할 수 있을지 어려웠습니다. 내부 문제이기 때문에 어떤 점이 부족한지 확인하기 어렵기 때문입니다. 그렇기 때문에 지금처럼 삶의 지도를 작성하고, 제가 공부했던 개념들을 다시 정립하는 시간을 갖도록 했습니다. 개념들을 하나씩 정리하다 보니 제가 단어에 익숙한 나머지 설명은 불가능하지만 알고있다고 착각을 했던 개념들이 존재했다는 것을 알았습니다. 기술 면접에서 추상적인 표현을 하며 설명을 하니 당연히 떨어질 수 밖에 없다는 생각이 들면서 아직은 준비가 되지 않았음을 인정하기 시작했습니다.

 

단어의 정의나 확실한 설명이 불가능하니 자연스레 제가 해왔던 프로젝트들에 대해서도 설명이 조금 난해하고 얼버무리는 경향을 찾아볼 수 있었습니다. 적응기에 너무 트랜디한 기술력을 따라가려고 하다보니 기초적인 부분이 매우 부실하여 결국 드러난다 생각하여 다시 한번 기초를 다지고 해왔던 것에 접목시켜 저만의 개념사전을 만들며 2023년 하반기를 준비했습니다.

마무리

이렇게 준비하다 보니 서류 합격률 100%를 달성하며 면접에서도 좋은 결과들이 많았고, 이제는 정말 준비가 되었고 어떤 기업에 들어갈지 고민을 할 수 있는 상황을 연출시킬 수 있었습니다. 이처럼 너무 빠르다고 좋은 것도 아니고 너무 느리다고 좋은 것도 아니며 제가 이 직군을 해야하는 이유에 대해서 매번 생각하고 다짐하며 공부해왔기 때문에 지치지 않고 해낼 수 있었다고 생각합니다.

 

글재주가 없어 회고를 한답시고 주저리주저리 쓸데없는 말을 너무 쓴 것 같지만 스스로 회고하며 정리하는 시간을 가질 수 있었음에 보람을 느끼며 기록과 동시에 블로깅을 하는 이유는 매번 초심을 잃지 않고 내가 어떻게 여기까지 성장할 수 있었음을 되새기는 시간을 가질 수 있도록 하기 위함입니다.

 

앞으로도 더 발전하여 언젠가 제가 만든 모델로 사람들이 편리함을 느끼고 리뷰를 통해 행복을 느낄 수 있는 날까지 최선을 다하고 싶습니다!

+ Recent posts