지난 알고리즘 공부하기 Step1(뭘 공부해야 하지?)와 Step2(입출력 30문제 풀며 이해하기)에 이어서 Dynamic Programming 공부를 하려 한다.
[공부 방법]
- 지적 호기심이 충분한 사람이나, 도전정신이 강한 사람이라면 이론 공부 후에 바로 문제에 도전 할 수 있을 것이다. 하지만 개인적으로는 강의 영상을 통해 동적 프로그래밍이 무엇이고 어떤 예제들이 있는지, 예제들을 어떻게 접근해서 어떻게 구현(코딩)해 나가는지 몇가지 예시를 보고 깊게 학습하는 것이 흥미를 잃지 않고 '지속 가능한' 학습 방법으로는 좋은 것 같다. 나는 아래의 나동빈님의 영상을 통해 동적 프로그래밍이 무엇인지 감을 잡았다.
- 위의 영상 1번을 시청하고, 2번은 시청하면서 잠시 멈추고 스스로 문제를 풀어보고 풀이를 보고 이해하고 이런 방식으로 하면 좋은 것 같다.
.... 이렇게 나아가다 보면, 피보나치 (4), 피보나치(3), 피보나치(2), 피보나치(1)을 반복 계산하게 되고 이는 계산에 심각한 낭비를 가져온다. 예를들면 피보나치(50)을 계산하기 위해서 49,48를 계산하고 49를 위해서 48,47을 계산하는데 이는 트리구조로 아래로 내려갈 수록 2배의 계산이 필요하다. 총 피보나치(N)을 계산하기 위해 2^50을 계산해야 한다.
입출력 - DP - 기타 - bfs,dfs - binary search - 분할 정복 - 그리디 - 완전탐색 순서로 풀어 보려고 한다.
이번 주말에 풀었던 입출력 문제들은 다음과 같다. (boj.kr/2557 형태로 검색!) 약 30문제, 5시간 정도 걸린 것 같다. BOJ - 2557, 1000, 2558, 10950, 10951, 10952, 10953, 11021, 11022, 11718, 11719, 11720, 11721, 2741, 2742, 2739, 1924, 8393, 10818, 2438, 2439, 2440, 2441, 2442, 2445, 2522, 2446, 10991, 10992
시간 여유가 없으면 힘들겠지만, 주말에 몰아서 문제들을 풀다보니 확실히 하루에 긴 시간을 투자해서 공부하는 것이 짧게 여러번 공부하는 것 보다 학습 효율이 좋은 것 같다. 실수 했던 부분이나 배운 부분을 바로 다음 문제에 활용 가능해서 기억 -> 체화로 넘어갈 수 있는 것 같다.
또 더블 모니터를 활용하면 한쪽에 문제 한쪽에 코딩을 할 수 있어서 확실히 더 효율이 높은 것 같다.
프로세스와 스레드의 차이를 어렴풋이 알고 있었는데, 좀 더 자세히 정리하고 싶어서 글을 쓴다.
"프로세스와 스레드의 차이에 대해 설명해 주세요"
- 프로세스는 운영체제로 부터 자원을 할당 받는 작업의 단위이고, 스레드는 할당 받은 자원을 활용하는 실행의 단위 입니다. (참조글 인용)
그럼 위에서 말하는 할당 받는 자원은 무엇인가요?
- CPU 시간, 운영되기 위해 필요한 주소 공간, 독립 메모리 영역(Code, Data, Stack, Heap)
멀티 프로세싱과 멀티 스레딩의 차이는 무엇인가요?
- 멀티 프로세싱을 하게 되면 프로세스에 할당 해야 하는 자원의 양도 많아지고 자원 할당을 위한 시스템콜 이 많아져 , 하나의 프로세스에서 멀티 스레딩으로 구현하게 된다면 자원 할당도 효율적으로 처리 할 수 있으며, 하나의 자원을 여러 스레드가 활용해야 한다면 스레드간의 통신 비용이 프로세스간의 통신 비용보다 낮기 때문에 효율적입니다. 하지만, 그만큼 프로그래머의 주의를 요구합니다.
무슨 주의가 필요하고, 멀티 스레딩의 단점은 무엇인가요?
- 일단, 동기화 문제 때문에 디버깅이 까다롭습니다. 또한 하나의 스레드의 문제가 생기면 전체에 영향을 줍니다. 추가로, 하나의 자원을 공유할 때 병목 현상이 발생할 수 있습니다.
병목현상을 막기 위해선 어떻게 해야 할까요?
- 과도한 Lock의 사용을 자제하고, 적절한 범위의 Lock을 걸 수 있도록 해야 합니다.
스레드가 프로세스로 부터 할당 받는 자원은 무엇인가요?
- 같은 프로세스안의 여러 스레드들은 프로세스의 자원(code, data, stack, heap)중에 개별 Stack을 할당 받습니다. 나머지 영역은 다른 스레드와 공유합니다.
새로운개념이나분야를공부해나갈때처음으로해야할일은 ‘무엇을모르는지아는것’이다. 요즘같은영상시대에서주로사용하는방법은유튜브에잘정리된개요강의가있는지확인하는것이다. 10분이라는짧은시간동안자료구조가무엇인지 ~ 어떤자료구조들이있고왜있는지를알려주는좋은개요강의를찾아서요약해보려한다.아래의 80%는 해당 유튜브 영상을 참조하여 정리한 것이다.
Max Heap과 Min Heap이있는데, 말그대로 Max Heap은부모노드가항상자식노드의값보다큰특징을같고있으며Min Heap은반대의특성을갖는다.
Insert와 Delete 는 Upheap, Downheap으로부르며다음에구체적으로정리하겠다.
위의 내용으로 어느정도 전체적인 개요를 머릿속에 넣을 수 있었다. 자료구조들을직접코딩해서만들어야할까? 아니다이미각언어들에서만들어놓은구조들이있는데이게그유명한 C++의 STL(Standard Template Library) / Java의 Java Class Library등이다. 앞으로는 각각의 자료구조에 대해 구체적으로 공부하면서 내용을 정리 해야겠다.
몇개 안되는 정보(Noise Vector)를 통해서 원래의 이미지를 만들어 내려면 정보 추론이 필요한데 그것이 1) Contextual Information 과 2) Perceptual Information 이다.
1) Contextual Information : 추론하고 싶은 픽셀의 주변 픽셀을 통해 해당 픽셀의 값을 추론한다. 맥락적 정보.
2) Perceptual Information : 이미지가 현실적이기 위해선 해당 픽셀의 값이 어떻게 되어야 하는지 추론한다. 쉽게 말하면 '그럴듯 하게'이다. 이를 위해선 기존에 학습되어 있어야 한다. AI가 만든 고양이 사진을 우리가 이상하다고 생각하는 것은 이 인지적 정보를 통해서 파악하는 것이다. 인지적 정보
인간은 위의 두가지 정보를 쉽게 알 수 있지만, 어떻게 그걸 알아내고 있는지 알고리즘으로 표현할 방법이 없다. 아직까지는 이를 제일 잘 해내고 있는 것이 통계와 머신러닝을 활용하는 방법이다.
[ 코드 관점 ]
Noise Vector는 무엇일까? 어떤 기준으로 만드는 것일까?
Noise Vector는 관용적으로 변수 Z 에 생성, 저장하여 활용하는데 이는 단순하게 균등분포(Uniform Distribution)이나 정규분포(Normal Distribution)에서 무작위로 추출된 값이다. Z 벡터가 존재하는 공간을 잠재공간(Latent Space)라고도 한다.
- 임의로 결정하는 것이다. 하지만 Z의 값을 통해서 이를 이미지로 만드는 것이기 때문에, 이미지의 특성을 충분히 담을 수 있을 정도의 크기여야 한다. 위 코드에서는 100차원으로 잡았다.
2) 위에서 '충분한'을 어떻게 알 수 있고, Z벡터의 의미를 어떻게 받아들여야 하지?
- 알기 힘들다. 일반적인 GAN에서는 Z의 의미를 쉽게 이해하기 힘들고 이 부분을 보완한 변형된 GAN중 하나가 DC GAN이다. Z의 특정 성분이 이미지의 특징(예를들면 얼굴의 모양 계란형 / 동그란 얼굴 / 네모 얼굴)등을 담당할 텐데 기존 GAN에서는 해당 성분을 찾을 수 없었다면 DCGAN에서 해당 성분을 찾아낼 수 있도록 하였다.