부스트캠프에는 특별한 세션이 존재한다.

 

쏘카에 계신 변성윤님께서 마스터로 계시는데, 변성윤 마스터님께서 해당 세션을 맡아 진행해주고 계신다.

 

부캠을 하면서 앓고 있던 고민을 익명(또는 실명)으로 작성하고 그 고민들을 바탕으로 해결할 수 있도록 대안책이나 의견을 말씀해주시고 그 외에도 필요한 정보들(이력서 작성이나 삶의 지도, API 등!)을 하나하나 알려주시기도 한다.

 

사실 이번주가 다섯 번의 두런두런 시간 중 네 번째 시간이었는데, 앞서 많은 이야기들을 남겨두고 네 번째 시간에서 언급된 "조급함"과 "신입"이라는 관점에서 나의 상황을 대입해 느낀 점을 적어보고자 한다.

 

이걸 보는 나와 비슷한 사람들에게 도움이 되었으면 좋겠다.

 

조급한 마음을 갖고 일을 진행하면 잘 될까?

질문을 보면 누구나 "No."라고 대답할 정도로 쉽게 말할 수 있을 것 같다.

 

쉬운 질문같아 보이지만 세상에 쉬운 질문도 이유 없이 만들어지지는 않았다.

 

대표적으로 사람은 시간이 촉박하다고 느끼거나 내 상황이 불안하다고 느낄 때 "조급함"을 느끼게 된다.

 

그렇다면 그 사람은 '아, 내가 지금 조급함에 사로잡혀 일을 제대로 진행하지 못하고 있는 것 같아. 조급함을 버려야겠어.' 라고 생각할까?

 

당연하게도 내 자신이 "조급함을 갖고 있다."라고 인식하지 못 할 것이다.

 

여기서 모든 일에 있어서 생각해야 할 것과 명심해야 할 것이 참 많은데 그 중 하나가 "조급함"이라고 생각한다.

 

'아, 나 이것도 해야하고 저것도 해야하는데 시간은 이만큼 뿐이야. 빨리 해야 해.'

 

'곧 졸업 시즌인데 다른 사람보다 스펙이 부족한 것 같아. 이번 방학때는 정신차리고 자격증 몇 개, 어학 몇 점, 인턴은 두 군데 이상, 주말에는 스터디도 하고 밤 12시 전에 잘 생각하지 말자.'

 

두 질문이 보이는 공통점을 알겠는가? 모두 '시간'과 '욕심'에서 비롯한 '조급함'이다.

 

결국에 다시 생각해보면 조급함을 초래하는 많은 원인 중 가장 사람들을 괴롭히는 원인은 '시간', '욕심', '계획'이라고 생각한다.

 

'일찍 계획세워서 준비했더라면..'

 

'아, 시간이 조금만 더 있었더라면..'

 

후회를 하기 전에 계획을 잘 세워야 하는 것이 첫째다.

 

그런데 문제가 있다.

 

프로젝트를 진행할 때는 당연하게도 "데드라인"이 존재하기 마련이다. (즉, 먼저 준비하기에는 한계가 있다.)

 

이런 경우 우리가 어떻게 해야할까?

 

그 답을 두런두런에서 찾을 수 있었다. (이 부분은 나를 포함한 많은 캠퍼분들이 이번 두런두런에서 얻을 수 있던 부분이 아닐까 생각한다.)

 

"취사선택"과 "우선순위"

 

한정된 시간 속에서 해야 할 것은 많다. 그럴 수밖에 없다.

 

한정된 시간 속에서 '아 나는 이것밖에 못했는데 왜 저사람은 이 짧은 시간안에 저만큼 할 수 있었을까?'하고 바라보게 되는 사람이 한 명은 꼭 있기 마련인데, 그 사람들은 항상 "우선순위"를 잘 정한 것 같았다.

 

이것도 해야하고 저것도 해야할 때, 갈팡질팡하거나 모두 동시에 진행하려고 하고, 너무 크게만 일을 보고 있다면 "우선순위"를 정해보는 것이 정말 큰 도움이 될 것 같다.

 

사실 이 우선순위를 정하고 진행하면 가장 처음에 하는 것들은 보통 기초가 되는 부분이나 뼈대가 되는 부분이기 때문에 당장에 눈에 보이는 성과가 없어서 불안할 수도 있을 것 같다. (내가 항상 그래왔다.)

 

그럼에도 불구하고 자신을 믿고 일의 우선순위를 정하여 차근차근히 진행한다면 시간이 주는 조급함을 조금이라도 해소할 수 있지 않을까 생각한다.

 

 

