AI 업무를 하다 보면 다양한 model들을 사용하게 될 것이다. 

사용자가 직접 model을 만들 수도 있지만, Google, Facebook 같은 기업이나 여러 대학들, 혹은 개인이나 단체에서 이미 만들고 실험을 한 좋은 model들이 많다. 이렇게 만들어진 유명한 model들을 따라가다 보면, 현재 AI 트렌드가 어떤 식으로 변하고 있는지, AI를 발달시키기 위해 대단하신 분들이 어떤 세련된 방법을 고안하셨는지도 공부할 수 있다.

 

현재 나는 Image Classification 관련 업무를 하고 있어서, NLP와 Face Detection 같은 분야의 유명 model들은 대충 '아~이 model 유명하지. 아~이거 들어봤어' 정도의 얕은 지식만 가지고 있다. 그래서 당분간은 Image Classification Model들만 간단히 리뷰를 하려고 한다.

 

Model Review를 할 수 있는 다양한 방법들이 많은 것 같다. paper를 직접 읽던, 구글링을 통해 model structure를 살펴보던, 유튜브에서 model review 영상을 보던... 하지만 이곳에 내가 정리를 하려는 이유는, 저런 방법들을 통해서 model review를 한 직후에는 '아! 이 model 이제 완벽히 이해했어' 생각이 들지만, 3일 지나면 다 까먹기 때문이다...('separable convolution이 xception에 쓰였던가 inception에 쓰였던가 둘 다 다 쓰였던가...? 하필 모델 이름은 헷갈리게 왜 이렇게 비슷한거')

 

그래서 나만의 방식으로 여기다가 리뷰를 해서 이해한 것을 기록하고, 기억하고 싶다.

Tree 문제를 해결할 때, 문제를 대충 확인한 후

 

첫번째 방법: 뭔가 이건 Iterative 혹은 BFS로 풀어야 할 것 같다 -> 거의 stack이나 queue에 node를 담아서 사용

두번째 방법: 뭔가 이건 Recursive 혹은 DFS로 풀어야 할 것 같다 -> 거의 그냥 함수를 Recursive 하게 사용

(물론 전부 다 이런 접근으로만 풀 수 있는 건 아니다)

 

좀 더 쉽고 자세히 설명을 해보면,

 

첫번째 방법에서는 for(auto n : Tree) 를 사용하여 순차적으로 child node를 불러오거나 저장할 수도 있고,

인덱스를 사용하여, 직접 i번째 child node에 접근 할 수도 있다.(특히 순차적으로 child node를 읽는 것이 아닌, reverse하게 읽거나 할 때 인덱스가 유용하게 쓰이는 것 같다)

마찬가지로, 미리 Tree의 각각 nth Level의 사이즈를 구해서 int size = queue.size() size를 요긴하게 사용하는 경우가 많다.

 

두번째 방법에서는(특히 Binary Tree에서 많이 쓰인다)

음...그냥 너무 어렵고 복잡하게 생각하지말자. 초반에 뭔가 Recursive하게 문제를 해결 하려 할 때, 너무 복잡하게 생각해서 시간만 날리고 스트레스만 받은 적이 많다.

(그 뭔가 머리속으로 직접 Recursive 하게 node를 타고 내려가다가 야바위를 보는 것처럼 핑핑 돌아버린적이 많다.)

그냥 단순하게 생각하자. 보통 함수를 myFunc(TreeNode* root) 형식으로 작성할 경우가 많을 텐데, 우선 해당 노드에서 해야할 작업을 생각해보자. 해당 노드에서는 해당 노드의 값, 한 level 밑의 child node 말고는 딱히 할 수 있는 작업이 없을 것이다. 또한 노드가 nullptr일 경우도 생각해야한다. 그러니까 저것들만 가지고 작업한다!

그리고 나서 그냥 myFunc(node->left), myFunc(node->right)를 함수로 넘겨버린다. 끝이다.

경험상, 첫번째 방법을 사용하면 아무래도 코드가 길어지고 복잡해지는 경우가 종종 있다.

그런데 두번째 방법을 사용했는데도 본인 코드가 길어지고 복잡하다면, 뭔가 문제가 있을 가능성이 크다

(머리속으로 recursive하게 야바위를 굴렸다는 뜻)

 

단지 큰 그림일 뿐이니, 문제를 보고 대충 어떤 방향으로 풀지 정할 때 만 사용하자.

+ Recent posts