MCTS
mcts는 몬테카를로 트리서치 트리 라는 이름이 붙은 것은 이렇게 가지를 쳐본다 이거에요 가지를 쳐봐 가지고 앞으로 상황이 어떻게 될지를 이제 이렇게 다 찾아가서 가보는 거죠
근데 이걸 다 가볼 순 없으니까 그래서 이제 트리서치라는 말이 이 트리를 찾아본다
이건데 이걸 모든 갈래를 다 가볼 순 없단 말이야
그러면 몇 개를 가보면 대략 우리가 평균적으로 어느 정도가 될지는 알 수 있겠죠
그래서 몬테카를로 이걸 처음부터 끝까지 쭉 따라가 보면 내가 예를 들어 이쪽으로 갔을 때와 이쪽으로 갔을 때에 각각 어떻게 될 거냐 이쪽으로 갔을 때 모든 걸 다 따라갈 순 없으니까 이 중에 그럴듯한 거를 몇 개 따라가 보면 뭐 한 100개를 따라가 보면 그 중에 90번이 이겼다
그러면 이거는 승률이 90%짜리 선택지고 이 끝까지 가면 100억 개가 있는데 100억 개를 다 안 가봐도 100개 가보니까 90개를 했다면 그 100억 개 중에서 우리가 90억 개 정도는 이기는 거겠죠
그런 가정이 있습니다
그 다음에 여기서도 마찬가지로 선택지가 1000억 개가 있는데 실제로는 1000억 개가 있는데 그 중에 10개만 따라가 보는 거예요
10가지 갈래만 따라가 보는 거예요
그랬더니 9번 이겼다 그러면 90% 정도 승률을 보인다는 거죠
그래서 우리가 이제 전책이 2개가 있는데 트리 정책이 있고 기본 정책이 있습니다
트리 정책은 언제 쓰는 거냐면 우리가 이 입장에 있을 때 이거를 따져볼까 저걸 따져볼까 지금 100번 따져봤고 10번 따져봤잖아요
끝까지 110번 해봤단 말이에요
우리가 200번 해볼 기회가 있어요
그러면 110번 했고 111번째는 이쪽으로 가볼까 이쪽으로 가볼까
그래서 그걸 결정하는 게 트리 정책이고 그건 UCB로 보통 한다고 했죠
그 다음 기본 정책은 자 이걸로 가보기로 했어요
여기서 한번 따라가보는 겁니다 따라가는 것을 기본 정책으로 합니다
그래서 알파고는 mcts는 바둑이라든가 이런 보드게임 같은 거 할 때 많이 했는데 보드게임만 하는 게 아니라 이제 어제 여러분들 토론하셨던 것들 중에 이런 걸로 할 수 있는 게 많이 있어요
뭐가 있을까요
우리가 공정 계획 같은 거 세울 때 공정 계획도 마찬가지잖아요
내가 a 공정을 먼저 할까
b 공정을 먼저 할까
고민이잖아요
그럼 실제로 한번 해보는 거죠
a 공정을 먼저 했다 치고 그럼 a 공정을 한 다음에 또 선택지가 있겠죠
b 를 한다 c 를 한다 d 를 한다
뭐 있으면 b 를 할 수도 있고 c 를 할 수도 있고 이렇게 해가지고 그럼 a 공정을 먼저 했을 때 우리가 어느 정도 이 전체 작업을 빨리 끝낼 수 있냐
b 공정을 했을 때 어느 정도 전체 작업을 빨리 끝낼 수 있냐
그거를 여러번 이렇게 트로 경우의 수를 다 따져보면은 우리 월드컵 할 때도 맨날 경우의 수를 따지잖아요
그렇게 하듯이 경우의 수를 따져보면은 데 모든 경우의 수를 다 따지는 건 불가능하니까 그중에 몇 개를 뽑아서 해본다 이런 거 그래서 그럴 때도 몬테카를로 트리서치를 쓸 수도 있고요 그 다음에 이제 어떤 재료가 이렇게 있는데 여기서 뭐 예를 들면 이렇게 생긴 판을 하나 뜯어내고 잘라내고 뭐 이렇게 생긴 거를 뜯어내고 어제 얘기하셨던 게 이제 이런 거죠
이걸 이제 배치를 해야 되는데 이것도 우리가 이제 여러 가지 방식으로 문제를 생각했을 때 하나는 순서대로 생각하는 거죠
보통 이렇게 있으면 일단 큰 거부터 한번 배치를 가운데 해놓고 그 다음에 좀 작은 거부터 이제 중간중간에 빈 공간에 이렇게 끼어넣으면 되겠죠
그럼
곧 큰 거를 이제 제일 먼저 큰 거를 놓을 건데 어디다 놓을까
이렇게 놓을까 이렇게 놓을까
뭐 이런 걸 이제 할 수 있겠죠
그래서 그거는 기본정책으로 놔요
어떻게 놓을까
근데 이제 하나를 놨으면 끝나는 게 아니라 그 다음에 이제 요걸 동그라미를 놓을까
세모를 놓을까
이제 그걸 선택을 해야 되잖아요
그러면은 이제 거기서 트리정책으로 동그라미로 놓는 경우에 또 그 다음으로 한번 다 놓아보는 거죠
끝까지 그 판내다가 다 한번 썰어 보는 거예요
처음부터 쭉 다 썰어 본 다음에 그러면 다 썰어 보면 이제 남는 뭐 낭비되는 재료 이런 것을 해볼 수 있잖아요
그러면은 이쪽으로 따라갔을 때 낭비되는 재료 이쪽으로 따라갔을 때 낭비되는 재료 이런 거를 이제 해가지고 어느 쪽으로 갔을 때 좀 더 낭비가 적을 가능성이 큰가
그거를 잘 해보면 되겠죠
그래서 트리정책이랑 이제 기본정책을 결합해서 구현을 하면 됩니다
알파고
그래서 강화학습을 지금 그냥 무작위로 초기화된 상태에서 강화학습을 시키잖아요
DQN 실습할 때 보면은 딱히 뭘 안해주고 그냥 바로 냅다 네가 시행차고 해라
이렇게 한단 말이에요
근데 이제 알파고에서 한 방법은 그렇게 하지 않고 일단 프로들이 둔 거를 지도학습을 시킨 다음에 그 다음에 강화학습을 시킵니다
이렇게 하면 장점이 뭐냐면 프로들이 그래도 바둑을 아주 못 두지는 않으니까 완전히 먼데서부터 시작해서 시행차고를 해가지고 정책이 여기까지 가는 게 아니라 어쨌든 프로들이 이 근처 어딘가에 있겠죠 그러니까 조금 더 학습을 빨리 할 수 있다
이런 아이디어예요
여러분들도 강화학습을 하실 때 좀 잘 안 되면 지도학습을 먼저 시킨 다음에 하실 수가 있습니다
예를 들면 우리가 배를 제어하는 아침에 하는 거 하면 처음에 이제 학습이 잘 안 되거든요
그러면 무작위로 하면 왜 학습이 안 되냐면 여기가 꼬리인데 얘가 이렇게 막 무작위로 움직이다가 어쩌다가 여기 닿아야 아 여기 가는 거구나
이걸 알아요
그러니까 이게 맵이 크면은 지도가 크면은 여기까지 무작위로 가서 닿기가 쉽지 않단 말이에요
그럼 어떻게 하냐면 일단 사람이 이 배를 몰아서 다양한 상황에서 어떤 궤적으로 배를 몰아서 가는지를 데이터를 만들어가지고 그걸로 궤적을 만들어서 일단 지도학습을 시킵니다
사람을 흉내 내게 그러면 강화학습을 시킬 때 좀 더 쉽겠죠
어쨌든 처음에 사람을 흉내 내다가 서서히 자기가 시행착오를 반복하면서 정책을 계산합니다
그래서 알파구에서 썼던 방식이 이 방식이고 그 다음에 이제 알파구 리이를 거쳐서 여기까지는 비슷하게 발전하는데 알파구 제로로 나갑니다
여기 원래 정책망하고 가치망이 분리가 돼 있었는데 정책망하고 가치망을 하나의 네트워크로 바꾸고 그 다음에 이제 점점 기술이 발전하면서 이 롤 아웃망이 따로 필요가 없어요
그래서 원래는 롤 아웃할 때는 가벼운 네트워크로 했는데 그냥 하나의 네트워크로 가치도 예측하고 정책도 결정하고 그 정책 결정하는 것으로 롤 아웃도 하고 이렇게 하게 됩니다
그 다음에 이제 알파 제로라고 해서 원래는 바둑만 둘 수 있었는데 그래서 이 알파구 제로에는 바둑에 특화된 여러 가지 몇 가지가 들어 있어요
근데 알파 제로에서는 바둑에 특화된 걸 다 빼버립니다
그래도 바둑을 잘 주더라 실제로 바둑 실력 자체는 알파구 제로가 알파 제로보다 더 잘 도요 특화된 모델이기 때문에 특화시키지 않아도 잘 된다는 걸 입증을 하게 되고요 이 알파 제로를 마지막으로 이게 다 구글 딥마인드에서 만든 건데 딥마인드는 알파구에서 손을 떼게 됩니다
바둑은 우리 이제 더 이상 연구할 게 없다
우리는 그 다음으로 가겠다
그래서 이제 뭐 요즘에 여러 가지 하는데 요즘에 유명한 거는 알파 폴드라고 있습니다
뭐냐면 단백질이 이렇게 우리가 A,T,C,G 뭐 이런 식으로 그 유전자 DNA가 있으면 얘가 이제 아미노산을 만들고 그 아미노산이 어떤 순서로 조합이 되면 얘네가 이렇게 그 자기네 애들끼리 인력하고 청력이 작용해서 얘네가 이렇게 가다가 갑자기 이렇게 팍 접히거든요
그래서 단백질이 접힌 모양에 따라서 단백질의 어떤 특성이 결정되는데 우리가 그걸 미리 예상하기가 되게 힘들어요
우리는 알 수 있는 게 뭐 A,T,C,G 이렇게 DNA 서열이 어떻게 되고 그 DNA에 따라서 아미노산이 스무 종이 나오는데 그 DNA가 어떻게 아미노산으로 번역되는지 정확하게 압니다
근데 그 아미노산이 어떤 시퀀스를 만들 때 걔네가 아미노산이 연결되면 단백질이 되거든요
어디서 접히고 어디가 펼쳐지는지를 예측을 못해요
물론 물리학적으로 시뮬레이션 하면 알 수 있는데 물리학적 시뮬레이션이 너무 어렵습니다
왜냐하면 아미노산이 한 두 개가 있는 게 아니잖아요
단백질 하나에 아미노산이 막 수십, 수백 개가 있단 말이에요
그럼 걔네끼리 서로 밀고 당기고 밀고 당기고 하면 우리가 그 삼체 문제 이런 거 하면 세 개만 돼도 예측하게 되게 힘든데 이건 다체 문제라서 멀티 바디 풀업을 해서 잘 안 풀린단 말이에요
근데 알파 폴드는 그거를 이제 딥러닝을 이용을 해가지고 단백질이 어떻게 접힐까
이런 걸 예측을 하는 거죠
그래서 만약에 우리가 단백질 모양이 어떻게 될지 알 수 있으면 신약 개발 같은 거 할 때 막 단백질이 되는 그런 약을 만들면 얘네가 어떤 성질을 결국 띄게 될지를 예측할 수 있습니다
실제로 시험을 해보지 않아도 정확하게 맞는 건 아닌데 정확하게 맞지 않더라도 우리가 후보물질의 범위를 굉장히 많이 줄일 수 있겠죠
그래서 딥마인드는 그런 거 연구하고 있고 요즘에 바둑은 접었어요
근데 이제 그럼 끝났냐 하면 그건 아니고 찾아보시면 그래서 이런 알파고 논문이 다 있으니까 논문을 보고 구현한 바둑 모델들이 굉장히 많이 있습니다
요즘에 프로 바둑 기사들은 바둑 선수를 바둑 기사라고 하는데 바둑 기사들은 집에 되게 좋은 고성능의 딥러닝 돌릴 수 있는 컴퓨터들을 다 한씩 가지고 있고 다 AI랑 바둑을 두면서 연습을 해요
그래서 요즘에 프로 바둑 기사들의 실력이 굉장히 상향편준화가 됐습니다
왜냐하면 옛날에는 그 옛날에 이제 여러분 이름 기억하실지
모르죠
이창호 구단이라고 있는데 이창호 구단이 바둑을 어떻게 배웠냐면 어렸을 때부터 조인원 구단이라고 당대 최고의 바둑 기사 집에 들어가서 10살 때인가?
되게 어렸을 때, 아기 때부터 그 집에서 완전 먹이고 재우고 씻기고 옷 입히고 다 했어요
근데 그래서 스승하고 집에서 같이 먹고 자고 하면서 바둑을 배워가지고 나중에 스승이 가지고 있던 타이틀을 다 뺐죠 호랑이 새끼를 키운 건데 옛날에는 되게 고수한테 배우지 않으면 바둑을 배울 방법이 없는데 지금은 AI가 바둑 어느 고수보다도 바둑을 잘 두니까 그냥 AI한테 배우면 됩니다
그리고 AI는 이수를 들면 승률이 몇 퍼센트까지인지도 알려주거든요
내가 잘못 들면 그거는 80%짜리 쓰고 여기다 두면 90%야
이런 거 알려주니까 공부가 엄청 되겠죠
그래서 바둑 기사들의 실력이 전반적으로 굉장히 많이 올라갔습니다
그래서 이제 알파고 같은 경우는 우리가 바둑의 실력을 평가할 때 엘로 평점이라는 걸 쓰는데 엘로라는 사람이 만든 방식이에요
그래서 여기 알파고 제로에서 트리서치를 하면 여기까지 되고 이게 어차피 정책만 가지고 하는 거니까 트리 탐색을 안 해봐도 기본 정책으로 보면 내가 어디다 두면 좋은지 알거든요
그래서 트리 탐색을 안 해도 수를 둘 수 있는데 트리 탐색을 안 하면 실력이 이 정도밖에 안 됩니다
트리 탐색을 하면 내가 최고의 실력을 가지고 있지만 그 실력으로 100번 1000번 도보 내린 결론이니까 더 정확하겠죠
실력이 더 오르는 거고 인간 최고수의 실력은 이 수준밖에 안 됩니다
그래서 엄청난 격차가 있죠
근데 이것도 지금 멈춰있는 게 아니라 계속 올라가고 있어요
알파고 제로는 이 정도 수준밖에 안 됩니다
그 뒤에 나온 카타고가 훨씬 더 잘 도요
그래서 끝도 없이 올라가고 있다
엘로 평점
이런 얘기고 그 다음 엘로 평점 얘기를 잠깐 드리면 엘로 평점은 사람 이름입니다
엘로가 약자 아니에요
엘로라는 사람이 만들어서 엘로인데 이 사람은 또 신기하게 물리학자에요 물리학자인데 이 사람은 체스 광이었거든요
체스 선수들 간의 실력을 어떻게 평가할까 하다가 이런 공식을 만들어요
그래서 s가 이기는 횟수고 e가 진 횟수인데 이 두 개를 차이를 한 다음에 여기다가 k를 곱해요
그 다음에 원래 평점이 있었는데 이 공식대로 평점을 수정을 하면 이걸 계속 수정을 하면 자기 실력으로 평점이 수렴한다
이런 얘기입니다
근데 여러분 이 공식 어디서 많이 본 거 같지 않으세요
m분의 1 한 다음에 r 빼기 v 이렇게 하면 v가 여기가 있죠
우리 같이 산정할 때 맨날 이 공식으로 하죠
그래서 엘로 평점 시스템을 쓰는 공식이 의도한 건 아닌데 강화학습에서 우리 같이 수정하는 시기랑 똑같습니다
그래서 몬테카를로로 하면 여기가 g가 돼 가지고 우리가 g를 많이 하면 결국 몬테카를로에서 이 업데이트하는 시기랑 똑같게 되는 거고 사실 생각해보면 논리가 똑같을 수밖에 없어요
엘로의 생각은 뭐냐면 평점이 높은 사람은 이기고 평점이 낮은 사람은 지는데 결국에는 많이 하다 보면 자기 평점 으로 수렴을 하게 된다
자기 승률이 있으니까 그리고 우리가 몬테카를로에서 같이 수정도 내가 확률은 잘 모르겠지만 하여간 많이 하면 내 가치로 수렴한다
이 얘기니까 사실 아이디어가 똑같거든요
그래서 서로 굉장히 다른 분야에서 굉장히 다른 백그라운드의 사람들이 똑같은 결론에 도달하게 됩니다
그래서 이제 이렇게 되고 그래서 엘로 평점 시스템에서 자기 점수를 알면 여기 앞에 있는 공식에다 넣으면 내 평점하고 상대방 평점을 여기다 넣고 계산하면 승률이 몇 퍼센트가 나올지를 알 수 있습니다
그래서 여기 보통 400으로 나누고 이렇게 하니까 한번 계산해 보시면 점수 차이가 이 정도 나버리면 거의 승률이 0이에요
사람 이길 수 없죠 사람은 절대 못 이긴다
이렇게 되고 그다음에 이거를 또 응용을 할 수 있는데 어떻게 응용할 수 있냐
문항 반응 이론
면 직접적으로 응용한 건 아닌데 이건 교육학에서 나온 문학 반응 이론이라는 게 있거든요
그래서 이것도 서로 다른 사람들이 다른 문제를 가지고 풀었는데 같은 결론에 도달한 건데 문학 반응 이론은 뭐냐면 학생들한테 시험 문제를 낼 때 자기 수준에 맞는 문제를 내자
이거 자기 수준에 맞는 문제를 내자는 건데 그러면 학생의 실력도 알아야 되고 문제의 수준도 알아야 되는 거죠
두 개를 알아야 그 학생 수준에 맞는 것을 알게 되겠죠
그래서 문학 반응 이론은 어떻게 생각하냐면 똑같습니다
이런 식으로 해가지고 내가 맞추면 이긴 거고 지면 틀린 거잖아요
그럼 그걸 반복을 하면 학생의 자기 실력으로 평점이 수렴하겠죠
근데 문제도 마찬가지로 문제를 내가 문제 입장에서 보면 학생이 틀리게 하면 그 문제가 학생을 이긴 거고 문제가 학생한테 맞춤 당하면 그 문제가 진 거예요
그럼 문제도 평점을 매길 수 있겠죠
서로 그렇게 굉장히 많은 학생이 굉장히 많은 문제를 내보면 결국 모든 문제가 자기 수준을 평점으로 가지게 됩니다
그리고 학생도 그걸 굉장히 많이 하면 자기 수준을 평점으로 가지게 돼요
그러면 자기 수준에 맞는 문제를 많이 내보면 사람도 그렇잖아요
자기 실력하고 비슷한 사람하고 겨뤄봐야 자기 실력을 파악할 수 있겠죠
너무 잘하는 사람하고 해보면 맨날 지니까 실력이 뭔지 알 수가 없어요
왜냐하면 조금 못해도 지고 많이 못해도 지고 그러니까 그냥 지기만 한단 말이에요
반대도 마찬가지고 여러분이 운동을 연습하는데 초등학생이랑 맨날 시합해보면 여러분 실력을 잘하는지 못하는지 알 수가 없어요 실력이 비슷한 사람끼리 겨뤄봐야 실력 평가가 됩니다
그래서 문학 반응 이론이라고 해가지고 문학 난이도를 이런 식으로 해서 딱 정확하게 학생 수준에 맞춰서 볼 수 있는 시스템이 있습니다
그래서 보면 강화학습, 엘로 평점, 문학 반응 이론 전부 다른 문제를 푸는데 결론이 똑같다
그래서 여러분들이 강화학습을 공부하시면 강화학습만 아는 게 아니라 다른 분야의 것들도 이렇게 아실 수 있는 거죠
이 얘기는 며칠 전에 한번 드리긴 했는데
근데 이 문학 반응 이론이 이론인 이유가 있어요 이론이 항상 현실에 안 맞는데 다 논리가 좋지만 잘 안 통하는데 특히 한국 사람들이나 중국 사람들 같이 항상 룰 브레킹을 좋아하는 우리 같은 사람들한테는 잘 안 맞습니다
왜냐하면 우리는 시험을 잘 보는데 너무나 특화되어 있기 때문에 그러면 초반에 내 평점을 좀 높여놔가지고 시스템을 속이면 내 능력을 실제 보다 더 높게 평가를 받을 수 있거든요
그래서 게임 같은 거 해보신 분들은 아시게 들어보셨을 텐데 버스 태워준다고 그러잖아요
이 용어 아시는 분 있나요?
롤 같은 데서 많이 하는 거 어떻게 하는 겁니까?
초반에 내 친구가 게임 대신 해가지고 아니면 게임 같이 해줘가지고 내 평점을 확 높여주면 내가 리그가 높아지니까 거기서는 좀 져도 별로 점수가 많이 안 떨어진단 말이에요
근데 초반에 내가 좀 못해서 이상한 리그 가 있으면 거기서 아무리 발버둥 쳐봤자 빠져나가기가 쉽지 않아요
그런 것도 약간 어르신이죠
그래서 룰을 속이는 건데 우리나라 사람들은 절대 자기 실력대로 시험 점수 받으려고 하지 않습니다
항상 자기 실력보다 높은 점수를 받는데 온갖 꼼수를 다 내기 때문에 문학 반응 이론이 한국에서는 별로 적용이 안 된다
그래서 실제로 컴퓨터 어댑티브 테스팅을 하는 경우가 거의 없고 언제 하냐면 수능 끝나면 교육 과정 평가원에서 사후적으로 이걸로 분석해가지고 수능 문제, 강 문제의 난이도를 분석을 해요
그래서 4점짜리가 실제로 어려웠냐 3점짜리가 실제로 적당했냐
뭐 그걸 이제 이런 식으로 평가하는 거죠
그래서 이런 걸로도 한다
이런 얘기고요 그다음에 우리가 실제로 실습을 해 볼 건데 mtsc는 mcts는 베이스 라인에 구현이 안 되기 때문에 직접 구현해야 됩니다
Tic-Tac-Toe
그래서 우리가 이제 이번에 볼 건 틱텍톤인데 틱텍톤은 우리말로 하면 삼목 정도 됩니다
오목은 다 아시죠?
오목하고 똑같은데 이렇게 보통 칸을 이렇게 놓고 동그라미하고 x하고 서로 번갈아 놓고 이렇게 한 줄이 되면 이기는 거예요
그래서 이제 우리가 틱텍토로 놓으면 어떻게 놔야 이길 가능성이 제일 높은가 이걸 하는 거고 아까 했던 공정계획은 우리가 메인 라인이 하나 있고 그 다음에 부재 만든 라인이 두 개가 있었죠
라인에다가 작업계획을 어떻게 배치를 해야 최단 시간에 작업을 마칠 수 있냐
이런 거를 하는 거죠
그러니까 결국에는 비슷한 문제입니다 놓는 판이 다르고 놓아야 되는 물건이 다른 거지 여기서 이제 동그라미랑 x를 놓는 거고 여기서는 작업 계획을 시간표에다 놓는 문제가 되는 거죠
그래서 그렇게 생각하시면 응용을 할 수 있다
이런 얘기고요 그래서 틱텍토를 놓아야 되는데 틱텍토를 구현을 해보면 1번은 x를 놓고 2번은 o를 놓고 이렇게 할 겁니다
그래서 먼저 틱텍토보드를 만들어 가지고 이 판에다가 놓을 건데요 그래서 함수를 몇 개 만들어야 돼요
그래서 Available Moves 이거는 지금 빈자리가 어딘지를 셉니다
그래서 여기 9개의 판 중에 빈자리가 어딨나 mt가 어딨나 우리가 아까 부품 놓는 걸로 하면 부품이 여기 하나 이미 들어가 있으면 여기는 못 넣잖아요
그럼 빈자리가 어디냐
이런 걸 찾아주는 게 필요하겠죠
아니면 이제 우리가 공정 계획 시간표를 짠다
여기랑 여기는 이미 배정이 끝났어요
여기만 빈자리가 있는 거죠
그래서 그런 걸 찾아주는 함수를 만드셔야 되고 그럼 이제 우리가 빈자리를 찾았으면 거기다가 놓을 수 있는 수가 뭐가 있느냐
이걸 찾아야겠죠
그래서 여기 이제 빈자리들 중에 하나씩 Make Move 해가지고 수를 두는 거고요 그 다음에 Random Move 함수는 그냥 비어 있는 거 중에 아무거나 하나 골라서 거기다가 수를 두는 겁니다
그 다음에 보상은 이기면 1점 지면 0점 무승부면 0.5점 이건 직관적이죠
이렇게 주면 되겠죠
아니면은 뭐 이기면 1점 지면 마이너스 1점 무승부면 0점 이렇게 주시면 됩니다
사실 큰 차이는 없고 어쨌든 그렇게 주시면 되고요 그 다음에 Make Move 하면은 인덱스 번째 자리에 덜하라고 하면은 셀프 점 튜브에 이렇게 표가 있거든요
그래서 0, 1, 2, 3, 4, 5, 6, 7, 8번까지 이렇게 있는데 예를 들어서 내가 4번 자리에 놓기로 했다
그럼 4번에 나의 표시를 이렇게 해주게 됩니다
그래서 다음 턴을 결정을 하고요 그리고 누가 이겼는지 판정을 해가지고 이긴 사람 없으면 그냥 넘어가는데 이긴 사람이 있으면은 이긴 사람이 있거나 아니면은 빈칸이 없으면 이제 끝납니다
무승부로 끝나든지 뭐 하든지 이렇게 되고 이제 이긴 사람 찾는 기준은 우리가 0, 1, 2 이렇게 한 줄이 되거나 3, 4, 5 이렇게 한 줄이 되거나 6, 7, 8 이렇게 한 줄이 되거나 아니면은 모든 경우에선 다 써놓은 거예요
대각선 이렇게 실제로 숫자 써놓고 보시면 이게 가로 세 줄인 경우 세로 세 줄인 경우 대각선 세 줄인 경우 이렇게 됩니다
그래서 1열로 만들었는지 판정을 해서 1열이면은 그 사람이 이긴 걸로 판정을 하는 거예요
그 다음에 이제 마지막은 이거 현재 화면을 예쁘게 출력을 해주는 기능을 합니다
그래서 이런 식으로 이제 틱탭토를 구성을 하시면 되고요 여러분들 문제에 맞게 이거를 구현을 하시면 돼요
비슷하게 구현하시면 됩니다
질문이 있었는데 여기서는 이제 이기거나 지거나 우승으로나 이렇게 되어있어요 부재 배치 같은 경우는 이제 아마 수율이 적어야 되는데 이거는 어떻게 하면 좋고 그렇죠
좋은 질문입니다
틱탭토리는 이제 이길 확률이 높은 데다가 둬야겠죠
그래서 이제 이거는 전체 100번 해서 90번 이기면 이길 확률이 90% 이렇게 되는데 약간 부재는 좀 다른 게 그 부재 놓는 거는 이건 약간 일종의 평균이잖아요
전체 100번 중에 90번 이기는 데 근데 그거는 어쨌든 최소값을 찾는 거죠
100번을 했는데 그 중에 한 번이라도 어쨌든 최소값이 있으면 되는 거잖아요
그럼
그런 경우는 이제 미니멈 기준으로 하시면 되겠죠
예를 들면 내가 이쪽 경로가 있고 이쪽 경로가 있는데 이쪽 경로로 갔을 때는 뭐 부재가 10% 남는 경우 5% 남는 경우 3% 남는 경우가 있었고 이쪽으로 갔을 때는 뭐 4% 4.1% 4.5% 이렇게 됐었다
그럼 평균적으로는 이쪽이 더 낮겠지만 미니멈으로 보면 이쪽이 더 낮았죠
그러면은 어쨌든 다음 번에 이제 어디로 갈 거냐면 이쪽이 그래도 더 가능성이 있겠죠
왜냐면 이쪽이 더 작은 게 있었으니까 잘 찾아보면 3% 밑도 있을 가능성이 있잖아요
근데 이쪽은 오른쪽은 보아하니까 4, 4.1, 4.5 이러니까 일단 해봐야 뭐 이 근처에 어디서 3.9 이런 게 나올 느낌이 좀 들죠 느낌상 근데 여기는 10도 나오고 3도 나오고 하니까 운이 좋으면 2도 나올 것 같고 나쁘면 15도 나올 것 같고 약간 그런 느낌이잖아요
그럼
이쪽에 한번 배팅을 해보는 게 좋겠죠
그래서 최소값을 찾는 경우에는 그런 식으로 생각을 하셔가지고 5% 남는 경우가 6.6% 아니죠
이건 승패를 가리는 게 아니고 어쨌든 그 남는 재료를 최소화 시키는 게 지금 하고 싶으신 거잖아요
그럼 남는 재료 양이 이제 처벌이 됩니다
내가 15% 만큼 재료를 남겼다
그럼 뭐 15점 10% 남겼다
10점 3% 남겼다
이렇게 하면 점수가 올라가잖아요
그래서 근데 이제 평균을 내시면 되고 미니멈 값으로 하셔야 된다
그렇게 됩니다
그래서 약간 UCB도 좀 바꾸셔야 돼요
UCB가 아니고 upper로 하시면 안 되고 그때는 LCB로 하셔야 되겠죠
lower로 하셔야 되는데 약간 그래서 이제 그렇게 되면 공식을 좀 바꾸셔야 되거든요
그래서 일단 여기가 더하기가 아니라 빼기가 되어야겠죠
그리고 여기를 평균 값으로 하시면 안 되고 가치가 보통 평균인데 최소값으로 하셔야 되겠죠
근데 수학적으로 그러면 맞았지는 모르겠는데 근데 적당히 하시면 될 거예요
보통 이게 약간 수학적으로 안 맞아도 대충 도라는 겁니다
그래서 그런 식으로 조금씩 응용을 하셔야 된다
그래서 이제 약간 이런 거는 서로 적대적인 나랑 너랑 목표가 다른 사람들끼리 서로 승부를 겨루는 거니까 나의 승리가 너의 패배고 이렇게 되지만 재료 배치하는 건 뭐 그런 건 없는 거죠
그냥 잘 배치하면 되는 거니까 또 질문 있으신가요?
Q. 한 번 이렇게 평가하는데 1초만 2초가 걸린다고 하면 결수가 엄청나게 많아지기 때문에 하루 이틀 걸려서 남기고 며칠만 걸려야 된다고 하면 그런 경우도 강화술을 사용할 수 있는 거예요?
Q. 최악의 경우 CFD의 결과가 나와야지
그걸 가지고 평가할 수 있다
아 시뮬레이터 한 번 돌리는데 시간이 너무 많이 걸려요
아 좋은 질문입니다
그래서 그런 경우에는 여러 가지 선택지가 있는데요
첫 번째는 시뮬레이터 자체가 오래 걸리는 거잖아요
시뮬레이터 돌리면 결과가 나오는데 이게 오래 걸려요
여기에 이제 시간이 오래 걸린다
그러면 이게 X고 결과가 Y인데 이거를 지도학습을 시키세요
그래서 지도학습을 시켜서 이걸 근사하는 거예요 정확한 시뮬레이션 결과는 아니지만 시뮬레이션 돌리면 대충 이쯤 나올 거에요 라고 딥러닝으로 근사를 하면 딥러닝 속도가 하여간 시뮬레이션 속도보다 빠르면 되는데 빠른 경우도 많이 있거든요
그래서 제가 유체역학 이런 쪽은 잘 모르지만 그런 거 시뮬레이션 되게 오래 걸리는데 실제로 얼마 전에 뉴스 보니까 저도 논문으로 본 건 아닌데 일기예보하는 거를 실제로 뉴럴리엣으로 하니까 슈퍼컴퓨터 돌리는 거랑 결과가 거의 비슷하게 나오더라
뭐 이런 얘기 있더라고요
그러니까 우리가 특히 강학습 할 때는 시뮬레이션에서 정책만 그러니까 우리가 좋은 정책을 찾기 위해서 가치를 꼭 정확하게 알아야 될 필요는 없거든요
왜냐하면은 가치 차이가 이렇게 돼도 A를 할 거고 AB가 있는데 A가 가치가 더 높잖아요
아니면은 A가 이거보다 높아도 할 거고 조금 낮아도 할 거고 그냥 B보다 높게만 나오면 됩니다
그러니까 이 지도학습으로 그 추정한 결과가 뭐 아주 부정확하지만 않으면 대략 우리가 할 수 있다
우리가 이제 교육이나 이런 것도 그런 일종의 시뮬레이션이잖아요
실제 현업에 가면 다른 이슈들이 다양하게 생기는데 그거랑 너무 차이만 안 나면 어쨌든 교육이 배운 게 효과가 있는 거죠 현업에 완전 반대라든가 이렇게도 말 아니면 돼요
이런 방법이 하나 있고 두 번째는 강학습을 하는데 MCTS를 이렇게 해요
그러면 한번 MCTS를 돌리면 자꾸 돌리면 우리가 많이 해보면 아 이 상황에서는 이쪽이 좋구나
이런 거를 알 수가 있잖아요
그럼 나중에 이거 자체를 데이터로 쌓아가지고 바로 이 데이터로 학습을 시키는 거에요
그래서 실제로 사용할 때는 MCTS를 안 돌리고 그냥 예전에 MCTS 할 때 보니까 이쪽이 이겼더라 라는 거를 학습한 모델을 씁니다
그래서 바둑 같은 경우도 여기 앞에 그림이 있는데 이 트리서치를 여기 보시면 트리서치를 하는 경우가 있고 안 하는 경우가 있고 그렇거든요
그리고 여기 테스트 타임에 트리서치를 안 하는 경우가 있는데 안 하면 당연히 실력이 떨어집니다
트리서치 하는 게 좋은데 어쨌든 안 해도 돌아는 간단한 거 왜냐하면 우리 기본정책이 있잖아요
그 기본정책으로 그냥 돌려버리면 됩니다
그래서 속도가 문제가 되면 두 가지 해결책이 이렇게 있을 수가 있습니다
둘 다 같이 쓸 수도 있겠죠
from collections import Counter, namedtuple
import numpy as np
PLAYER1 = 'X'
PLAYER2 = 'O'
EMPTY = ' '
# tup: 배치, turn: 턴, winner: 승자, terminal: 종료 여부
_TTTB = namedtuple("TicTacToeBoard", "tup turn winner terminal")
class TicTacToeBoard(_TTTB):
@classmethod
def new(cls):
return cls(tup=(EMPTY,) * 9, turn=PLAYER1, winner=None, terminal=False)
def available_moves(self): # 가능한 수
return [i for i, value in enumerate(self.tup) if value == EMPTY]
def find_children(self): # 자식(후속 수) 찾기
if self.terminal:
return set()
return {self.make_move(i) for i in self.available_moves()}
def random_move(self): # 무작위로 두기
return self.make_move(np.random.choice(self.available_moves()))
def reward(self, player):
if self.winner is None:
return 0.5 # 무
elif player == self.winner:
return 1 # 승
else:
return 0 # 패
def make_move(self, index): # index에 수 두기
tup = self.tup[:index] + (self.turn,) + self.tup[index + 1 :]
turn = PLAYER2 if self.turn == PLAYER1 else PLAYER1 # 다음 턴
winner = self.find_winner(tup) # 승자
terminal = winner is not None or EMPTY not in tup # 종료 여부
return TicTacToeBoard(tup, turn, winner, terminal)
def find_winner(self, tup):
winning_comobos = [ # 일렬이 되는 경우
[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
for i, j, k in winning_comobos: # 일렬을 만들면 이김
if tup[i] != EMPTY and tup[i] == tup[j] == tup[k]:
return tup[i]
return None
def to_pretty_string(self): # 예쁘게 출력
lines = [' 1 2 3']
for i in range(0, 9, 3):
row = self.tup[i:i+3]
lines.append(f'{i+1} {" ".join(row)}')
return '\n'.join(lines) + '\n'
MCTS 구현
class MCTS:
def __init__(self, exploration_weight=2):
self.Q = Counter() # 보상 합계
self.N = Counter() # 방문 횟수
self.children = dict() # 자식 노드
self.exploration_weight = exploration_weight # 탐색 가중치
def search(self, node, budget=50):
for _ in range(budget): # 예산 내에서 롤아웃
self.do_rollout(node)
def score(n):
if self.N[n] == 0:
return -np.inf # 방문하지 않은 경우는 -무한대
return self.Q[n] / self.N[n] # 평균 보상
return max(self.children[node], key=score) # 평균 보상이 큰 자식 선택
def do_rollout(self, node):
path = self._select(node)
leaf = path[-1]
self._expand(leaf)
reward = self._simulate(leaf, node.turn)
self._backpropagate(path, reward)
def _select(self, node):
path = []
while True:
path.append(node)
if node not in self.children or node.terminal: # 방문한 적이 없거나, 종료 노드이면 끝
return path
unexplored = self.children[node] - self.children.keys()
if unexplored: # 방문한 적이 있으면, 자식 노드 중에 탐색 안한 노드 추가
n = unexplored.pop()
path.append(n)
return path
node = self._uct_select(node) # 모든 자식 노드를 방문했으면 UCT로 선택
def _expand(self, node):
# 자식 노드를 확장
if node not in self.children:
self.children[node] = node.find_children()
def _simulate(self, node, player):
while not node.terminal: # 끝날 때까지 기본 정책으로 진행
node = node.random_move() # 기본 정책은 무작위로 두기
return node.reward(player) # 보상 계산
def _backpropagate(self, path, reward):
for node in reversed(path):
self.N[node] += 1
self.Q[node] += reward
reward = 1 - reward # 상대방의 보상
def _uct_select(self, node):
Ns = np.log(self.N[node])
def uct(n):
return self.Q[n] / self.N[n] + self.exploration_weight * np.sqrt(Ns / self.N[n])
return max(self.children[node], key=uct)
승률 측정
mcts = MCTS()
board = TicTacToeBoard.new()
while not board.terminal:
if board.turn == PLAYER1:
board = board.random_move() # 플레이어 1은 무작위로
else:
board = mcts.search(board) #플레이어 2는 MCTS로
win_rate = int(100*mcts.Q[board]/mcts.N[board])
print(f'Q={mcts.Q[board]}, N={mcts.N[board]}, Q/N={win_rate}%')
print(board.to_pretty_string())
print(f'Winner: {board.winner}')
1 2 3
1
4 X
7
Q=5.5, N=7, Q/N=78%
1 2 3
1 O
4 X
7
1 2 3
1 O
4 X
7 X
Q=8.0, N=11, Q/N=72%
1 2 3
1 O
4 X
7 O X
1 2 3
1 O X
4 X
7 O X
Q=14, N=17, Q/N=82%
1 2 3
1 O O X
4 X
7 O X
1 2 3
1 O O X
4 X X
7 O X
Q=30, N=30, Q/N=100%
1 2 3
1 O O X
4 O X X
7 O X
Winner: O
그 다음에 이제 mcts를 구현을 해야겠죠
mcts 구현은 어렵다면 어렵고 쉽다면 쉬운데 우리가 이제 여기 q가 있고 n이 있어가지고 이거 사실 생각해보니까 노테이션이 좀 잘못되는데 이걸 q라고 하면 되겠죠
어쨌든 보상을 여기다 다 더할 거고 그 다음에 이제 몇 번 해봤는지를 다 더할 겁니다
그러면 q 나 누기 n 하면 우리가 이제 일종의 기대값을 구할 수 있겠죠
이건 제가 기호를 좀 잘못 썼는데 여기를 q라고 하면 안 됐죠
여기는 뭐 g나 이런 걸 썼어요
어쨌든 그런 뜻이고 그 다음에 exploration weight 이건데 이거는 탐색을 얼마나 할 거냐
요고가 됩니다
그래서 요걸 늘려 주시면 탐색을 많이 하고요 줄이면 탐색을 적게 합니다
당연히 탐색을 많이 하면 더 정확한 조정이 되겠죠
그래서 여기서 이제 서치를 하는데 일단 버짓이 있어요
그래서 우리가 50번 롤 아웃을 하겠다
이게 우리 예산입니다
그래서 여기 mcts.do 롤 아웃되어 있는데 이거는 셀프에요 홈페이지에서는 제가 고쳐놨는데 강의자로 해서 안 고쳐놨네요
셀프.do 롤 아웃 하면서 롤 아웃 한다는 건 뭐냐면 우리가 가진 기본 정책 가지고 그냥 한번 쭉 도 보는 겁니다
예를 들면 내가 이렇게 있는데 상대방 여기다 뒀어요
내가 여기다 둘까?
이렇게 생각을 했어요
아직 두진 않았어요
둘까?
라고 생각만 한 거예요
그럼 나 혼자 머릿속을 한번 도 보는 거예요
그러면 내가 여기 두면 상대방이 여기 둘 거고 그럼 내가 여기 막으면 상대방이 이렇게 둘 거고 그럼 내가 여기 막으면 상대방이 여기다 둘 거고 그럼 내가 여기 두고 상대방이 두고 무승부는 한번 롤 아웃 이렇게 해본 거예요
이런 식으로 그러면 우리가 예산이 50번이니까 50번 할 수 있는 거죠
이거 이 생각을 그럼 내가 이렇게 둔데 상대방이 일로 막으면 어떡하지?
그러면 이렇게 막고 이렇게 이걸 50번 해보는 거죠
그래서 롤 아웃을 50번 하고 50번을 했으니까 우리가 이제 우리 자식들 자식이라는 건 뭐냐면 여기 에 X를 둔다는 게 현재 상황이고 그럼 여기서 파생되는 상황들이 가운데 라인과 확정된 거고 내가 여기 두는 상황도 있을 수 있고 여기 두는 상황도 있을 수 있고 이런 것들을 자식이라고 합니다
그럼 그 자식들 중에서 이 점수가 제일 큰 애를 찾는다
이런 거예요
이 점수는 뭘 하냐면 이거 이제 노드 자식을 하나 받아가지고 자식 하나를 받아서 그 자식에 몇 번 방문했는지 만약에 방문한 적이 없으면 여기가 0분의 Q가 되니까 무한대가 되고요 마이너스 무한대가 되고 그래서 방문한 적 없는 애는 원래 0분의 0이니까 사실 그냥 에러 나거든요
그래서 이제 이런 애들은 마이너스 무한대로 점수를 주고 만약에 방문한 적이 있으면 Q분의 N 해가지고 평균적으로 얼마나 보상을 받는지 여기서는 결국에는 Q는 이길 때마다 1점이니까 내가 10번 해서 9번 이겼으면 10분의 9 해서 이건 그대로 승률이 됩니다
부재로 하시는 분들은 계산공식을 바꾸셔야 돼요
그래서 이거를 맥스로 하시면 안 되고 이제 민으로 해야 되겠죠
그리고 여기도 민 Q 이런 식으로 하셔야 될 것 같아요
그 다음에 이제 두 롤라웃은 별거 아니고 우리가 이제 이 노드를 고른 다음에 익스팬드 하면 선택지를 펼쳐 선택지를 펼치고 그래서 이제 바둑판 상황이 있으면 여기서 이제 어떤 선택지가 있는지를 다 찾아본다
이런 선택지 저런 선택지 뭐 이런 그 다음에 이제 시뮬레이트 이렇게 하면 이 시뮬레이트가 롤라웃 하라는 거예요
그래서 여기서부터 내가 이걸 골랐다
그럼 여기서부터 쭉 가봐라 그럼 끝까지 더 보면 리워드가 나오겠죠
여기 이제 승패가 됩니다
승무패 그래서 백프로파게이터라고 그러면 여기까지 갔으면 거꾸로 이제 뒤집어오면서 그 승패를 이 중간 단계에다가 다 1승씩 표시를 해주면 되겠죠
졌으면 1패씩 표시하시고 그 다음에 이제 슬랙트는 내가 이제 방문한 적이 없거나 아니면 여기 이제 막다른 골목이다
이미 승패가 갈렸다
그러면 이제 거기서 끝나고 만약에 방문한 적이 있으면 내가 이제 탐색을 안 한 노드를 추가를 해줍니다
그 다음에 내가 이제 모든 자식 노드를 다 방문했다
방문했다는 건 뭐냐면 다 어쨌든 그 수가 어떤 수인지 열어봤다는 거야 확인을 해봤다는 거야
그러니까 예를 들면은 여기에 이제 이런 상황인데 그러면은 이런 상황도 있고 이런 상황도 있고 이제 방문을 한다는 건 이거 하나씩 다 확인을 해본다는 겁니다
어떤 경우인지 그럼 다 했으면 내가 이제 8개가 있겠죠
이렇게 8개를 다 펼쳐봤다 그러면은 이 중에 어느 것을 해볼까요
이렇게 골라야 되잖아요
그때는 UCT로 고르게 됩니다
UCT는 여기 UCT 셀렉트가 있는데 이 공식 m분의 q 이거는 승률이죠
여기가 승률이고 그 다음에 몇 번 방문했는지 내가 몇 번 방문했는 지로 m분의 1에다가 이제 루트를 씌워 가지고 이렇게 하고요 그 다음에 여기 Exploration weight가 있는데 이 앞에다가 이제 곱해 주는 값이에요
지금 2를 곱해 주는데 그럼 만약에 이 숫자를 크게 준다
예를 들면 2가 아니라 20 이렇게 준다 그러면은 n이 작으면 자를수록 이 배수가 훨씬 크게 반영이 되겠죠
그래서 승률을 많이 반영할 거냐
내가 안 해본 걸 더 무게를 줄 거냐 Exploration weight가 결정을 합니다
보통 한 이 정도 두는데 왜냐하면은 우리가 보통 오차범위 계산할 때 95% 오차범위로 많이 하거든요
그냥 관행적으로 여론조사 같은 거 보면 이 여론조사는 오차범위 95%에 플러스 마이너스 3.1% 포인트입니다
이런 얘기 하잖아요
뉴스 같은 데 보시면 이 얘기 많이 하죠
95% 오차범위가 보통 여기에다가 1.96 정도 거의 한 2 정도 곱하면 되거든요
그러니까 여기다 2를 곱한다는 거는 내가 한 95% 정도 오차범위를 생각하는 건데 그거의 상방을 보겠다
이런 얘기 하죠
여기 플러스로 되어 있는데 하방을 보시려면 마이너스로 바꿔주셔야겠죠
그 다음에 백프로파게이트는 그냥 이 패스가 이제 내가 거쳐온 경로에요
내가 여기서 이제 끝났는데 끝난거에서 역순으로 따라 거슬로 올라가면서 승률을 하나씩 카운트를 시켜주시면 됩니다
여기는 이제 딱히 할인이 없는데 할인이 필요한 경우에는 여기도 할인도 적용을 해주시면 되겠죠
그래서 이제 mcts 알고리즘 이렇게 정의를 했고 그다음에 이제 틱틱톡 보드를 만든 다음에 보드점 터미널이 뭐냐면 종료에요 게임 종료 게임 오버 게임 오버가 될 때까지 반복적으로 게임을 하는데 플레이어 1은 그냥 랜덤하게 합니다
그다음에 플레이어 2는 mcts로 하는데 이 mcts가 별로 그렇게 잘 이기지는 않거든요
왜냐하면 여기 시뮬레이션 하는 이게 롤라웃 정책인데 기본 정책 자체가 랜덤무브에요
사실 얘도 수를 생각해 보긴 하는데 얘도 좀 바보라 가지고 얘도 수를 랜덤무브로 기본정책을 쓰니까 수를 고르는 거는 uct를 쓰는데 고른 다음에 플레이는 자기가 랜덤으로 해 본단 말이에요
그래서 사실 막상 해보시면 그렇게 잘 두지는 않습니다
되게 바보같이 두거든요
기본정책이 나쁘면 mcts를 써도 소용이 없다
그래서 우리가 이제 한번 돌려보면 여기 이제 두시면 여기 x가 이제 1번 플레이어 입니다
얘는 랜덤하게 두기 때문에 그냥 아무 데나 둬요
빈칸 있으면 그러면 x가 이제 뒀는데 여기 이제 여기다가 두잖아요
여기 7번 자리에다가 여기다가 두는데 그 이 동그라미는 mcts로 둔 겁니다
그래서 얘가 해 보니까 여기다 뒀을 때 총 8번을 했는데 내가 6번 이기고 한번 무승부더라 한번은 지고 사실 틱택톤은 잘 두면 절대 질 수는 없거든요
이게 판이 작아 가지고 무조건 상대방만 막으면 비기는 건 보장입니다
사실 진다는 건 기본정책이 바보란 얘기에요
질 수가 없는데 어쨌든 내가 여기다 두니까 8번 중에 6번 이기고 한번은 지더라
승률 81%라서 나는 여기다 뒀다
이런 얘기입니다
그 다음에 이제 x는 또 아무 데나 둡니다
그 다음에 내가 여기다 두니까 승률이 66%더라 9번 뒀는데 내가 여기다가 9번 뒀봤는데 6번 이기더라
그 다음에 또 x는 아무데나 두고요 그 다음에 이제 n이 좀 늘어났는데 왜냐하면 이제 거의 막다른 골목에 왔기 때문에 둘 수 있는 수가 제한이 되어 있어요
그래서 여기에 가운데다가 22번 뒀는데 당연히 22번 뒀면 22번 이기겠죠
여기서 있으면 무조건 이기니까 이건 100% 이기는 수다
이렇게 여기다 두고 얘가 이깁니다
이렇게 하면 이제 할 수 있고 그래서 다시 해보면은 매번 이기는 건 아니에요 질 때도 있어요
기본정책이 나쁘기 때문에 그랬습니다
그래서 이런 식으로 7번 더 봤더니 여기다 두면 5번 이기더라
이러면서 12번 둬서 8번 이겼다
16번 둬서 13번 이겼다
그래서 이렇게 두는데 결국에는 집니다
바보죠
그래서 그렇게 이제 되는 거고 이렇게 이제 돌려보시면 되겠죠
mcts로 할 수 있죠
여기를 플레이어 1도 mcts로 두려면 이렇게 바꾸시면 됩니다
서치를 랜덤 무브를 아이고 이거 아 다시 못찍었다
여기 플레이어 1은 랜덤 무브 하게 되어있는데 여기를 mcts 서치보드 이렇게 바꾸시면 됩니다
그 다음에 승률도 출력하게 하려면 이 밑에 것도 있어야겠죠
아 그러면 아예 그냥 이 품은 자체를 없애버리면 되겠네요
맞나 이 품은 자체를 없애버리면 됩니다
둘 다 이렇게 하면은 둘 다 보도록 두겠죠
그러면은 1번도 내가 두어보니까 여기다 둘 때 승률이 78%더라
그럼 2번은 난 여기다 두니까 승률 68% 던데
그럼 내가 여기다 두면 승률이 55%지
아 난 여기다 둬서 승률 59%로 여기를 두겠어
이렇게 자기들끼리 두죠
그래서 이런식으로 이 품은 그냥 없애시면 되요
모두가 플레이어 1 2가 다 mcts로 두게 되죠