신입, 경력이 참 빵빵하군! 그런데, 이것은 왜 했나? 저것은 왜 선택했고? 이유를 알려줄 수 있겠나?

사실 이것은 내 현재 상황을 보는 것 같다.

 

내가 알기론 현재 부캠에서 내가 가장 어리다. (멘토님 말씀에 의하면 현재까지의 1기, 2기, 3기 중에서 가장 어리다고 하신 것을 보면 아마 부캠 역사 중 내가 제일 어린 것 같다.)

 

이 "어리다"라는 것이 장점으로 보일 수 있지만 단점이 꽤 명확하다.

 

다른 사람들은 이미 경력도 쌓아본 적이 있거나 경험이 풍부한 사람들이다.

 

그런 사람들은 똑같은 교육을 듣더라도 얻어가는 것이 더 많고 더 자세하게 공부하기 마련이다. (또한, 공부에 있어서 완급조절도 잘한다.)

 

반대로 나의 경우 교육을 듣더라도 이해가지 않는 부분이 등장하고 (특히 수식과 어려운 개념, 또는 영어..) 일단 받아들이고 프로젝트에서 써보는 경우도 많다.

 

그리고 '조금 어릴 때부터 다른 사람들보다 앞서기 위해서는 해볼 수 있는 경험을 많이 쌓아보아야 하고 스펙도 많이 잘 쌓아야 한다.'라는 생각을 갖고 있었는데 이 생각을 다시 해보게 되는 계기가 바로 변성윤 마스터님께서 말씀해주신 아래의 내용이다.

 

"신입의 경력은 화려할 필요가 없다. 하나의 프로젝트에서라도 왜 이것을 선택했고 적용했는지를 잘 설명할 수 있어야 한다."

 

집중할 포인트는 "왜 선택, 왜 적용, 어떻게 적용"이다.

 

이 부분이 앞서 내가 말했던 단점이 제대로 부각되고 내 생각이 조금 잘못되었음을 보여준다.

 

교육을 수강할 때 놓치거나 "받아들인"다면 "왜"라는 것을 생각하지 못하게 된다.

 

즉, 가르쳐줬으니 쓰는 것이고 성능이 잘나오니 쓰는 것이 된다.

 

면접관이 "00님, 이 모델을 왜쓰셨나요?"라고 묻는다면 "아, 그 모델 SOTA라서 썼어요."라고 대답할 수 있는가?

 

면접관이 "00님, 이 방법은 무슨 이유로 도입하셨나요?"라고 묻는다면 "그거요? 멘토님이 가르쳐주셔서 좋아보이는 것 같아 썼어요."라고 대답할 수 있는가?

 

안된다. 사실 안된다라는 표현보다 잘못되었다라는 표현이 어울릴 것 같다.

 

프로젝트를 설계함에 있어서 "단순히 좋아서", "알려줘서" 사용한다면 이는 잘못되었다.

 

당장에 Kaggle을 보아도 답이 보인다.

 

현재 Medical Segmentation 분야 대회가 있는데 공유된 Code들을 보면 paperswithcode에 성능이 잘나오는 모델들이 훨씬 많음에도 불구하고 mask r-cnn, unet, resnet 등이 빈번하게 사용된다.

 

"왜?"

 

대표적으로 "제한된 학습 시간"이라는 이유 한 가지가 있을 것이다.

 

즉, 모든 조건, 모든 변수를 고려하고 분석을 통하여 적합한 선택지를 추려놓고 실험을 통해서 결정해야 한다. (일반적으로)

 

이런 점에서 "자세하게"가 아닌 "무조건 많고 화려하게"가 정답이 아님을 보여준다.

 

 

다음으로 내 생각에 대해서 수정해보았다.

 

앞서 말했듯 내 생각은 '조금 어릴 때부터 다른 사람들보다 앞서기 위해서는 해볼 수 있는 경험을 많이 쌓아보아야 하고 스펙도 많이 잘 쌓아야 한다.'였다.

 

이 생각이 완전히 틀렸다는 것이 아니다. 핀트가 잘못되었다.

 

"경험을 많이 해보는 것" 당연히 중요하다.

 

"스펙도 많이 잘 쌓는 것" 당연히 좋다.

 

잘못된 것은 "다른 사람들보다 앞서기 위해서"라는 점과 "많이"라는 것이다.

 

일단 다른 사람들보다 앞서기 위해서 스펙을 쌓는다는 것은 미련한 짓이다.

 

앞서고자 스펙을 쌓는다면 단순히 "양"에 집중하게 될 것이고 그로 인해서 각각의 스펙을 쌓는 과정에서 내가 자세하게 들어갔다면 얻을 수 있는 것들을 모두 잃게 된다.

 

즉, 수정하자면 아래와 같다.

 

'나를 위해서라도, 내가 성장하고자 한다면 지금부터라도 해볼 수 있는 경험을 다양하게 해보고 얻을 수 있는 것들을 최대한 얻자.'

 

 

사실 위 내용이 두런두런 4회차에서 앞 부분만으로 얻은 내용이다.

 

앞서 말했던 것처럼 1회차부터 3회차에는 위와 같이 많은 사람들이 공통적으로 겪고 있는 고민들을 포함해서 삶의 지도 작성 팁, 이력서 작성 팁, 질문하는 방법, 직군 찾기 등 정말 큰 도움이 되는 내용들을 많이 공유해주셨다.

 

단순히 "딥러닝 공부"만 우선순위로 생각하는 것이 아니라 그 외 부수적인 요소부터 "Computer Science"에만 해당하는 것이 아니라 살면서 중요한 것들도 많이 얻을 수 있는 시간이 두런두런이라고 생각한다.

 

그래서 내가 가장 좋아하는 부스트캠프 세션도 마스터 클래스나 오피스 아워, 프로젝트, 강의 등이 아닌 두런두런인 것도 위와 같은 이유에서다.

 

 

내가 어떻게 살아왔는지 "삶의 지도"를 통해서 조금 더 내 삶을 돌아볼 수 있었고 앞으로 어떻게 나아가야 할지를 생각했으며,

 

내가 희망하는 "직군"을 어떻게 찾아야 할 지, 무엇이 있는지를 생각해보게 되었고

 

그 직군으로 일을 시작하기 위해서 내가 쌓아온 경력들을 어떻게 "이력서"에 잘 녹여낼 수 있는지를 배웠으며

 

지금 배울 때뿐만 아니라 회사에 들어가서도 어떻게 "질문"해야 하는지를 터득하였고

 

회사에서 프로젝트를 할 때 "프로젝트 매니징""아키텍처 설계"가 왜 필요한지도 배웠다.

 

그리고 절대 조급해하지 말자는 것도.

 

이것이 1회차부터 4회차까지 배운 내용이다.

 

꼭 상기하고 생각해보고 적용해보자.

 

큰 도움이 될 것이다.

import sys
input = sys.stdin.readline

S = input().strip()    # S 입력 (가능 여부 판독 문자)
T = input().strip()    # T 입력 (조건 문자)

while S != T and len(T) > 0:    # T와 S가 같지 않고 T의 길이가 0보다 큰 경우에만 진행
    if T[-1] == 'B':    # T의 마지막 문자가 B일 경우
        T = T[::-1][1:]    # T를 뒤집고 처음 문자를 제외하여 T에 저장 (즉, 마지막 B를 제거한 역순)
    else:    # T의 마지막 문자가 A일 경우
        T = T[::-1][1:][::-1]    # T를 뒤집고 처음 문자를 제외한 후 다시 뒤집어 T에 저장 (즉, 마지막 A만 제거함)
print(1 if S == T else 0)    # S와 T가 같은 경우 1을 출력하고 같지 않을 경우 0을 출력

S부터 시작하지 않은 이유는 S 뒤에 A가 와야할지 B가 와야할지 모르기 때문이다.

반대로 역으로 보았을 때 T의 마지막 문자에 따라서 진행해주면 되기 때문에 T를 보고 해주면 된다.

 

다른 풀이들을 보니 list로 이용해서 푸는 풀이가 많던데 str를 이용하여 풀고 싶어 A에서는 돌리는 행위가 두 번 들어가 있다..

해당 부분이 불편하면 다른 메소드를 쓰면 되겠지만 왠지 시간초과가 발생할 수도 있을 것 같아서 그냥 두 번 돌렸다.

3월 3일 저녁 7시, 드디어 첫 프로젝트가 끝이 났다!

(글을 쓰기 시작한 것은 3월 6일인데 마무리 짓는 시기는 3월 23일이다. 많이 바쁘기도 했고 고민하면서 써서 그런가..)

 

Image Classification과 관련한 프로젝트였고, 마스크 착용 상태를 분류하는 Competition 형태였다.

 

부스트 캠프 내에서 회고에 쓰일 질문 문항을 7개 정도 사전에 제공해주어서 해당 문항을 포함한 내 개인 의견까지 포함하여 한 번 적어보려고 한다.

 

 

1. 이번 프로젝트에서 나의 목표는 무엇이었는가?

 

일단 나는 부스트캠프에 들어오기 전에 전문적인 교육을 받은 적도, 전문적인 프로젝트를 진행 해 본 적도 없었다.

 

AI 프로젝트도 작년에 동아리에서 KISIA 측에서 진행한 KUCIS 프로젝트에 참여할 수 있게 되어 Malware Classification라는 프로젝트를 해보았지만, 내가 참여할 수 있는 부분은 극히 드물었었다.

(왜냐면 이제 막 AI를 공부하려고 시작한 상황이었는데, 내가 프로젝트를 통해서 공부해보려고 했지만 실제적으로 이렇게까지 어려웠을 줄 몰랐고 또 도움을 줄 수 있는 부분도 극히 드물었었다.)

 

따라서 이번 프로젝트가 내가 참여하고 기여할 수 있는 첫 번째 프로젝트였다.

 

특히, 시간으로만 따지면 1주일 살짝 넘은 기간동안 진행하는 단기간 프로젝트라는 것도 처음 해보는 것이었다.

(적어도, 학교 팀플도 3주 정도는 시간이 주어졌었기 때문..)

 

그렇기에 나의 첫 목표는 "이번 프로젝트를 성공적으로 마무리 해보자."였다.

 

성공적이라는 것이 성능이 잘나오고, 단순히 프로젝트를 마치는 것이 아니라 성능이 잘 나오지 않을지언정 내가 직접 참여 해보고, 다른 팀원들도 포기하지 않고 끝까지 완주하는 것이었다.

 

이 목표는 성공적으로 달성이 되었다!

 

우리 조는 프로젝트를 이탈자 없이, 중간 포기 없이 성공적으로 완주하였고, 우수한 순위권은 아니었지만 나도 직접 참여해보고 노력해보았다.

 

그 다음으로의 목표가 "어느정도 나 혼자서 개인 프로젝트를 할 수 있을 정도로 실력을 끌어 올려보고 이번 경험을 통해서 어느정도 프로젝트의 틀을 잡아가자"였다.

 

앞서 말한 것처럼, 나는 이런 전문적인 프로젝트가 처음이기 때문에 프로젝트의 틀이 많이 잡히지 않아있었다.

 

이번 프로젝트를 통해서 전반적으로 "아, 전문적으로 진행하는 프로젝트는 이렇게 짜이는구나"라는 틀을 잡아가고, 프로젝트를 통해서 내 실력을 성장시키는 것도 하나의 목표였다.

 

개인적으로 이 목표는 달성하지 못한 것 같다.

 

일단, 프로젝트를 통해서 내가 스스로 개인 프로젝트를 할 수 있을 정도로 실력을 쌓기에는 너무 짧은 시간이었고 너무 안일한 생각이었다.

 

프로젝트 한 번을 통해서 내가 스스로 개인 프로젝트를 할 수 있을 것이라는 생각 자체가 애초에 잘못 되었던 것 같다..

 

또한, 프로젝트의 틀 역시 아직 완벽하게 짜이지 않았다.

 

우리 조는 github보다는 notion을 통해서 협업이 주로 진행되었다는 점에서 약간 아쉬움이 남는데, 실제로 멘토님께서 notion과 github를 같이 이용하는 것이 좋다고도 하셨었고, github로는 단순히 코드 공유 정도로 그쳤기 때문이다.

 

따라서 다음 프로젝트에서는 github를 조금 더 세부적으로, 다각적으로 사용하여 프로젝트의 틀을 만들어 놓고 싶다!

 

사실 그 다음의 목표들은 부차적인 목표들이다.

 

"48개의 팀들 중 24위 안에는 들어보자.", "순위권도 한 번 들어가보자!" 이런 순위 관련 부차적인 목표였는데, 사실 이는 희망사항일 뿐, 우선 순위의 목표들은 아니었다.

 

 

2. 나는 내 학습 목표를 달성하기 위해 무엇을 어떻게 했는가?

 

일단, 프로젝트가 시작하고 EDA를 진행해 보았다.

 

EDA를 시작하면서, 어떻게 EDA를 시작해야 하는지 감조차 잡히지 않았고, EDA를 시작하여도 "내가 pandas나 matplotlib, seaborn을 아직 잘 다루고 있지 못하는 구나"라는 생각도 들었다.

 

그렇기에 EDA를 해보았음에도 불구하고, 내가 알아보고 싶은 가장 중요한 정보는 직접 손으로 적어가며 정보를 얻어내었었다.

 

따라서, 다음 프로젝트를 진행하기 전에 EDA를 조금 더 확실하게 연습해 둘 필요가 있을 것 같다.

 

EDA 이후에는 모델 선정을 시도해보았지만 (Resnet18) 코딩 구현 능력이 부족하여 실패하였고, 다른 캠퍼 분이 올려주신 Resnet18을 시도해보았지만 같은 조 캠퍼 분이 Efficientnet-b0와 Resnet18을 비교하여 성능을 내어서 이 부분은 더이상 진행하지 않았다.

 

이 역시, 다음 프로젝트부터 끝날 때까지 (어쩌면 끝나고 나서도) 계속 연습해야 할 부분이 아닐까 생각한다.

 

아무리 데이터가 중요하더라도 모델을 쓸 줄 모르면... 말짱 도루묵이 되기 때문에...

 

이후에는 Data Augmentation을 진행했다!

 

이 부분을 정말 집중적으로 실험했다.

 

처음에는 단순히 baseline code에서 augmentation이 회전이나 뒤집기만 적용이 되어있어서 "RGB변형과 같은 색조 변형, 윤곽선 강조처럼 직접적인 변형은 효과가 없을까?"라는 생각으로 진행하였다.

 

이러한 생각을 바탕으로 albumentations라는 augmentation 툴을 사용하는 방법을 숙지하고, albumentations 공식 문서를 참고하여 augmentation을 해 보았다.

 

얼마 지나지 않아 우리 조 다른 캠퍼 분들이 진행한 실험 결과들을 바탕으로 60세 이상 label에 대해 분류하는 정확도가 낮다는 문제점을 파악했고, 이 점을 해결하기 위해 augmentation 기능들의 특성을 보고 해당 label을 더 잘 분류할 수 있을만한 기능을 선택하여 진행해 보았다.

 

결과적으로는 해당 실험들이 큰 성능 향상을 이루지는 못하였지만, 내가 직접 문제점을 파악하고 실험한 점에서 크게 자신감을 얻었던 것 같다.

 

Augmentation이 끝난 이후, 오피스 아워에서 언급된 Auto-ML을 이용한 Hyper-parameter Tuning을 직접 우리 코드에 적용해보고 싶다는 생각이 들었고, 이를 직접 적용하고자 시도했다.

 

다양한 에러와 해결 방법이 구글링을 통해서도 안뜨는 에러가 생겨서 많이 삽질했는데, 결과적으로는 성공하게 되어서 너무 너무 기뻤던 기억이 남는다.ㅋㅋㅋ

 

마지막에 우리 조 다른 캠퍼분이 작성해 준 하드보팅 Ensemble을 적용해 보았고, last dance 느낌으로 기존의 학습 방법인 Supervised Learning을 Semi-Supervised Learning으로 변환하려는 시도를 해 보았다.

 

처음에는 Pseudo Labeling을 적용해 보려 하였으나 Pseudo Labeling의 단점 중 하나인 "teacher가 잘못 편향되어 학습이 일어난 경우 student도 잘못 편향되어 학습이 일어난다"는 점이 현재 우리의 60세 이상 label에 동일하게 문제점으로 작용할 것이라고 생각되어 다른 방법을 고안했다.

 

Pseudo Labeling의 단점을 보완한 Meta Pseudo Labels를 시도해보려고 하였으나 자료도 부족하였고 시간도 부족하였고 (프로젝트 마무리 당일 날 생각 해 본 내용) 또한 github에서 코드를 긁어와서 변형해보려고 하였지만 능력도 부족하여 결국에는 해보지 못했다.

 

 

3. 나는 어떤 방식으로 모델을 개선했는가?

 

학습에 평가되는 방법이 f1 score였기 때문에 accuracy에 집중하는 것이 아니라 f1 score에 집중하였다.

 

따라서 모든 시도가 f1 score를 근거로 평가되었으며 내가 주로 했던 Augmentation 역시 마찬가지였다.

 

특히 가장 문제가 되었던 60세 이상 label을 집중적으로 공략하려고 FaceNet 등을 도입하여 진행해보았으나 효과가 미미하였었다.

 

시도한 내용을 정리해보면 크게 Augmentation, Auto-ML, Learning 방법 변환 (Supervised -> Semi-Supervised) 시도를 해본 것 같다.

 

 

4. 내가 한 행동의 결과로 어떤 지점을 달성하고, 어떠한 깨달음을 얻었는가?

 

내가 프로젝트에서 한 행동들은 "main"이 되는 행동이라기 보다는 조금 "보조" 해주는 행동들을 많이 한 것 같다.

 

데이터를 상세 분석하여 유의미한 결과를 도출하거나, 모델 선정에 있어서 최적의 모델을 찾아내거나, 앙상블을 진행하여 성능을 끌어올리는 행동은 하지 않았던 것 같고 주로 데이터 Augmentation을 통해서 성능 향상을 보이는지와 Hyper-parameter Tuning을 통해서 가장 나은 Optimizer와 Loss를 구하는 행동들 말이다.

 

따라서 내가 생각하기에 이번 프로젝트를 통해서 "시작 선"을 넘었다고 생각한다. 그것도 한 걸음 크게.

 

앞서도 말했다시피 기존에 해봤던 프로젝트는 Malware Classification이었고 전문성도 떨어지고 내가 아는 것이 없었기에 보고 어떻게 하는 것인지 느끼는 정도였다면 이번 프로젝트를 통해서 전반적인 프로젝트의 큰 틀, 협업의 큰 틀, AI Develop에서의 시작을 보고 해보면서 배우지 않았나 생각이 든다.

 

또한 이로써 현재의 내 정확한 실력을 판가름 할 수 있는 지표를 얻었다고 생각하고, 내가 직접 시도하고 성공한 Data Augmentation, Auto-ML with NNI에 대해서는 어느정도 자신감을 얻었다고 생각한다. (여기서 말한 성공은 유의미한 결과 도출이 아니라 아무것도 알지 못하는 상태에서 직접 필요성을 느껴서 library를 불러와서 코드를 직접 짜보고 에러를 고쳐내고 실험해보는 작업을 말한다.)

 

깨달음이라 하면.. 일단 데이터의 중요성에 대해서 크게 느낀 것 같다.

 

데이터에 잔 오류가 많았고, imbalance한 문제가 정말 컸기 때문에 데이터가 얼마나 잘 정돈되어 있고 품질도 좋고 양도 어느정도 확보되어있는지가 가장 중요한 부분이라고 느꼈다.

 

물론, 실제로는 그렇지 않은 데이터가 다반사기에 어쩔 수 없는 부분인 것 같기도 하다.

 

 

5. 전과 비교해서, 내가 새롭게 시도한 변화는 무엇이고, 어떤 효과가 있었는가?

 

사실 "전"이라는 것이 나한테 존재하지 않았어서 모든 것이 다 새로웠다.

 

"나 자신에 대한 변화"라면 내가 모든 것을 해야만 한다고 생각하지 않고 일단은 내가 그나마 잘할 수 있는 것이 무엇인지를 찾아가며 필요한 것들을 도움이 될 수 있도록 시도해 본 점인 것 같다.

 

이 덕에 딥러닝 프로젝트의 구성 요소 하나하나를 알아가고 초반부를 어느정도 정복해 나가는 느낌을 받았다.

 

또한, 부스트캠프가 마무리 될 즈음에는 나 스스로가 하나의 프로젝트를 만들 수 있을 정도의 실력을 쌓을 수 있을 것 같다는 느낌도 들었다.

 

다만, 모델을 직접 짜보는 부분이 여전히 어려워서 이 부분은 어떻게든 연습을 해야할 것 같다. (데이터 시각화도 마찬가지)

 

 

6. 마주한 한계는 무엇이며, 아쉬웠던 점은 무엇인가?

 

가장 먼저, EDA에 대한 부족이 떠오른다.

 

Matplotlib이나 Seaborn library 수업에서 조금 가벼이 하고 넘어간 것이 아마 화근이 되지 않았나 싶다.

 

또한 모델링 부분도 부족한 것 같다.

 

바로 위에서 말했었지만 모델을 직접 짜보는 부분이 너무 어렵기도 하고 아직 전반적으로 어떤 코드가 어떤 위치에 필요한지를 이해하지 못하여서 더더욱이 직접 짜보는 것이 어렵다.

 

마지막으로 코드에 대한 이해가 부족하다는 점이다.

 

Semi-Supervised Learning 기법(VAT와 MPL)을 우리 코드에 적용시켜보고자 github 등에서 코드를 찾고 입맛에 맞게 변형시켜보려고 하였으나 나의 코드 작성 능력과 이해 능력이 아직 현저하게 부족하다는 점을 크게 느꼈다.

 

아쉬웠던 점이라면.. 내가 시도해 본 결과들이 유의미한 결과를 내지 못했다는 점과 다른 상위권 조들의 방법을 들었을 때 우리가 했던 방법들과 비슷했던 것 같은데 그러한 생각들을 해보지 못한 점이 정말 아쉬웠다.

 

또한 내 개인 f1 score를 0.7을 넘겨보지 못한 점 또한 아쉽다. (팀 f1 score는 0.73이었지만 내가 제출한 것 중 가장 잘 나온 f1 score는 0.68이었다.)

 

끝으로 Github를 통한 협업과 WandB/MLFlow 등의 협업을 제대로 해보지 못한 것이 아쉽다.

 

우리 조의 경우 Notion을 통한 협업은 정말 잘되었으나 Github는 단순 코드 공유 정도, WandB나 MLFlow는 시도해보지 않아서 이 부분이 조금 아쉬웠던 것 같다.

 

 

7. 한계/교훈을 바탕으로 다음 P-Stage에서 스스로 새롭게 시도해볼 것은 무엇일까?

 

앞으로의 P-Stage에서도 내가 처음 들어보는 기술들을 적용시켜야 할 때가 올 것이다. (당장에 이 말을 적고 있는 23일 지금, Object Detection 프로젝트가 시작하였는데 Object Detection 자체가 내가 처음 들어보는 기술들로 가득하다.)

 

이번에는 실력적인 부분에서도 미흡했고 시간도 부족하여 적용해 보지 못하였지만 다음 기회가 온다면 한 번 붙잡고 늘어져보는 것도 좋은 방법이라고 생각하여 시도해보고 싶다.

 

또한 직접 모델링(일단은 pre-trained model을 불러와 우리의 입맛에 맞게 fine-tuning하고 갖가지 코드들을 조금 더 덧붙이는)을 성공해보고 싶다.

 

아! Notion을 통한 협업뿐만 아니라 Notion + Github + MLFlow 세 가지를 모두 아우르는 협업도 해보고 싶다.

이번에도 ASCII를 다루는 문제였다.

 

주의할 점은 대문자를 13 뒤로 미뤘을 때 소문자로 가는 부분까지 처리해주어야 한다는 점이다.

 

해당 부분만 주의해서 처리해주면 쉽게 풀 수 있는 문제였다!

 

sentence = input()
answer = ''    # 정답 문자 출력

for ch in sentence:    # 각 문자별 반복
    if not ch.isalpha():    # 알파벳이 아닐경우 그대로 출력
        answer += ch
        continue
    new = chr(ord(ch) + 13)
    if ch.isupper():    # 대문자인 경우
        if ord(new) > ord('Z'):    # Z보다 ASCII 값이 크다면
            new = chr(ord(new) - 26)    # 26만큼 빼서 대문자 알파벳 범위내로 조정
        answer += new    # 정답에 해당 문자 추가
        continue
    new = chr(ord(ch) + 13)    # 소문자인 경우 13만큼 뒤로 미룸
    if not new.isalpha():    # 뒤로 미룬 값이 알파벳이 아니라면
        new = chr(ord(new) - 26)    # 아스키 코드 값에 의해 26만큼 당겨서 알파벳 범위내로 조정
    answer += new    # 정답에 해당 문자 추가

print(answer)    # 정답 출력

Python에서 find 내장함수를 사용하면 쉽게 해결할 수 있습니다.

 

문제 자체가 find의 사용을 요구하는 것처럼 보였는데, 실제로 find에서 단어가 존재하지 않으면 -1을 출력합니다.

 

따라서, find를 이용하면 쉽게 해결할 수 있는 문제였습니다! (+ Python에서의 ASCII 사용법인 chr과 ord도 사용해야 합니다.)

 

import sys
input = sys.stdin.readline

answer = []    # 정답을 저장할 리스트 생성
word = input().strip()    # 단어 입력

for i in range(ord('a'), ord('z')+1):    # a부터 z까지 반복
    answer.append(word.find(chr(i)))    # 알파벳의 위치를 단어에서 찾고 정답에 추가 (없을 경우 -1이 자동 추가)

print(*answer)    # 정답 출력

 

파이썬에서 ASCII 코드를 사용하는 방법은 간단하다.

 

문자를 숫자로 바꾸는 경우 ord()를 사용하는데 해당 함수를 사용하면 된다.

 

(숫자를 문자로 바꾸는 방법은 chr())

import sys
input = sys.stdin.readline

S = input().strip()    # 단어 입력
answer = [0] * 26    # count할 리스트 생성

for ch in S:
    answer[ord(ch)-97] += 1 

print(*answer)    # 정답 출력

지난 번에 GCD 합 문제를 풀면서 Fraction을 이용한 적이 있는데, 해당 library를 이용하면 쉽게 풀 수 있다!

 

사실, 해당 library 안 써도 쉽게 풀 수 있을 것 같기는 하다..ㅋㅋㅋ

 

Fraction library는 두 수를 기약 분수 꼴로 나타내 준다.

 

문제는 기약 분수 꼴로 나타낼 때 완전히 정수로 나눠진다면 분모에 1이 남겨지지 않고 정수로 그대로 출력된다는 점이다.

 

따라서 완전히 정수로 나눠질 때 분모에 1을 추가해주는 작업을 따로 해주면 된다!

 

import sys
from fractions import Fraction    # 기약 분수로 나타내는 Python Library
input = sys.stdin.readline

N = int(input())    # 링의 개수를 입력
rings = list(map(int, input().strip().split(' ')))    # 링의 반지름들을 입력

for i in range(1, N):    # 첫 번째 링을 제외한 나머지 링들에 대해서 진행
    if rings[0] % rings[i] == 0:    # 두 수가 정수꼴로 나눠지면
        print(str(int(rings[0]/rings[i])) + '/' + '1')    # 분모가 1인 분수꼴로 표현
    else:    # 두 수가 정수꼴로 나눠지지 않는다면
        print(Fraction(rings[0], rings[i]))    # Fraction을 이용해 분수로 표현

바로 직전에 풀어보았던 GCD 합 문제처럼 combinations library를 이용하면 쉽게 풀 수 있는 문제였다.

 

from itertools import combinations    # 수학에서의 조합을 사용할 수 있게 해주는 library
import sys
input = sys.stdin.readline    # 시간 초과 error를 해결하기 위한 input함수 재정의

result = []    # 정답 저장

N = int(input())    # 수열 S의 크기
S = list(map(int, input().strip().split(' ')))    # 수열 S

for i in range(1, N+1):    # 수열 S의 크기만큼 반복
    for args in list(combinations(S, i)):    # 수열 S에서 i개를 꺼내어 조합
        result.append(sum(args))    # 조합으로 나온 수 i개를 합하여 나온 결과를 저장

result = set(sorted(result))    # 중복 제거를 위해 집합으로 변환

for i in range(1, max(result) + 2):    # 1부터 result의 결과보다 1 큰 수까지 반복
    if i not in result:    # 정수 i가 result에 존재하지 않을 경우 출력 후 마침
        print(i)
        break

 

combinations의 수학적 정의를 생각해보면, nCx에서 x가 n/2를 넘어가면 n-x로 바뀌는 경우 시간이 더 적게 소모된다.

 

해당 부분을 적용하면 시간적인 부분에서 더 감소하지 않을까 생각하여 다시 제출하였다.

 

from itertools import combinations    # 수학에서의 조합을 사용할 수 있게 해주는 library
import sys
input = sys.stdin.readline    # 시간 초과 error를 해결하기 위한 input함수 재정의

result = []    # 정답 저장

N = int(input())    # 수열 S의 크기
S = list(map(int, input().strip().split(' ')))    # 수열 S

for i in range(1, N+1):    # 수열 S의 크기만큼 반복
    if i > N/2:    # 현재 정수가 N/2보다 크다면
        for args in list(combinations(S, N-i)):    # 수열 S에서 N-i개를 꺼내어 조합
            result.append(sum(S) - sum(args))    # 조합으로 나온 수 i개를 합하여 나온 결과를 전체 수열의 합에 뺀 후 저장
    else:    # 현재 정수가 N/2보다 작다면
        for args in list(combinations(S, i)):    # 수열 S에서 i개를 꺼내어 조합
            result.append(sum(args))    # 조합으로 나온 수 i개를 합하여 나온 결과를 저장

result = set(sorted(result))    # 중복 제거를 위해 집합으로 변환

for i in range(1, max(result) + 2):    # 1부터 result의 결과보다 1 큰 수까지 반복
    if i not in result:    # 정수 i가 result에 존재하지 않을 경우 출력 후 마침
        print(i)
        break

 

 

+ Recent posts