├── AGREEMENT.md ├── FAQ.md ├── FAQ_NSML.md ├── LICENSE.md ├── README.md ├── missions ├── examples │ ├── kin │ │ ├── example │ │ │ ├── dataset.py │ │ │ ├── kor_char_parser.py │ │ │ ├── main.py │ │ │ └── setup.py │ │ └── sample_data │ │ │ └── kin │ │ │ └── train │ │ │ ├── train_data │ │ │ └── train_label │ └── movie-review │ │ ├── example │ │ ├── dataset.py │ │ ├── kor_char_parser.py │ │ ├── main.py │ │ └── setup.py │ │ └── sample_data │ │ └── movie_review │ │ └── train │ │ ├── train_data │ │ └── train_label ├── kin.md ├── movie-review.md └── tutorial.md ├── quick-guide.md └── res ├── NSMLHack_web_1000x260_G.jpg ├── cSGPHtzPFQ.png ├── ckh.jpg ├── kdh.jpg ├── kin 2.jpg ├── kin.jpg ├── ksh.jpg ├── leaderboard.png ├── movie.png ├── rank1.png ├── rank2.png ├── result_kin_final.png ├── result_kin_r2-1.png ├── result_kin_r2-2.png ├── result_movie_final.png ├── result_movie_r2-1.png ├── result_movie_r2-2.png ├── shj.jpg └── smj.jpg /AGREEMENT.md: -------------------------------------------------------------------------------- 1 | # 참가 동의서 2 | 3 | 본인은 네이버 주식회사(이하 “회사”라 함)가 주최하는 “네이버 AI 해커톤 2018”(이하 "해커톤"이라 함)에 참가함에 있어, 다음과 같은 내용을 확인하고 이에 동의 합니다. 4 | 5 | ## 권리 귀속에 관한 사항 6 | * 응모된 아이디어에 대한 권리는 아이디어 제안자에게 있습니다. 7 | * 다만, 본 대회를 위하여 회사가 제공한 일체의 자료(소스코드, 학습용 데이터, 튜토리얼 포함)에 대한 권리는 회사에 있습니다. 8 | * 제안된 아이디어를 대회 진행 중에 회사가 함께 개선, 발전시킨 경우, 변경된 아이디어에 대한 권리는 제안자 및 회사의 공동 소유로 합니다. 다만 이는 아이디어 제안자의 원래 아이디어 및 이에 대한 지식재산권에는 영향을 미치지 않습니다. 9 | * 회사가 참가자의 아이디어에 대한 권리의 사용권을 허여 받고자 하는 경우, 별도의 사용권 계약을 체결하여 대가, 범위, 기간 등 사용권 허여와 관련된 구체적인 방법과 절차 등을 상호 협의하여 결정합니다. 다만, 그 아이디어가 수상된 것이며 사용 범위가 공모전 홍보, 당선작 전시 등 공모전 개최 목적이나 일반적인 거래 관행에 비추어 적절한 경우는 그러하지 아니합니다. 10 | * 회사가 아이디어에 대한 권리를 양수하고자 하는 경우, 참가자와 별도의 양도 계약을 체결하여야 하며, 이 경우 대가, 대가의 지급방법 등 양도와 관련된 구체적인 방법과 절차 등을 상호 협의하여 결정합니다. 11 | * 참가자가 수상 아이디어에 대한 권리 및 이 아이디어에 대한 지식재산권을 단독으로 갖고 회사가 수상 아이디어에 대한 상금을 지급하는 경우, 회사는 수상 아이디어에 대한 통상실시권」 및 「지식재산권 양도 등에 대해 결과 발표일로부터 4개월 동안 우선 협상할 수 있는 권리 (우선협상권)」를 가집니다. 12 | * 아이디어가 공중에 알려지거나 알려질 수 있는 상태에 놓이게 될 경우, 그 아이디어는 공공의 소유가 되어 특허를 받을 수 없으므로, 가급적 특허 출원 등 필요한 조치를 마치고 참가해주시기 바랍니다. (한국의 경우, 공지된 발명에 해당하게 된 날부터 12개월까지 공지예외주장을 통하여 권리화가 가능합니다.) 13 | 14 | 15 | ## 정보보호 및 영업비밀 보호의무 16 | * 해커톤 과정을 통해 취득한 회사 정보 및 회사가 보호할 의무가 있는 타사, 타인의 정보자산, 지식재산, 직무상의 기술, 영업비밀 등 모든 정보를 해커톤 참여 이외의 용도로 이용하거나 회사의 동의 없이 복사, 기록, 보관, 변경, 삭제, 타인에게 공개 및 유출하지 않겠습니다. 17 | * 해커톤 종료시 회사로부터 지급 받은 일체의 자산과 회사 관련 정보는 반드시 회사에 반납하겠습니다. 18 | * 해커톤 참가시는 물론, 해커톤 종료 후에도 회사의 영업비밀이 회사동의 없이 공개, 누설, 사용되지 않도록 하겠습니다. (‘공개, 누설’ 이라 함은 적극적으로 타인에게 영업비밀을 알리는 행위뿐만 아니라 타인이 직접 또는 간접적으로 회사의 영업비밀을 취득하는 행위를 묵인하는 소극적 의무 위반을 포함합니다.) 19 | * 참가자는 위 정보보호 준수사항 및 영업비밀 보호사항에 관한 내용을 해커톤 참가시는 물론 해커톤 종료 후에도 숙지하여야 하며, 본 내용을 준수하지 않음으로 인해 발생되는 모든 책임은 참가자 본인에게 있습니다. 또한 참가자가 정보보호 및 영업비밀 보호의무를 위반하여 회사에 손해를 입힌 경우 민·형사상의 모든 책임은 참가자 본인에게 있으며, 회사에 입힌 손해에 지체 없이 전액 배상 및 복구해야 합니다. 20 | 21 | ※ ‘영업비밀’이라 함은 공연히 알려져 있지 아니하고 독립된 경제적 가치를 가지는 것으로서 회사가 비밀로 관리하는 생산방법, 판매방법, 소프트웨어의 개발방법, 기타영업활동에 유용한 기술상 또는 경영상의 정보를 말합니다. 22 | 23 | ## 아이디어의 도용 및 유출 방지를 위한 사항 24 | * 회사는 다음의 경우를 제외하고 공모전에 응모된 아이디어에 관한 내용을 응모자의 동의 없이 제3자에게 제공하지 않습니다. 25 | 1. 회사의 고의 또는 과실에 의하지 않고 이미 공지의 사실로 된 정보 26 | 2. 공모전 운영 및 선정, 평가의 목적으로 제3자에게 관련 정보를 제공할 필요가 있는 경우 (이 경우 회사는 제3자와 별도의 비밀유지약정을 체결합니다) 27 | * 회사는 결과 발표일로부터 1년 동안 관련 자료를 보관하며, 그 이후 자료를 폐기합니다. 다만 대회에서 수상한 것에 대해서는 참가자의 동의를 얻어 폐기하지 않을 수 있습니다. 28 | 29 | ## 참가자 유의사항 30 | * 해커톤에 참가한 아이디어가 타인의 아이디어를 고의로 도용한 것으로 인정되거나 부정한 방법으로 수상한 경우에는 수상 이후에도 수상은 취소될 수 있으며, 참가자는 상금을 포함한 시상 내역 일체를 반환해야 합니다. 이 때 참가자가 회사에 아이디어에 대한 권리에 대해서 양도 또는 사용권 허여 계약을 한 경우에는, 그와 관련된 손해에 대하여 배상을 하여야 합니다. 31 | * 참가자는 회사가 제공한 일체의 자료(소스코드, 학습용 데이터, 튜토리얼 포함)를 본 대회의 참가를 위한 목적 내에서 정해진 가이드라인에 따라 이용하여야 합니다. 32 | * 회사의 사전 동의 없이 이를 복사, 기록, 보관, 공개, 배포, 상업적 이용 등을 하는 행위는 금지되어 있습니다. 33 | * 학습용 데이터 등 회사가 제공한 일체의 자료를 논문에서 인용하기 위하여는 다음의 가이드라인에 따르셔야 합니다. 34 | 1. 네이버 AI 해커톤 2018에 참여해 개발한 알고리즘이라는 점을 Acknowledgement에 명시 35 | 1. **데이터에 대한 구체적인 설명이나 예시를 들 수 없음** 36 | 1. 단, 데이터의 구체적 내용을 유추할 수 없는 범위에서 데이터 구조에 대한 설명이나 데이터 Summary 및 Descriptive Statistics를 보여주는 것은 가능 37 | * 참가자는 본 대회의 참가가 종료되는 즉시 회사가 제공한 일체의 자료를 반환 내지는 폐기하여야 합니다. 38 | 39 | ※ ‘아이디어’라 함은 재산적 가치가 있는 것으로서, 이를 보호할 수 있는 권리가 창작자에게 당연히 발생하거나 별도의 절차에 의해 창작자가 그 권리를 취득할 수 있는 것을 말합니다. 40 | -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | ### Q. 특별한 개발 지식이나 언어 사용 경험이 없어도 참여 가능한가요? 2 | 기반 지식은 필요하며, AI로 다양한 문제를 해결 해 본 경험이 있다면 더 좋은 결과를 낼 수 있습니다. 3 | 4 | ### Q. 참가 정보를 변경하고 싶어요! 5 | 변경할 정보를 dl_ai_hackathon_2018@navercorp.com으로 보내주세요. 6 | 7 | ### Q. 미션에 대한 좀 더 상세한 정보를 알고 싶어요! 8 | "네이버 지식iN 질문 유사도 예측"은 한 쌍의 질문 문장이 유사한 질문인지 아닌지를 학습하고 예측하는 문제 입니다. "네이버 영화 평점 예측"은 영화 리뷰와 그 평점을 학습하고 주어진 리뷰의 평점을 예측하는 문제입니다. 미션에 대한 자세한 설명은 예선 시작과 동시에 공개할 예정입니다. 9 | 10 | ### Q. 예선 1라운드, 2라운드와 결선 차이점은 뭔가요? 11 | 리더보드 순위로 2라운드, 결선 진출자를 선발하며 라운드가 올라갈수록 더 많은 데이터를 사용할 수 있습니다. 12 | 13 | ### Q. 미션은 둘 중 하나만 도전할 수 있나요? 14 | 하나만 해도 되고 둘 다 해도 됩니다. 시상은 미션별로 할 예정입니다. 15 | 16 | ### Q. 예선은 온라인으로만 진행하나요? 17 | 네. 온라인으로만 진행합니다. 18 | 19 | ### Q. 결선은 모든 팀원이 참석해야 하나요? 20 | 모든 팀원이 참석하는 게 원칙입니다. 피치 못할 사정이 발생 한다면 먼저 문의를 해 주세요. 21 | 22 | ### Q. 멘토에게 어떻게 멘토링을 받을 수 있나요? 23 | 예선 기간 동안에는 멘토링 받고 싶은 내용을 dl_ai_hackathon_2018@navercorp.com로 보내 주세요. 결선 기간 동안에는 현장에서 멘토와 직접 멘토링을 할 수 있습니다. 24 | 25 | ### Q. NSML은 언제 사용해 볼 수 있나요? 26 | 해커톤을 위한 NSML은 예선 시작일인 4월 2일(월) 오전부터 사용할 수 있습니다. 27 | 28 | ### Q. NSML 사용법은 어디서 확인 할 수 있나요? 29 | 예선 시작과 함께 튜토리얼과 baseline을 함께 공개할 예정입니다. 30 | 31 | ### Q. NSML에서 사용하는 언어는 뭔가요? 32 | NSML은 네이버에서 개발한 머신러닝 클라우드 플랫폼입니다.CLI와 웹 등의 인터페이스를 통해 클라우드 자원을 사용할 수 있습니다. tensorflow, Keras, Pytorch 등을 비롯해 파이썬 기반의 머신 러닝 라이브러리는 대부분 사용할 수 있습니다. 33 | 34 | ### Q. NSML에서 사용하는 GPU 사양은 어떻게 되나요? 35 | GPU는 tesla p40 모델입니다. 36 | 37 | ### Q. 해커톤에서 개발한 알고리즘을 개인 논문에 사용해도 되나요? 38 | 다음 사항을 준수한다면 사용할 수 있습니다. 39 | * 네이버 AI 해커톤 2018에 참여해 개발한 알고리즘이라는 점을 Acknowledgement에 명시 40 | * **데이터에 대한 구체적인 설명이나 예시를 들 수 없음** 41 | * 단, 데이터의 구체적 내용을 유추할 수 없는 범위에서 데이터 구조에 대한 설명이나 데이터 Summary 및 Descriptive Statistics를 보여주는 것은 가능 42 | 43 | ### Q. 네이버 클라우드 플랫폼 크레딧은 뭔가요? 44 | 네이버 클라우드 플랫폼([www.ncloud.com](https://www.ncloud.com))의 모든 상품을 사용할 수 있는 현금이라고 생각하시면 됩니다. 45 | 해커톤 참가자에게는 기본 30만원 크레딧을 제공하며 결선 참가자 및 수상자에게는 더 많은 추가 크레딧을 제공합니다. 크레딧을 받는 방법은 개별 안내 드리겠습니다. 46 | -------------------------------------------------------------------------------- /FAQ_NSML.md: -------------------------------------------------------------------------------- 1 | # FAQ For NSML 2 | 3 | #### 0. final update 사항(dataset) 4 | ##### 1.kin_data: 5 | - 학습용/테스트용 지식인 질문의 주제가 다릅니다. 예를 들어, 학습용 데이터가 컴퓨터에 관한 것이었다면, 테스트용 데이터는 핸드폰에 관한 질문인 방식입니다. 따라서, phase1/2때보다 generalization에 좀 더 집중해야 좋은 점수를 얻을 수 있습니다. 6 | 7 | ##### 2. movie_review: 8 | - 1.과 마찬가지로 학습용/테스트용 영화 항목이 다릅니다. 9 | 10 | #### 0. phase2 update 사항 11 | ##### 1. nsml submit -t option 추가 : 테스트 모드 추가 (형식: nsml submit -t session model) 12 | - submit시 오류가 발생할 때, 메시지를 잘 받아볼 수 없는 문제를 보완하기 위해서 -t 옵션을 추가. 13 | - nsml submit -t로 명령을 수행하면 테스트 셋 데이터의 첫 10줄에 대한 prediction결과를 출력합니다. 14 | - 중간에 문제가 생기면 세션이 종료되며, 이 때 session id 가 출력되기 때문에 nsml logs를 이용해서 디버깅이 가능합니다. 15 | - 기존 코드에 문제가 있는 경우 (각각의 경우는 FAQ 다른 항목 참고), 과거에는 세션 응답없음까지 기다렸다면, 이제는 그 전에 먼저 종료됨 16 | - out of memory에러, 혹은 timeout이 발생할 경우 nsml submit -b를 이용해 배치 사이즈 조정 가능 17 | ###### 2. nsml fork 18 | - fork를 해서 생성한 세션에 대해서 nsml submit이 정상적으로 동작하지 않던 버그 수정 19 | 20 | 21 | #### 0. 빠르게 submit까지 해보고 싶은데요. 핵심만 알려면 어떻게 하나요? 22 | 아래 링크를 따라하시면 빠르게 submit해보실 수 있습니다. 23 | https://github.com/naver/ai-hackathon-2018/blob/master/quick-guide.md 24 | 25 | #### 1. nsml local에서 IS_DATASET import 오류가 아래와 같이 나와요. 26 | ``` 27 | Traceback (most recent call last): 28 | 29 | File "main.py", line 12, in 30 | 31 | from nsml import DATASET_PATH, IS_DATASET, GPU_NUM 32 | 33 | ImportError: cannot import name 'IS_DATASET' 34 | ``` 35 | 답변) 36 | 샘플코드는 과거 버전입니다. 배포된 코드는 IS_DATASET -> HAS_DATASET으로 변경되어 배포되었습니다. 37 | 문제 해결을 위해서 아래 링크에서 example을 새로 받으세요. 38 | https://github.com/naver/ai-hackathon-2018/tree/master/missions/examples 39 | ​ 40 | #### 2. nsml-local를 설치 하여, local에서 작업을 하려고 하는데 아래와 같이 nsml을 인식하지 못합니다. 41 | (간단한 package link 문제인거 같은데...) 42 | ``` 43 | Traceback (most recent call last): 44 | File "main.py", line 30, in 45 | import nsml 46 | ModuleNotFoundError: No module named 'nsml' 47 | ``` 48 | 답변) nsml local의 재설치를 위해서 아래 명령어를 실행하시면 됩니다. uninstall 및 install을 수행합니다. 49 | ``` 50 | pip uninstall git+https://github.com/n-CLAIR/nsml-local.git;pip install git+https://github.com/n-CLAIR/nsml-local.git 51 | ``` 52 | 53 | #### 3. 영화 평점 리뷰에 대한 Tensorflow 예제는 없나요? 54 | 답변) 네에, 영화 평점 리뷰는 PyTorch로 되어있습니다. 하지만, Kin예제는 Tensorflow로 되어 있습니다. 두 예제가 비슷하므로 어렵지 않게 변경이 가능할 것으로 예상됩니다. 55 | 56 | #### 4. submit을 했는데, leaderboard에 변경이 없어요. 과거 submit history를 확인하는 방법이 있나요? 57 | 답변) leaderboard에 제출된 값중에서 가장 좋은 결과 1건만 보여주고 있습니다. 추가로 자신이 제출한 모든 이력을 확인하는 방법이 있습니다. 아래 그림과 같이 leaderboard에서 public 탭을 private으로 변경하시면 됩니다. 58 | 59 | ![leaderboard-private](./res/leaderboard.png) 60 | 61 | #### 5. credit은 어떻게 지급되나나요? 62 | 답변) credit은 매일 10:30(am) ~ 11:00(am) 사이에 지급됩니다. CLI의 nsml credit 명령과 web화면에서 확인 가능합니다. 63 | 64 | #### 6. 팀원이 두명인데, 한명만 로그인이 되어요. 정상인가요? 65 | 답변) 네에, 현재 팀원1로 등록된 분만 nsml에 접근하시어 사용가능합니다. credit 또한 1명의 계정에만 지급됩니다. 66 | 67 | #### 7. nsml에서 외부 python package를 설치할 수 있나요? 68 | 답변) 네에, setup.py를 통하여 추가 설치를 할 수 있습니다. 69 | 70 | #### 8. nsml에서 pythone이외의 lib를 사용할 방법이 있나요? 71 | 답변) 네에, 몇가지 조건을 만족하면 외부 lib를 사용할 수 있습니다. 일단, docker image를 생성하여 setup.py의 맨 위줄 #nsml: ... 형식으로 docker image의 이름을 명시하여야 합니다. 72 | 관련 내용은 아래 링크에서 참고하실 수 있습니다. https://github.com/naver/ai-hackathon-2018/blob/master/missions/tutorial.md#%EB%AA%A8%EB%8D%B8-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0 73 | 74 | #### 9. setup.py에는 항상 #nsml로 시작해야하나요? 75 | 답변) setup.py에 첫 줄에 있는 #nsml: ... 은 nsml에서 docker Hub에 있는 외부 Docker image를 사용할 때만 적으면 됩니다. 실제로, 샘플로 제공된 kin과 movie review 예제 중에서 한쪽만 #nsml: ... 형식을 취하고 있습니다. 이곳에 아무것도 적지 않으면, nsml은 nsml사용을 위해서 생성해둔 기본 docker image를 사용하게 됩니다. 76 | 77 | #### 10. 학습 프로그램 작성 및 nsml 관련하여 문의는 어디로 하면 되나요? 또한 문의시 어떤 것을 적으면 될까요? 78 | 답변) 이번 해커톤 지원을 위해서 2개의 email 주소가 있습니다. 각각 용도가 따로 있으니 구분하여 문의하시는 것이 보다 빠른 회신을 받으실 수 있습니다. 79 | pytorch 및 NLP 관련 문의는 dl_ai_hackathon_2018_mentors@navercorp.com 로 진행하시면 되며, nsml의 실행에 관련된 문의 및 오류는 dl_ai_hackathon_2018@navercorp.com 로 문의하시면 됩니다. 문의시 자신의 session이름이 포한된 terminal상의 오류 화면을 포함하시면 됩니다. 80 | 81 | #### 11. 다음과 같이 submit 오류가 납니다. 어떻게 해야하나요? 82 | ``` 83 | ..............Error: Session does not respond 84 | 2018/04/07 08:58:12 nsml: Internal server error 85 | ``` 86 | 다양한 이유로 발생할 수 있습니다. 먼저 아래에 서술된 사례를 먼저 검토해보시고, 문제가 지속된다면 정확환 원인 분석을 위해서 dl_ai_hackathon_2018@navercorp.com 로 문의 메일을 주시기 바랍니다. 보내실 때는 session이름을 확인 할 수 있도록 터미널 화면을 복사해서 보내주시면 됩니다. 87 | 알려진 사례는 다음과 같습니다. 88 | - nsml submit시 학습데이터 셋을 참조하려고하는 경우: train과 submit는 서로 다른 환경에서 동작하고 있습니다. submit에서는 train에서 사용하는 file을 사용할 이유가 없기 때문에 해당 파일을 올려두지 않고 있습니다. 그런데, 사용자 작성 코드에서 submit시 call하게 되는 infer함수 내부에서 train용 학습셋을 참조한 경우가 있었으며 위와 같은 오류가 보고된 사례가 있었습니다. 대응 가이드로, if config.mode == 'train': 과 같이 분기조건만 학습셋을 참조하도록 의견드렸습니다. 89 | 90 | #### 12. nsml run에서 구동할 수 있는 코드는 제약이 있나요? 91 | 답변) nsml run시 별도 설정이 없을 경우 main.py를 기본적으로 전송하게 됩니다. 현재는 python코드만 전송 및 수행이 가능하도록 제한을 두고 있습니다. 또한 파일명 또한 .으로 시작하면 upload할 수 없도록 막혀있습니다. 92 | 93 | #### 13. nsml run에서 'No machine available'가 나와요. 94 | 답변) nsml에서 준비한 모든 GPU 자원을 사용중에 발생하는 메시지로, 주로 참가자가 몰리는 시간에 발생하는 경향이 있습니다. 다른 참가자의 session이 종료되면 다시 사용가능하게 되므로 보통은 10-20분 정도 후에 재실행하면 됩니다. 95 | 96 | #### 14. session에서 최대로 사용할 수 있는 GPU 수는 얼마입니까? 97 | 답변) 이번 해커톤에서는 session당 최대 2개로 제한하고 있습니다. nsml run -g 2 ... 옵션으로 두 개의 GPU를 사용할 수 있습니다. 98 | 99 | #### 15. 동시에 수행할 수 있는 session은 제한이 있나요? 100 | 답변) id마다 session을 제한을 두고있지 않습니다. credit이 허용한다면, session 수의 제한 없이 동시 수행이 가능합니다. 101 | 102 | #### 16. nsml에서 외부 모듈을 설치할 수 있나요? 103 | 답변) nsml에서 아래 두 가지 방법으로 외부 모듈 사용이 가능합니다. 104 | 1. pip install : 간단한 python lib 설치 105 | 2. docker image : JVM 환경이 필요하거나, 추가 구동 환경이 필요한 lib 설치 (docker image 생성 -> docker hub에 image 올리고 -> setup.py 첫 줄에 #nsml:... 명시) 106 | 107 | #### 17. nsml에서 pip install은 어떻게 하나요? 108 | 답변) setup.py의 install_requires에 모듈을 적으면 됩니다. 109 | ``` 110 | from distutils.core import setup 111 | setup( 112 | name='nsml example 10 ladder_network', 113 | version='1.0', 114 | description='ns-ml', 115 | install_requires =[ 116 | 'matplotlib', (← add custom lib ) 117 | 'tqdm', 118 | 'pillow' 119 | ] 120 | ) 121 | ``` 122 | #### 18. nsml에서 docker image 사용은 어떻게 하나요? 123 | 답변) docker image를 사용하기 위해서는 docker image를 build하여 docker hub에 올려야합니다. 124 | 그리고, hub에 올려진 image의 이름을 setup.py 첫 줄에 문법에 맞추어 적으면 됩니다. 아래는 movie example에 사용된 setup의 첫 줄입니다. 125 | ``` 126 | #nsml: floydhub/pytorch:0.3.0-gpu.cuda8cudnn6-py3.17 127 | ``` 128 | 129 | 130 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2018 NAVER Corp. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 네이버 AI 해커톤 2018 2 | 3 | "한계를 넘어 상상에 도전하자!" 4 | 5 | 인간이 오감을 활용하는 것처럼 AI도 인간의 오감을 모두 활용하는 방향으로 나아갈 것입니다.
6 | 또한, 인터넷과 모바일이 세상을 크게 변화시킨 것처럼 AI 역시 세상을 크게 변화시킬 것이며 그 영향력은 더욱 커질 것입니다.
7 | 네이버는 AI와 함께 더 편리하고 행복한 미래를 만들기 위해 **네이버 AI 해커톤 2018**을 준비했습니다.
8 | 9 | 특히, 이번 네이버 AI 해커톤 2018은 네이버의 클라우드 머신러닝 플랫폼인 [NSML](https://hack.nsml.navercorp.com/intro)과 함께 합니다. 10 | 11 | NSML(Naver Smart Machine Learning)은 모델을 연구하고 개발하는 데 필요한 복잡한 과정을 대신 처리해주어
12 | 연구 개발자들이 "모델 개발"에만 전념할 수 있고, 다양한 시도를 쉽게 할 수 있는 창의적인 환경을 제공할 것입니다. 13 | 14 | AI를 통해 복잡한 문제를 해결하고 싶나요?
15 | AI 전문가들과 함께 문제 해결 방법을 고민하고 경험을 공유하고 싶다고요? 16 | 17 | 지금 바로 네이버 AI 해커톤 2018에 참여해서
18 | 서로의 경험을 공유하고, 다양하고 창의적인 방법으로 문제를 해결해 보세요! 19 | 20 | [![안내 및 문제 소개](res/cSGPHtzPFQ.png)](https://youtu.be/cSGPHtzPFQw) 21 | 22 | ## 대회 종료 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 36 | 39 | 40 | 41 | 44 | 47 | 50 | 51 | 52 | 55 | 58 | 61 | 62 |
순위지식인 유사도영화 평점
31 | 1위 32 | 34 | Team Sadang 팀 35 | 37 | HCC 팀 38 |
42 | 2위 43 | 45 | error 모르게따 팀 46 | 48 | 콜라마시며코딩 팀 49 |
53 | 3위 54 | 56 | 푸핑톤 팀 57 | 59 | JJu 팀 60 |
63 | 64 | * [네이버 지식iN 질문 유사도 예측 문제 최종결과](res/result_kin_final.png) 65 | * [네이버 영화 평점 예측 최종결과](res/result_movie_final.png) 66 | 67 | ## 모델 공유 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 79 | 82 | 85 | 86 | 87 | 90 | 93 | 96 | 97 | 98 | 101 | 104 | 107 | 108 | 109 | 112 | 115 | 118 | 119 | 120 | 123 | 127 | 130 | 131 | 132 | 135 | 139 | 142 | 143 | 144 | 147 | 150 | 153 | 154 | 155 | 158 | 162 | 165 | 166 | 167 | 170 | 174 | 177 | 178 | 179 | 182 | 185 | 188 | 189 | 190 | 193 | 196 | 199 | 200 | 201 | 204 | 208 | 211 | 212 | 213 | 216 | 220 | 223 | 224 |
팀명미션링크
77 | HongTeam 78 | 80 | 네이버 영화 평점 예측 81 | 83 | 바로가기 84 |
88 | tantara 89 | 91 | 네이버 영화 평점 예측 92 | 94 | 바로가기 95 |
99 | ToMuchInfo 100 | 102 | 네이버 영화 평점 예측 103 | 105 | 바로가기 106 |
110 | Hermits 111 | 113 | 네이버 영화 평점 예측 114 | 116 | 바로가기 117 |
121 | 슈퍼갤럭시 122 |     124 | 네이버 영화 평점 예측
125 | 네이버 지식iN 질문 유사도 예측 126 |
128 | 바로가기 129 |
133 | SOCC 134 | 136 | 네이버 영화 평점 예측
137 | 네이버 지식iN 질문 유사도 예측 138 |
140 | 바로가기 141 |
145 | HCC 146 | 148 | 네이버 영화 평점 예측 149 | 151 | 바로가기 152 |
156 | kozistr 157 | 159 | 네이버 영화 평점 예측
160 | 네이버 지식iN 질문 유사도 예측 161 |
163 | 바로가기 164 |
168 | Team Sadang 169 | 171 | 네이버 영화 평점 예측
172 | 네이버 지식iN 질문 유사도 예측 173 |
175 | 바로가기 176 |
180 | Hala Madrid 181 | 183 | 네이버 지식iN 질문 유사도 예측 184 | 186 | 바로가기 187 |
191 | 푸핑톤 192 | 194 | 네이버 지식iN 질문 유사도 예측 195 | 197 | 바로가기 198 |
202 | STUnitas ATS 203 | 205 | 네이버 영화 평점 예측
206 | 네이버 지식iN 질문 유사도 예측 207 |
209 | 바로가기 210 |
214 | Deeppangyo 215 | 217 | 네이버 영화 평점 예측
218 | 네이버 지식iN 질문 유사도 예측 219 |
221 | 바로가기 222 |
225 | 226 | > ※ 모델을 공유하실 팀은 PR 부탁드립니다. 227 | 228 | ## 멘토 229 | 여러분들과 함께 문제 해결 방법을 고민하고 조언 해주실 슈퍼 멘토를 소개합니다. 230 | 231 | 232 | 233 | 237 | 241 | 245 | 249 | 253 | 254 |
234 |
235 | 김성훈 236 |
238 |
239 | 곽동현 240 |
242 |
243 | 서민준 244 |
246 |
247 | 송현제 248 |
250 |
251 | 최경호 252 |
255 | 256 | ## 참가 신청 257 | AI로 문제를 해결하는 데 관심 있는 분이라면 누구나 참가 신청할 수 있습니다.
258 | 개인 또는 팀(최대 3명)으로 참가 가능합니다. [네이버 폼](http://naver.me/GyfLHzwg)으로 참가 신청하세요! 259 | 260 | * **신청기간**: 2018년 3월 12일(월)~3월 25일(일) 261 | * **참가 신청 폼**: 참가 신청 마감 262 | * 신청자가 많을 경우 심사 후 개별 안내 263 | 264 | ## 일정 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 276 | 277 | 280 | 281 | 282 | 286 | 287 | 291 | 292 | 293 | 297 | 298 | 301 | 302 |
일정기간장소
273 | 참가 신청
274 | 2018년 3월 12일(월)~3월 25일(일) 275 |
2주 278 | 참가 신청 마감 279 |
283 | 예선
284 | 2018년 4월 2일(월)~4월 16일(월) 285 |
2주 288 | 온라인
289 | https://hack.nsml.navercorp.com 290 |
294 | 결선
295 | 2018년 4월 26일(목)~4월 27일(금) 296 |
1박 2일 299 | 네이버 커넥트원(춘천)
300 |
303 | 304 | > ※ 예선 및 결선 참가자에게는 개별로 참가 안내드립니다.
305 | >    결선 참가자는 네이버 본사(그린팩토리, 분당)에 모여서 커넥트원(춘천)으로 함께 이동하며
306 |    네이버 본사 - 커넥트원 간 이동 차량 및 결선 기간 중 숙식, 간식 등을 제공합니다. 307 | 308 | ## 미션 309 | * [네이버 지식iN 질문 유사도 예측](missions/kin.md) 310 | * [네이버 영화 평점 예측](missions/movie-review.md) 311 | 312 | > ※ 모든 미션은 NSML 플랫폼을 사용해 해결합니다.
313 | >    NSML을 통해 미션을 해결하는 방법은 이 [튜토리얼](missions/tutorial.md)을 참고해 주세요. 314 | 315 | ## 진행 방식 및 심사 기준 316 | 317 | ### 예선 318 | 319 | * 예선 참가자에게는 예선 기간 중 매일 오전 11시에 600 NSML 크레딧을 지급합니다. 320 | * 팀 참가자일 경우 대표 팀원에게만 지급합니다. 321 | * 사용하지 않는 크레딧은 누적됩니다. 322 | 323 | #### ***예선 1라운드*** 324 | * 2018년 4월 2일(월) ~ 2018년 4월 9일(월) 오전 11시 325 | * NSML 리더보드 순위로 2라운드 진출자 선정. 순위가 낮으면 자동 컷오프. 326 | 327 | #### ***예선 2라운드*** 328 | * 2018년 4월 10일(화) 오전 11시 ~ 2018년 4월 16일(월) 오전 11시 329 | * NSML 리더보드 순위로 결선 진출자 선정 330 | 331 | ### 결선 332 | * 2018년 4월 26일(목) ~ 4월 27일(금) 1박 2일 동안 진행 333 | * 결선 참가자에게는 1440 + α NSML 크레딧을 지급합니다. 334 | * NSML 리더보드 순위로 최종 순위를 결정합니다. 335 | 336 | > ※ 1 NSML 크레딧으로 NSML GPU를 1분 사용할 수 있습니다.
337 | >    10 NSML 크레딧 = GPU 1개 * 10분 = GPU 2개 * 5분 사용 338 | 339 | > ※ 예선, 결선 진출자는 개별 안내 드립니다. 340 | 341 | 342 | ## 시상 및 혜택 343 | 344 | * 총 1000만 원 상당의 상금(각 미션별 시상) 및 기념품 345 | * 총 1억 원 상당의 [네이버 클라우드 플랫폼 크레딧](FAQ.md#q-%EB%84%A4%EC%9D%B4%EB%B2%84-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%ED%94%8C%EB%9E%AB%ED%8F%BC-%ED%81%AC%EB%A0%88%EB%94%A7%EC%9D%80-%EB%AD%94%EA%B0%80%EC%9A%94) 지급 346 | * 결선 진출자에게는 티셔츠 등의 기념품 증정 347 | * 우수 참가자 중 네이버 인턴 지원 시 서류 전형 면제 348 | 349 | ## FAQ 350 | * 자주 문의하는 내용을 확인해 보세요! [FAQ.md](FAQ.md) 351 | * NSML에 대해 자주 문의 하는 내용을 공유합니다. [FAQ_NSML.md](FAQ_NSML.md) 352 | 353 | ## 문의 354 | 해커톤 관련 문의는 아래 이메일을 통해 할 수 있습니다.
355 | ~~dl_ai_hackathon_2018@navercorp.com~~ 356 | 357 | ## License 358 | ``` 359 | Copyright 2018 NAVER Corp. 360 | 361 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 362 | associated documentation files (the "Software"), to deal in the Software without restriction, including 363 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 364 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 365 | the following conditions: 366 | 367 | The above copyright notice and this permission notice shall be included in all copies or substantial 368 | portions of the Software. 369 | 370 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 371 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 372 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 373 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 374 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 375 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 376 | ``` 377 | -------------------------------------------------------------------------------- /missions/examples/kin/example/dataset.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Copyright 2018 NAVER Corp. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 7 | associated documentation files (the "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial 13 | portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 17 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 19 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | """ 22 | 23 | 24 | import os 25 | 26 | import numpy as np 27 | 28 | from kor_char_parser import decompose_str_as_one_hot 29 | 30 | 31 | class KinQueryDataset: 32 | """ 33 | 지식인 데이터를 읽어서, tuple (데이터, 레이블)의 형태로 리턴하는 파이썬 오브젝트 입니다. 34 | """ 35 | def __init__(self, dataset_path: str, max_length: int): 36 | """ 37 | 38 | :param dataset_path: 데이터셋 root path 39 | :param max_length: 문자열의 최대 길이 40 | """ 41 | # 데이터, 레이블 각각의 경로 42 | queries_path = os.path.join(dataset_path, 'train', 'train_data') 43 | labels_path = os.path.join(dataset_path, 'train', 'train_label') 44 | 45 | # 지식인 데이터를 읽고 preprocess까지 진행합니다 46 | with open(queries_path, 'rt', encoding='utf8') as f: 47 | self.queries = preprocess(f.readlines(), max_length) 48 | # 지식인 레이블을 읽고 preprocess까지 진행합니다. 49 | with open(labels_path) as f: 50 | self.labels = np.array([[np.float32(x)] for x in f.readlines()]) 51 | 52 | def __len__(self): 53 | """ 54 | 55 | :return: 전체 데이터의 수를 리턴합니다 56 | """ 57 | return len(self.queries) 58 | 59 | def __getitem__(self, idx): 60 | """ 61 | 62 | :param idx: 필요한 데이터의 인덱스 63 | :return: 인덱스에 맞는 데이터, 레이블 pair를 리턴합니다 64 | """ 65 | return self.queries[idx], self.labels[idx] 66 | 67 | 68 | def preprocess(data: list, max_length: int): 69 | """ 70 | 입력을 받아서 딥러닝 모델이 학습 가능한 포맷으로 변경하는 함수입니다. 71 | 기본 제공 알고리즘은 char2vec이며, 기본 모델이 MLP이기 때문에, 입력 값의 크기를 모두 고정한 벡터를 리턴합니다. 72 | 문자열의 길이가 고정값보다 길면 긴 부분을 제거하고, 짧으면 0으로 채웁니다. 73 | 74 | :param data: 문자열 리스트 ([문자열1, 문자열2, ...]) 75 | :param max_length: 문자열의 최대 길이 76 | :return: 벡터 리스트 ([[0, 1, 5, 6], [5, 4, 10, 200], ...]) max_length가 4일 때 77 | """ 78 | vectorized_data = [decompose_str_as_one_hot(datum, warning=False) for datum in data] 79 | zero_padding = np.zeros((len(data), max_length), dtype=np.int32) 80 | for idx, seq in enumerate(vectorized_data): 81 | length = len(seq) 82 | if length >= max_length: 83 | length = max_length 84 | zero_padding[idx, :length] = np.array(seq)[:length] 85 | else: 86 | zero_padding[idx, :length] = np.array(seq) 87 | return zero_padding 88 | -------------------------------------------------------------------------------- /missions/examples/kin/example/kor_char_parser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Copyright 2018 NAVER Corp. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 7 | associated documentation files (the "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial 13 | portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 17 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 19 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | """ 22 | 23 | 24 | cho = "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ" # len = 19 25 | jung = "ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ" # len = 21 26 | jong = "ㄱ/ㄲ/ㄱㅅ/ㄴ/ㄴㅈ/ㄴㅎ/ㄷ/ㄹ/ㄹㄱ/ㄹㅁ/ㄹㅂ/ㄹㅅ/ㄹㅌ/ㄹㅍ/ㄹㅎ/ㅁ/ㅂ/ㅂㅅ/ㅅ/ㅆ/ㅇ/ㅈ/ㅊ/ㅋ/ㅌ/ㅍ/ㅎ".split('/') # len = 27 27 | test = cho + jung + ''.join(jong) 28 | 29 | hangul_length = len(cho) + len(jung) + len(jong) # 67 30 | 31 | 32 | def is_valid_decomposition_atom(x): 33 | return x in test 34 | 35 | 36 | def decompose(x): 37 | in_char = x 38 | if x < ord('가') or x > ord('힣'): 39 | return chr(x) 40 | x = x - ord('가') 41 | y = x // 28 42 | z = x % 28 43 | x = y // 21 44 | y = y % 21 45 | # if there is jong, then is z > 0. So z starts from 1 index. 46 | zz = jong[z - 1] if z > 0 else '' 47 | if x >= len(cho): 48 | print('Unknown Exception: ', in_char, chr(in_char), x, y, z, zz) 49 | return cho[x] + jung[y] + zz 50 | 51 | 52 | def decompose_as_one_hot(in_char, warning=True): 53 | one_hot = [] 54 | # print(ord('ㅣ'), chr(0xac00)) 55 | # [0,66]: hangul / [67,194]: ASCII / [195,245]: hangul danja,danmo / [246,249]: special characters 56 | # Total 250 dimensions. 57 | if ord('가') <= in_char <= ord('힣'): # 가:44032 , 힣: 55203 58 | x = in_char - 44032 # in_char - ord('가') 59 | y = x // 28 60 | z = x % 28 61 | x = y // 21 62 | y = y % 21 63 | # if there is jong, then is z > 0. So z starts from 1 index. 64 | zz = jong[z - 1] if z > 0 else '' 65 | if x >= len(cho): 66 | if warning: 67 | print('Unknown Exception: ', in_char, chr(in_char), x, y, z, zz) 68 | 69 | one_hot.append(x) 70 | one_hot.append(len(cho) + y) 71 | if z > 0: 72 | one_hot.append(len(cho) + len(jung) + (z - 1)) 73 | return one_hot 74 | else: 75 | if in_char < 128: 76 | return [hangul_length + in_char] # 67~ 77 | elif ord('ㄱ') <= in_char <= ord('ㅣ'): 78 | return [hangul_length + 128 + (in_char - 12593)] # 194~ # [ㄱ:12593]~[ㅣ:12643] (len = 51) 79 | elif in_char == ord('♡'): 80 | return [hangul_length + 128 + 51] # 245~ # ♡ 81 | elif in_char == ord('♥'): 82 | return [hangul_length + 128 + 51 + 1] # ♥ 83 | elif in_char == ord('★'): 84 | return [hangul_length + 128 + 51 + 2] # ★ 85 | elif in_char == ord('☆'): 86 | return [hangul_length + 128 + 51 + 3] # ☆ 87 | else: 88 | if warning: 89 | print('Unhandled character:', chr(in_char), in_char) 90 | return [] 91 | 92 | 93 | def decompose_str(string): 94 | return ''.join([decompose(ord(x)) for x in string]) 95 | 96 | 97 | def decompose_str_as_one_hot(string, warning=True): 98 | tmp_list = [] 99 | for x in string: 100 | tmp_list.extend(decompose_as_one_hot(ord(x), warning=warning)) 101 | return tmp_list 102 | -------------------------------------------------------------------------------- /missions/examples/kin/example/main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Copyright 2018 NAVER Corp. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 7 | associated documentation files (the "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial 13 | portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 17 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 19 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | """ 22 | 23 | 24 | import argparse 25 | import os 26 | 27 | import numpy as np 28 | import tensorflow as tf 29 | 30 | import nsml 31 | from nsml import DATASET_PATH, HAS_DATASET, IS_ON_NSML 32 | from dataset import KinQueryDataset, preprocess 33 | 34 | 35 | # DONOTCHANGE: They are reserved for nsml 36 | # This is for nsml leaderboard 37 | def bind_model(sess, config): 38 | # 학습한 모델을 저장하는 함수입니다. 39 | def save(dir_name, *args): 40 | # directory 41 | os.makedirs(dir_name, exist_ok=True) 42 | saver = tf.train.Saver() 43 | saver.save(sess, os.path.join(dir_name, 'model')) 44 | 45 | # 저장한 모델을 불러올 수 있는 함수입니다. 46 | def load(dir_name, *args): 47 | saver = tf.train.Saver() 48 | # find checkpoint 49 | ckpt = tf.train.get_checkpoint_state(dir_name) 50 | if ckpt and ckpt.model_checkpoint_path: 51 | checkpoint = os.path.basename(ckpt.model_checkpoint_path) 52 | saver.restore(sess, os.path.join(dir_name, checkpoint)) 53 | else: 54 | raise NotImplemented('No checkpoint!') 55 | print('Model loaded') 56 | 57 | def infer(raw_data, **kwargs): 58 | """ 59 | 60 | :param raw_data: raw input (여기서는 문자열)을 입력받습니다 61 | :param kwargs: 62 | :return: 63 | """ 64 | # dataset.py에서 작성한 preprocess 함수를 호출하여, 문자열을 벡터로 변환합니다 65 | preprocessed_data = preprocess(raw_data, config.strmaxlen) 66 | # 저장한 모델에 입력값을 넣고 prediction 결과를 리턴받습니다 67 | pred = sess.run(output_sigmoid, feed_dict={x: preprocessed_data}) 68 | clipped = np.array(pred > config.threshold, dtype=np.int) 69 | # DONOTCHANGE: They are reserved for nsml 70 | # 리턴 결과는 [(확률, 0 or 1)] 의 형태로 보내야만 리더보드에 올릴 수 있습니다. 리더보드 결과에 확률의 값은 영향을 미치지 않습니다 71 | return list(zip(pred.flatten(), clipped.flatten())) 72 | 73 | # DONOTCHANGE: They are reserved for nsml 74 | # nsml에서 지정한 함수에 접근할 수 있도록 하는 함수입니다. 75 | nsml.bind(save=save, load=load, infer=infer) 76 | 77 | 78 | def _batch_loader(iterable, n=1): 79 | """ 80 | 데이터를 배치 사이즈만큼 잘라서 보내주는 함수입니다. PyTorch의 DataLoader와 같은 역할을 합니다 81 | 82 | :param iterable: 데이터 list, 혹은 다른 포맷 83 | :param n: 배치 사이즈 84 | :return: 85 | """ 86 | length = len(iterable) 87 | for n_idx in range(0, length, n): 88 | yield iterable[n_idx:min(n_idx + n, length)] 89 | 90 | 91 | def weight_variable(shape): 92 | initial = tf.truncated_normal(shape, stddev=0.1) 93 | return tf.Variable(initial) 94 | 95 | 96 | def bias_variable(shape): 97 | initial = tf.constant(0.1, shape=shape) 98 | return tf.Variable(initial) 99 | 100 | 101 | if __name__ == '__main__': 102 | args = argparse.ArgumentParser() 103 | # DONOTCHANGE: They are reserved for nsml 104 | args.add_argument('--mode', type=str, default='train') 105 | args.add_argument('--pause', type=int, default=0) 106 | args.add_argument('--iteration', type=str, default='0') 107 | 108 | # User options 109 | args.add_argument('--output', type=int, default=1) 110 | args.add_argument('--epochs', type=int, default=10) 111 | args.add_argument('--batch', type=int, default=2000) 112 | args.add_argument('--strmaxlen', type=int, default=400) 113 | args.add_argument('--embedding', type=int, default=8) 114 | args.add_argument('--threshold', type=float, default=0.5) 115 | config = args.parse_args() 116 | 117 | if not HAS_DATASET and not IS_ON_NSML: # It is not running on nsml 118 | DATASET_PATH = '../sample_data/kin/' 119 | 120 | # 모델의 specification 121 | input_size = config.embedding*config.strmaxlen 122 | output_size = 1 123 | hidden_layer_size = 200 124 | learning_rate = 0.001 125 | character_size = 251 126 | 127 | x = tf.placeholder(tf.int32, [None, config.strmaxlen]) 128 | y_ = tf.placeholder(tf.float32, [None, output_size]) 129 | # 임베딩 130 | char_embedding = tf.get_variable('char_embedding', [character_size, config.embedding]) 131 | embedded = tf.nn.embedding_lookup(char_embedding, x) 132 | 133 | # 첫 번째 레이어 134 | first_layer_weight = weight_variable([input_size, hidden_layer_size]) 135 | first_layer_bias = bias_variable([hidden_layer_size]) 136 | hidden_layer = tf.matmul(tf.reshape(embedded, (-1, input_size)), 137 | first_layer_weight) + first_layer_bias 138 | 139 | # 두 번째 (아웃풋) 레이어 140 | second_layer_weight = weight_variable([hidden_layer_size, output_size]) 141 | second_layer_bias = bias_variable([output_size]) 142 | output = tf.matmul(hidden_layer, second_layer_weight) + second_layer_bias 143 | output_sigmoid = tf.sigmoid(output) 144 | 145 | # loss와 optimizer 146 | binary_cross_entropy = tf.reduce_mean(-(y_ * tf.log(output_sigmoid)) - (1-y_) * tf.log(1-output_sigmoid)) 147 | train_step = tf.train.AdamOptimizer(learning_rate).minimize(binary_cross_entropy) 148 | 149 | sess = tf.InteractiveSession() 150 | tf.global_variables_initializer().run() 151 | 152 | # DONOTCHANGE: Reserved for nsml 153 | bind_model(sess=sess, config=config) 154 | 155 | # DONOTCHANGE: Reserved for nsml 156 | if config.pause: 157 | nsml.paused(scope=locals()) 158 | 159 | if config.mode == 'train': 160 | # 데이터를 로드합니다. 161 | dataset = KinQueryDataset(DATASET_PATH, config.strmaxlen) 162 | dataset_len = len(dataset) 163 | one_batch_size = dataset_len//config.batch 164 | if dataset_len % config.batch != 0: 165 | one_batch_size += 1 166 | # epoch마다 학습을 수행합니다. 167 | for epoch in range(config.epochs): 168 | avg_loss = 0.0 169 | for i, (data, labels) in enumerate(_batch_loader(dataset, config.batch)): 170 | _, loss = sess.run([train_step, binary_cross_entropy], 171 | feed_dict={x: data, y_: labels}) 172 | print('Batch : ', i + 1, '/', one_batch_size, 173 | ', BCE in this minibatch: ', float(loss)) 174 | avg_loss += float(loss) 175 | print('epoch:', epoch, ' train_loss:', float(avg_loss/one_batch_size)) 176 | nsml.report(summary=True, scope=locals(), epoch=epoch, epoch_total=config.epochs, 177 | train__loss=float(avg_loss/one_batch_size), step=epoch) 178 | # DONOTCHANGE (You can decide how often you want to save the model) 179 | nsml.save(epoch) 180 | 181 | # 로컬 테스트 모드일때 사용합니다 182 | # 결과가 아래와 같이 나온다면, nsml submit을 통해서 제출할 수 있습니다. 183 | # [(0.3, 0), (0.7, 1), ... ] 184 | elif config.mode == 'test_local': 185 | with open(os.path.join(DATASET_PATH, 'train/train_data'), 'rt', encoding='utf-8') as f: 186 | queries = f.readlines() 187 | res = [] 188 | for batch in _batch_loader(queries, config.batch): 189 | temp_res = nsml.infer(batch) 190 | res += temp_res 191 | print(res) -------------------------------------------------------------------------------- /missions/examples/kin/example/setup.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | Copyright 2018 NAVER Corp. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 6 | associated documentation files (the "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial 12 | portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 16 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 17 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 18 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | """ 21 | 22 | 23 | from distutils.core import setup 24 | setup( 25 | name='nsml LSTM kin query', 26 | version='1.0', 27 | description='', 28 | install_requires =[ 29 | ] 30 | ) -------------------------------------------------------------------------------- /missions/examples/kin/sample_data/kin/train/train_data: -------------------------------------------------------------------------------- 1 | 경제가 불안하면 국채를 왜발행하나요?? 국채 발행 이유? 2 | 경제가 불안하면 국채를 왜발행하나요?? 국채를 많이 발행하면 왜 수요가 떨어져요? 3 | 경제가 불안하면 국채를 왜발행하나요?? 국채발행은 왜 필요한가 4 | 경제가 불안하면 국채를 왜발행하나요?? 국채를 발행하며 왜 시장 금리가 올라가나요? 5 | 경제가 불안하면 국채를 왜발행하나요?? 나라가 국채를 발행할때 6 | 국채 발행 이유? 국채를 많이 발행하면 왜 수요가 떨어져요? 7 | 국채 발행 이유? 국채발행은 왜 필요한가 8 | 국채 발행 이유? 국채를 발행하며 왜 시장 금리가 올라가나요? 9 | 국채 발행 이유? 나라가 국채를 발행할때 10 | 외환보유고 에 관한 질문 외환보유고에 대해... 11 | 외환보유고 에 관한 질문 한국의 외환보유고에 관한 질문 12 | 외환보유고 에 관한 질문 외환보유고에 대해서 13 | 외환보유고 에 관한 질문 한국의 외환 보유고 (추가내공 有) 14 | 외환보유고에 대해... 한국의 외환보유고에 관한 질문 15 | 외환보유고에 대해... 외환보유고에 대해서 16 | 외환보유고에 대해... 한국의 외환 보유고 (추가내공 有) 17 | 한국의 외환보유고에 관한 질문 외환보유고에 대해서 18 | 한국의 외환보유고에 관한 질문 한국의 외환 보유고 (추가내공 有) 19 | 외환보유고에 대해서 한국의 외환 보유고 (추가내공 有) 20 | 외환보유고 에 관한 질문 외환보유액에 대해서 21 | 외환보유고에 대해... 외환보유액에 대해서 22 | 한국의 외환보유고에 관한 질문 외환보유액에 대해서 23 | 외환보유고에 대해서 외환보유액에 대해서 24 | 한국의 외환 보유고 (추가내공 有) 외환보유액에 대해서 25 | 중국은 달러 보유가 많아서 미국 금융위기에 영향을 가장 적게 받는다고 하는데 사실인가요? 중국에서 미국달러가치가 높아짐에따라 중국은 어떠한영향을 받는지에대해 26 | 중국은 달러 보유가 많아서 미국 금융위기에 영향을 가장 적게 받는다고 하는데 사실인가요? 미국 중국 금리변화가 끼치는 영향? 27 | 중국은 달러 보유가 많아서 미국 금융위기에 영향을 가장 적게 받는다고 하는데 사실인가요? 중국이 미국을 제치고 1위의 경제대국이 되면 달러의 가치는 어떻게 될까요? 28 | 중국은 달러 보유가 많아서 미국 금융위기에 영향을 가장 적게 받는다고 하는데 사실인가요? 미국국채를 일본과 중국이 구입할때 29 | 중국은 달러 보유가 많아서 미국 금융위기에 영향을 가장 적게 받는다고 하는데 사실인가요? 미국 금리인상이 우리나라 환율에 어떤 영향을 미치나요? 30 | 중국에서 미국달러가치가 높아짐에따라 중국은 어떠한영향을 받는지에대해 미국 중국 금리변화가 끼치는 영향? 31 | 중국에서 미국달러가치가 높아짐에따라 중국은 어떠한영향을 받는지에대해 중국이 미국을 제치고 1위의 경제대국이 되면 달러의 가치는 어떻게 될까요? 32 | 중국에서 미국달러가치가 높아짐에따라 중국은 어떠한영향을 받는지에대해 미국국채를 일본과 중국이 구입할때 33 | 중국에서 미국달러가치가 높아짐에따라 중국은 어떠한영향을 받는지에대해 미국 금리인상이 우리나라 환율에 어떤 영향을 미치나요? 34 | 한-미 통화 스와프체결이 무슨 뜻인가요? 통화스와프가 무슨 뜻이예요? 35 | 한-미 통화 스와프체결이 무슨 뜻인가요? 유상사급이 무슨 뜻인가요? 36 | 한-미 통화 스와프체결이 무슨 뜻인가요? scrap yard가 무슨 뜻인가요?? 37 | 한-미 통화 스와프체결이 무슨 뜻인가요? 컨소시엄이 무슨뜻인가요? 38 | 한-미 통화 스와프체결이 무슨 뜻인가요? Tango가 무슨 뜻인가요 39 | 노동시장의 유연화 노동시장의 유연성이란? 40 | 노동시장의 유연화 노동시장알려주세요. 41 | 노동시장의 유연화 자신의 노동에 대해 매겨지는 시장시세는 정당한가? 42 | 노동시장의 유연화 노동시장 구조개혁 43 | 노동시장의 유연화 노동시장에서 노동자는 수요자인가요 공급자인가요? 44 | 노동시장의 유연성이란? 노동시장알려주세요. 45 | 노동시장의 유연성이란? 자신의 노동에 대해 매겨지는 시장시세는 정당한가? 46 | 노동시장의 유연성이란? 노동시장 구조개혁 47 | 노동시장의 유연성이란? 노동시장에서 노동자는 수요자인가요 공급자인가요? 48 | 브릭스(BRICs)에 대해서 질문좀 할께요 브릭스에 대한 질문 49 | 브릭스(BRICs)에 대해서 질문좀 할께요 브릭스에 대해서 물어볼게있어요 50 | 브릭스에 대한 질문 브릭스에 대해서 물어볼게있어요 51 | 브릭스(BRICs)에 대해서 질문좀 할께요 베네룩스에 대해서 질문 좀 할게요 52 | 브릭스(BRICs)에 대해서 질문좀 할께요 좌수에 대한 질문입니다. 53 | 브릭스(BRICs)에 대해서 질문좀 할께요 외규장각 의궤에대한 질문 54 | 브릭스에 대한 질문 베네룩스에 대해서 질문 좀 할게요 55 | 브릭스에 대한 질문 좌수에 대한 질문입니다. 56 | 브릭스에 대한 질문 외규장각 의궤에대한 질문 57 | 브릭스에 대해서 물어볼게있어요 베네룩스에 대해서 질문 좀 할게요 58 | 브릭스에 대해서 물어볼게있어요 좌수에 대한 질문입니다. 59 | 브릭스에 대해서 물어볼게있어요 외규장각 의궤에대한 질문 60 | "전화국에서 교환기,기지국이 하는 역할이 무엇인지? 기지국이뭐고 전화국이뭔가요?" 61 | "전화국에서 교환기,기지국이 하는 역할이 무엇인지? PCS와 위성 기지국이 머에요?" 62 | "전화국에서 교환기,기지국이 하는 역할이 무엇인지? PCS기지국이 SKT에서 쓰는 기지국보다 좋지 않나요?" 63 | "전화국에서 교환기,기지국이 하는 역할이 무엇인지? 통화란 무엇이며, 통화의 역할은 무엇인가요?" 64 | "전화국에서 교환기,기지국이 하는 역할이 무엇인지? 캐치콜의 원리는 무엇인가요?" 65 | 기지국이뭐고 전화국이뭔가요? PCS와 위성 기지국이 머에요? 66 | 기지국이뭐고 전화국이뭔가요? PCS기지국이 SKT에서 쓰는 기지국보다 좋지 않나요? 67 | "기지국이뭐고 전화국이뭔가요? 통화란 무엇이며, 통화의 역할은 무엇인가요?" 68 | 기지국이뭐고 전화국이뭔가요? 캐치콜의 원리는 무엇인가요? 69 | 가등록이 되었던 폰이라는건 뭔가요 자급제폰이 뭔가요? 70 | 가등록이 되었던 폰이라는건 뭔가요 일시구입폰이뭔가요 71 | 가등록이 되었던 폰이라는건 뭔가요 부품용 폰이 뭔가요? 72 | 가등록이 되었던 폰이라는건 뭔가요 제일 최근에 나온 폰이 뭐에여? 73 | 가등록이 되었던 폰이라는건 뭔가요 자급제폰이 뭐죠 74 | 휴대폰 불법복제란 무엇인가요? 휴대폰복제에대해서궁금합니다. 75 | 휴대폰 불법복제란 무엇인가요? 휴대폰 복제란? 76 | 휴대폰복제에대해서궁금합니다. 휴대폰 복제란? 77 | 휴대폰 불법복제란 무엇인가요? 불법 복제가 뭔가요?? 78 | 휴대폰 불법복제란 무엇인가요? 복제란 무엇인가? 79 | 휴대폰 불법복제란 무엇인가요? 복제란 무엇인가요 ? 80 | 휴대폰복제에대해서궁금합니다. 불법 복제가 뭔가요?? 81 | 휴대폰복제에대해서궁금합니다. 복제란 무엇인가? 82 | 휴대폰복제에대해서궁금합니다. 복제란 무엇인가요 ? 83 | 휴대폰 복제란? 불법 복제가 뭔가요?? 84 | 휴대폰 복제란? 복제란 무엇인가? 85 | 휴대폰 복제란? 복제란 무엇인가요 ? 86 | 왜 휴대폰으로 전화 할땐 지역번호를 눌러야 할까요? 집전화는 지역번호를 누르지않아도되고 휴대폰은 눌러야하는 이유? 87 | 왜 휴대폰으로 전화 할땐 지역번호를 눌러야 할까요? 인터넷에는 왜 휴대폰번호나 집전화번호를 입력하는 것은 안 될까요? 88 | 왜 휴대폰으로 전화 할땐 지역번호를 눌러야 할까요? 휴대폰전화번호 뒷자리 4번과 자기 집 전화번호 뒷자리 4번과 같은 이유? 89 | 왜 휴대폰으로 전화 할땐 지역번호를 눌러야 할까요? 한개 휴대폰으로 2개이상 전화번호사용?(내공20) 90 | 왜 휴대폰으로 전화 할땐 지역번호를 눌러야 할까요? 119 장난전화 하면 안되는 이유(숙제) 91 | 집전화는 지역번호를 누르지않아도되고 휴대폰은 눌러야하는 이유? 인터넷에는 왜 휴대폰번호나 집전화번호를 입력하는 것은 안 될까요? 92 | 집전화는 지역번호를 누르지않아도되고 휴대폰은 눌러야하는 이유? 휴대폰전화번호 뒷자리 4번과 자기 집 전화번호 뒷자리 4번과 같은 이유? 93 | 집전화는 지역번호를 누르지않아도되고 휴대폰은 눌러야하는 이유? 한개 휴대폰으로 2개이상 전화번호사용?(내공20) 94 | 집전화는 지역번호를 누르지않아도되고 휴대폰은 눌러야하는 이유? 119 장난전화 하면 안되는 이유(숙제) 95 | 스크랩하는 방법을 알려주세요 스크랩하는 방법 좀 알려주세요~ 96 | 스크랩하는 방법을 알려주세요 스크랩하는 방법좀 알려주세요. 97 | 스크랩하는 방법을 알려주세요 스크랩하기 사용방법좀 알려주세요. 98 | 스크랩하는 방법을 알려주세요 스크랩하는 방법좀 알려주세요 자세히요. 99 | 스크랩하는 방법을 알려주세요 스크랩 방법을 알려주세요!! 100 | 스크랩하는 방법 좀 알려주세요~ 스크랩하는 방법좀 알려주세요. 101 | 스크랩하는 방법 좀 알려주세요~ 스크랩하기 사용방법좀 알려주세요. 102 | 스크랩하는 방법 좀 알려주세요~ 스크랩하는 방법좀 알려주세요 자세히요. 103 | 스크랩하는 방법 좀 알려주세요~ 스크랩 방법을 알려주세요!! 104 | 스크랩하는 방법좀 알려주세요. 스크랩하기 사용방법좀 알려주세요. 105 | 스크랩하는 방법좀 알려주세요. 스크랩하는 방법좀 알려주세요 자세히요. 106 | 스크랩하는 방법좀 알려주세요. 스크랩 방법을 알려주세요!! 107 | 스크랩하기 사용방법좀 알려주세요. 스크랩하는 방법좀 알려주세요 자세히요. 108 | 스크랩하기 사용방법좀 알려주세요. 스크랩 방법을 알려주세요!! 109 | 스크랩하는 방법좀 알려주세요 자세히요. 스크랩 방법을 알려주세요!! 110 | -------------------------------------------------------------------------------- /missions/examples/kin/sample_data/kin/train/train_label: -------------------------------------------------------------------------------- 1 | 1 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 1 11 | 1 12 | 1 13 | 1 14 | 1 15 | 1 16 | 1 17 | 1 18 | 1 19 | 1 20 | 0 21 | 0 22 | 0 23 | 0 24 | 0 25 | 1 26 | 0 27 | 0 28 | 0 29 | 0 30 | 0 31 | 0 32 | 0 33 | 0 34 | 0 35 | 0 36 | 0 37 | 0 38 | 0 39 | 1 40 | 0 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 1 49 | 1 50 | 1 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 1 61 | 0 62 | 0 63 | 0 64 | 0 65 | 0 66 | 0 67 | 0 68 | 0 69 | 0 70 | 0 71 | 0 72 | 0 73 | 0 74 | 1 75 | 1 76 | 1 77 | 0 78 | 0 79 | 0 80 | 0 81 | 0 82 | 0 83 | 0 84 | 0 85 | 0 86 | 1 87 | 0 88 | 0 89 | 0 90 | 0 91 | 0 92 | 0 93 | 0 94 | 0 95 | 1 96 | 1 97 | 1 98 | 1 99 | 1 100 | 1 101 | 1 102 | 1 103 | 1 104 | 1 105 | 1 106 | 1 107 | 1 108 | 1 109 | 1 110 | -------------------------------------------------------------------------------- /missions/examples/movie-review/example/dataset.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Copyright 2018 NAVER Corp. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 7 | associated documentation files (the "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial 13 | portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 17 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 19 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | """ 22 | 23 | import os 24 | 25 | import numpy as np 26 | from torch.utils.data import Dataset 27 | 28 | from kor_char_parser import decompose_str_as_one_hot 29 | 30 | 31 | class MovieReviewDataset(Dataset): 32 | """ 33 | 영화리뷰 데이터를 읽어서, tuple (데이터, 레이블)의 형태로 리턴하는 파이썬 오브젝트 입니다. 34 | """ 35 | def __init__(self, dataset_path: str, max_length: int): 36 | """ 37 | initializer 38 | 39 | :param dataset_path: 데이터셋 root path 40 | :param max_length: 문자열의 최대 길이 41 | """ 42 | # 데이터, 레이블 각각의 경로 43 | data_review = os.path.join(dataset_path, 'train', 'train_data') 44 | data_label = os.path.join(dataset_path, 'train', 'train_label') 45 | 46 | # 영화리뷰 데이터를 읽고 preprocess까지 진행합니다 47 | with open(data_review, 'rt', encoding='utf-8') as f: 48 | self.reviews = preprocess(f.readlines(), max_length) 49 | # 영화리뷰 레이블을 읽고 preprocess까지 진행합니다. 50 | with open(data_label) as f: 51 | self.labels = [np.float32(x) for x in f.readlines()] 52 | 53 | def __len__(self): 54 | """ 55 | 56 | :return: 전체 데이터의 수를 리턴합니다 57 | """ 58 | return len(self.reviews) 59 | 60 | def __getitem__(self, idx): 61 | """ 62 | 63 | :param idx: 필요한 데이터의 인덱스 64 | :return: 인덱스에 맞는 데이터, 레이블 pair를 리턴합니다 65 | """ 66 | return self.reviews[idx], self.labels[idx] 67 | 68 | 69 | def preprocess(data: list, max_length: int): 70 | """ 71 | 입력을 받아서 딥러닝 모델이 학습 가능한 포맷으로 변경하는 함수입니다. 72 | 기본 제공 알고리즘은 char2vec이며, 기본 모델이 MLP이기 때문에, 입력 값의 크기를 모두 고정한 벡터를 리턴합니다. 73 | 문자열의 길이가 고정값보다 길면 긴 부분을 제거하고, 짧으면 0으로 채웁니다. 74 | 75 | :param data: 문자열 리스트 ([문자열1, 문자열2, ...]) 76 | :param max_length: 문자열의 최대 길이 77 | :return: 벡터 리스트 ([[0, 1, 5, 6], [5, 4, 10, 200], ...]) max_length가 4일 때 78 | """ 79 | vectorized_data = [decompose_str_as_one_hot(datum, warning=False) for datum in data] 80 | zero_padding = np.zeros((len(data), max_length), dtype=np.int32) 81 | for idx, seq in enumerate(vectorized_data): 82 | length = len(seq) 83 | if length >= max_length: 84 | length = max_length 85 | zero_padding[idx, :length] = np.array(seq)[:length] 86 | else: 87 | zero_padding[idx, :length] = np.array(seq) 88 | return zero_padding 89 | -------------------------------------------------------------------------------- /missions/examples/movie-review/example/kor_char_parser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Copyright 2018 NAVER Corp. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 7 | associated documentation files (the "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial 13 | portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 17 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 19 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | """ 22 | 23 | cho = "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ" # len = 19 24 | jung = "ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ" # len = 21 25 | # len = 27 26 | jong = "ㄱ/ㄲ/ㄱㅅ/ㄴ/ㄴㅈ/ㄴㅎ/ㄷ/ㄹ/ㄹㄱ/ㄹㅁ/ㄹㅂ/ㄹㅅ/ㄹㅌ/ㄹㅍ/ㄹㅎ/ㅁ/ㅂ/ㅂㅅ/ㅅ/ㅆ/ㅇ/ㅈ/ㅊ/ㅋ/ㅌ/ㅍ/ㅎ".split( 27 | '/') 28 | test = cho + jung + ''.join(jong) 29 | 30 | hangul_length = len(cho) + len(jung) + len(jong) # 67 31 | 32 | 33 | def is_valid_decomposition_atom(x): 34 | return x in test 35 | 36 | 37 | def decompose(x): 38 | in_char = x 39 | if x < ord('가') or x > ord('힣'): 40 | return chr(x) 41 | x = x - ord('가') 42 | y = x // 28 43 | z = x % 28 44 | x = y // 21 45 | y = y % 21 46 | # if there is jong, then is z > 0. So z starts from 1 index. 47 | zz = jong[z - 1] if z > 0 else '' 48 | if x >= len(cho): 49 | print('Unknown Exception: ', in_char, chr(in_char), x, y, z, zz) 50 | return cho[x] + jung[y] + zz 51 | 52 | 53 | def decompose_as_one_hot(in_char, warning=True): 54 | one_hot = [] 55 | # print(ord('ㅣ'), chr(0xac00)) 56 | # [0,66]: hangul / [67,194]: ASCII / [195,245]: hangul danja,danmo / [246,249]: special characters 57 | # Total 250 dimensions. 58 | if ord('가') <= in_char <= ord('힣'): # 가:44032 , 힣: 55203 59 | x = in_char - 44032 # in_char - ord('가') 60 | y = x // 28 61 | z = x % 28 62 | x = y // 21 63 | y = y % 21 64 | # if there is jong, then is z > 0. So z starts from 1 index. 65 | zz = jong[z - 1] if z > 0 else '' 66 | if x >= len(cho): 67 | if warning: 68 | print('Unknown Exception: ', in_char, 69 | chr(in_char), x, y, z, zz) 70 | 71 | one_hot.append(x) 72 | one_hot.append(len(cho) + y) 73 | if z > 0: 74 | one_hot.append(len(cho) + len(jung) + (z - 1)) 75 | return one_hot 76 | else: 77 | if in_char < 128: 78 | result = hangul_length + in_char # 67~ 79 | elif ord('ㄱ') <= in_char <= ord('ㅣ'): 80 | # 194~ # [ㄱ:12593]~[ㅣ:12643] (len = 51) 81 | result = hangul_length + 128 + (in_char - 12593) 82 | elif in_char == ord('♡'): 83 | result = hangul_length + 128 + 51 # 245~ # ♡ 84 | elif in_char == ord('♥'): 85 | result = hangul_length + 128 + 51 + 1 # ♥ 86 | elif in_char == ord('★'): 87 | result = hangul_length + 128 + 51 + 2 # ★ 88 | elif in_char == ord('☆'): 89 | result = hangul_length + 128 + 51 + 3 # ☆ 90 | else: 91 | if warning: 92 | print('Unhandled character:', chr(in_char), in_char) 93 | # unknown character 94 | result = hangul_length + 128 + 51 + 4 # for unknown character 95 | 96 | return [result] 97 | 98 | 99 | def decompose_str(string): 100 | return ''.join([decompose(ord(x)) for x in string]) 101 | 102 | 103 | def decompose_str_as_one_hot(string, warning=True): 104 | tmp_list = [] 105 | for x in string: 106 | da = decompose_as_one_hot(ord(x), warning=warning) 107 | tmp_list.extend(da) 108 | return tmp_list 109 | -------------------------------------------------------------------------------- /missions/examples/movie-review/example/main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Copyright 2018 NAVER Corp. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 7 | associated documentation files (the "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial 13 | portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 17 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 19 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | """ 22 | 23 | import argparse 24 | import os 25 | 26 | import numpy as np 27 | import torch 28 | 29 | from torch.autograd import Variable 30 | from torch import nn, optim 31 | from torch.utils.data import DataLoader 32 | 33 | import nsml 34 | from dataset import MovieReviewDataset, preprocess 35 | from nsml import DATASET_PATH, HAS_DATASET, GPU_NUM, IS_ON_NSML 36 | 37 | 38 | # DONOTCHANGE: They are reserved for nsml 39 | # This is for nsml leaderboard 40 | def bind_model(model, config): 41 | # 학습한 모델을 저장하는 함수입니다. 42 | def save(filename, *args): 43 | checkpoint = { 44 | 'model': model.state_dict() 45 | } 46 | torch.save(checkpoint, filename) 47 | 48 | # 저장한 모델을 불러올 수 있는 함수입니다. 49 | def load(filename, *args): 50 | checkpoint = torch.load(filename) 51 | model.load_state_dict(checkpoint['model']) 52 | print('Model loaded') 53 | 54 | def infer(raw_data, **kwargs): 55 | """ 56 | 57 | :param raw_data: raw input (여기서는 문자열)을 입력받습니다 58 | :param kwargs: 59 | :return: 60 | """ 61 | # dataset.py에서 작성한 preprocess 함수를 호출하여, 문자열을 벡터로 변환합니다 62 | preprocessed_data = preprocess(raw_data, config.strmaxlen) 63 | model.eval() 64 | # 저장한 모델에 입력값을 넣고 prediction 결과를 리턴받습니다 65 | output_prediction = model(preprocessed_data) 66 | point = output_prediction.data.squeeze(dim=1).tolist() 67 | # DONOTCHANGE: They are reserved for nsml 68 | # 리턴 결과는 [(confidence interval, 포인트)] 의 형태로 보내야만 리더보드에 올릴 수 있습니다. 리더보드 결과에 confidence interval의 값은 영향을 미치지 않습니다 69 | return list(zip(np.zeros(len(point)), point)) 70 | 71 | # DONOTCHANGE: They are reserved for nsml 72 | # nsml에서 지정한 함수에 접근할 수 있도록 하는 함수입니다. 73 | nsml.bind(save=save, load=load, infer=infer) 74 | 75 | 76 | def collate_fn(data: list): 77 | """ 78 | PyTorch DataLoader에서 사용하는 collate_fn 입니다. 79 | 기본 collate_fn가 리스트를 flatten하기 때문에 벡터 입력에 대해서 사용이 불가능해, 직접 작성합니다. 80 | 81 | :param data: 데이터 리스트 82 | :return: 83 | """ 84 | review = [] 85 | label = [] 86 | for datum in data: 87 | review.append(datum[0]) 88 | label.append(datum[1]) 89 | # 각각 데이터, 레이블을 리턴 90 | return review, np.array(label) 91 | 92 | 93 | class Regression(nn.Module): 94 | """ 95 | 영화리뷰 예측을 위한 Regression 모델입니다. 96 | """ 97 | def __init__(self, embedding_dim: int, max_length: int): 98 | """ 99 | initializer 100 | 101 | :param embedding_dim: 데이터 임베딩의 크기입니다 102 | :param max_length: 인풋 벡터의 최대 길이입니다 (첫 번째 레이어의 노드 수에 연관) 103 | """ 104 | super(Regression, self).__init__() 105 | self.embedding_dim = embedding_dim 106 | self.character_size = 251 107 | self.output_dim = 1 # Regression 108 | self.max_length = max_length 109 | 110 | # 임베딩 111 | self.embeddings = nn.Embedding(self.character_size, self.embedding_dim) 112 | 113 | # 첫 번째 레이어 114 | self.fc1 = nn.Linear(self.max_length * self.embedding_dim, 200) 115 | # 두 번째 (아웃풋) 레이어 116 | self.fc2 = nn.Linear(200, 1) 117 | 118 | def forward(self, data: list): 119 | """ 120 | 121 | :param data: 실제 입력값 122 | :return: 123 | """ 124 | # 임베딩의 차원 변환을 위해 배치 사이즈를 구합니다. 125 | batch_size = len(data) 126 | # list로 받은 데이터를 torch Variable로 변환합니다. 127 | data_in_torch = Variable(torch.from_numpy(np.array(data)).long()) 128 | # 만약 gpu를 사용중이라면, 데이터를 gpu 메모리로 보냅니다. 129 | if GPU_NUM: 130 | data_in_torch = data_in_torch.cuda() 131 | # 뉴럴네트워크를 지나 결과를 출력합니다. 132 | embeds = self.embeddings(data_in_torch) 133 | hidden = self.fc1(embeds.view(batch_size, -1)) 134 | # 영화 리뷰가 1~10점이기 때문에, 스케일을 맞춰줍니다 135 | output = torch.sigmoid(self.fc2(hidden)) * 9 + 1 136 | return output 137 | 138 | 139 | if __name__ == '__main__': 140 | args = argparse.ArgumentParser() 141 | # DONOTCHANGE: They are reserved for nsml 142 | args.add_argument('--mode', type=str, default='train') 143 | args.add_argument('--pause', type=int, default=0) 144 | args.add_argument('--iteration', type=str, default='0') 145 | 146 | # User options 147 | args.add_argument('--output', type=int, default=1) 148 | args.add_argument('--epochs', type=int, default=10) 149 | args.add_argument('--batch', type=int, default=2000) 150 | args.add_argument('--strmaxlen', type=int, default=200) 151 | args.add_argument('--embedding', type=int, default=8) 152 | config = args.parse_args() 153 | 154 | if not HAS_DATASET and not IS_ON_NSML: # It is not running on nsml 155 | DATASET_PATH = '../sample_data/movie_review/' 156 | 157 | model = Regression(config.embedding, config.strmaxlen) 158 | if GPU_NUM: 159 | model = model.cuda() 160 | 161 | # DONOTCHANGE: Reserved for nsml use 162 | bind_model(model, config) 163 | 164 | criterion = nn.MSELoss() 165 | optimizer = optim.Adam(model.parameters(), lr=0.01) 166 | 167 | # DONOTCHANGE: They are reserved for nsml 168 | if config.pause: 169 | nsml.paused(scope=locals()) 170 | 171 | 172 | # 학습 모드일 때 사용합니다. (기본값) 173 | if config.mode == 'train': 174 | # 데이터를 로드합니다. 175 | dataset = MovieReviewDataset(DATASET_PATH, config.strmaxlen) 176 | train_loader = DataLoader(dataset=dataset, 177 | batch_size=config.batch, 178 | shuffle=True, 179 | collate_fn=collate_fn, 180 | num_workers=2) 181 | total_batch = len(train_loader) 182 | # epoch마다 학습을 수행합니다. 183 | for epoch in range(config.epochs): 184 | avg_loss = 0.0 185 | for i, (data, labels) in enumerate(train_loader): 186 | predictions = model(data) 187 | label_vars = Variable(torch.from_numpy(labels)) 188 | if GPU_NUM: 189 | label_vars = label_vars.cuda() 190 | loss = criterion(predictions, label_vars) 191 | if GPU_NUM: 192 | loss = loss.cuda() 193 | 194 | optimizer.zero_grad() 195 | loss.backward() 196 | optimizer.step() 197 | print('Batch : ', i + 1, '/', total_batch, 198 | ', MSE in this minibatch: ', loss.data[0]) 199 | avg_loss += loss.data[0] 200 | print('epoch:', epoch, ' train_loss:', float(avg_loss/total_batch)) 201 | # nsml ps, 혹은 웹 상의 텐서보드에 나타나는 값을 리포트하는 함수입니다. 202 | # 203 | nsml.report(summary=True, scope=locals(), epoch=epoch, epoch_total=config.epochs, 204 | train__loss=float(avg_loss/total_batch), step=epoch) 205 | # DONOTCHANGE (You can decide how often you want to save the model) 206 | nsml.save(epoch) 207 | 208 | # 로컬 테스트 모드일때 사용합니다 209 | # 결과가 아래와 같이 나온다면, nsml submit을 통해서 제출할 수 있습니다. 210 | # [(0.0, 9.045), (0.0, 5.91), ... ] 211 | elif config.mode == 'test_local': 212 | with open(os.path.join(DATASET_PATH, 'train/train_data'), 'rt', encoding='utf-8') as f: 213 | reviews = f.readlines() 214 | res = nsml.infer(reviews) 215 | print(res) -------------------------------------------------------------------------------- /missions/examples/movie-review/example/setup.py: -------------------------------------------------------------------------------- 1 | #nsml: floydhub/pytorch:0.3.0-gpu.cuda8cudnn6-py3.17 2 | 3 | """ 4 | Copyright 2018 NAVER Corp. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 7 | associated documentation files (the "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial 13 | portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 17 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 19 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | """ 22 | 23 | from distutils.core import setup 24 | setup( 25 | name='nsml movie review', 26 | version='1.0', 27 | description='', 28 | install_requires=[ 29 | ] 30 | ) 31 | -------------------------------------------------------------------------------- /missions/examples/movie-review/sample_data/movie_review/train/train_data: -------------------------------------------------------------------------------- 1 | 우리 집에는 한동안 햇닭 세 마리가 있었다 2 | 나는 부엌칼을 장 항아리에 갖다 대고 잠깐 갈았다 3 | 붉은 녹이 없어지고 시퍼렇게 날이 섰다 4 | 작은 공기 하나를 가지고 대문간으로 갔다 5 | 한편 발로 붙들려 매인 두 발을 곽 밟았다 6 | 칼로 거기를 몇 번 베었다 7 | 몹시 아프고 괴로운지 펼떡펼떡 두 발을 놀리고 온몸을 푸덕푸덕한다 8 | 나는 더욱 발에다 힘을 주고 손에 힘을 주어 목을 곽 붙잡고 또 몇 차례 베었다 9 | 닭의 목에서는 붉은 피가 줄줄 흘러서 공기에 방울방울 떨어진다 10 | 한참 붙들고 피가 나오고 죽기를 기다렸다 11 | 나는 잊어버렸던 듯이 얼른 숨구멍을 찾아서 베었다 12 | 씨르륵 소리가 나고 한 번 푸르르 떨더니 그만 늘어진다 13 | 먼 훗날 당신이 찾으시면 14 | 그때에 내 말이 잊었노라 15 | 당신이 속으로 나무라면 16 | 「무척 그리다가 잊었노라」 17 | 그래도 당신이 나무라면 18 | 「믿기지 않아서 잊었노라」 19 | 오늘도 어제도 아니 잊고 20 | 먼 훗날 그때에 「잊었노라」 21 | 우리 집 뒷산에는 풀이 푸르고 22 | 숲사이의 시냇물 모래 바닥은 23 | 파아란 풀 그림자 떠서 흘러요 24 | 그리운 우리 임은 어디 계신고 25 | 날마다 피어나는 우리 임 생각 26 | 날마다 뒷산에 홀로 앉아서 27 | 날마다 풀을 따서 물에 던져요 28 | 흘러가는 시내의 물에 흘러서 29 | 내어던진 풀잎은 엷게 떠갈제 30 | 물살이 헤적헤적 품을 헤쳐요 31 | 가엾은 이내 속을 둘 곳 없어서 32 | 날마다 풀을 따서 물에 던지고 33 | 흘러가는 잎이나 맘 헤보아요 34 | 산(山) 위에 올라서서 바라다보면 35 | 가로막힌 바다를 마주 건너서 36 | 님 계시는 마을이 내 눈앞으로 37 | 꿈 하늘 하늘같이 떠오릅니다 38 | 흰 모래 모래 비낀 선창(船倉)가에는 39 | 한가한 뱃노래가 멀리 잦으며 40 | 날 저물고 안개는 깊이 덮여서 41 | 흩어지는 물꽃뿐 안득입니다 42 | 이윽고 밤 어두운 물새가 울면 43 | 물결조차 하나 둘 배는 떠나서 44 | 저 멀리 한바다로 아주 바다로 45 | 마치 가랑잎같이 떠나갑니다 46 | 나는 혼자 산(山)에서 밤을 새우고 47 | 아침해 붉은 볕에 몸을 씻으며 48 | 귀 기울고 솔곳이 엿듣노라면 49 | 님 계신 창(窓) 아래로 가는 물노래 50 | 흔들어 깨우치는 물노래에는 51 | 내 님이 놀라 일어나 찾으신대도 52 | 내 몸은 산(山) 위에서 그 산(山) 위에서 53 | 고이 깊이 잠들어 다 모릅니다 54 | 고요하고 어두운 밤이 오면은 55 | 어스러한 등(燈)불에 밤이 오면은 56 | 외로움에 아픔에 다만 혼자서 57 | 하염없는 눈물에 저는 웁니다 58 | 제 한 몸도 예전엔 눈물 모르고 59 | 조그만한 세상(世上)을 보냈습니다 60 | 그때는 지난날의 옛이야기도 61 | 아무 설움 모르고 외웠습니다 62 | 그런데 우리 님이 가신 뒤에는 63 | 아주 저를 버리고 가신 뒤에는 64 | 전(前)날에 제게 있던 모든 것들이 65 | 가지가지 없어지고 말았습니다 66 | 그러나 그 한때에 외워 두었던 67 | 옛이야기뿐만은 남았습니다 68 | 나날이 짙어가는 옛이야기는 69 | 부질없이 제 몸을 울려 줍니다 70 | 그리운 우리 님의 맑은 노래는 71 | 언제나 제 가슴에 젖어 있어요 72 | 긴 날을 문 밖에서 서서 들어도 73 | 그리운 우리 님의 고운 노래는 74 | 해지고 저무도록 귀에 들려요 75 | 밤들고 잠드도록 귀에 들려요 76 | 고이도 흔들리는 노랫가락에 77 | 내 잠은 그만이나 깊이 들어요 78 | 고적한 잠자리에 홀로 누워도 79 | 내 잠은 포스근히 깊이 들어요 80 | 그러나 자다깨면 님의 노래는 81 | 하나도 남김 없이 잃어버려요 82 | 들으며 듣는 대로 님의 노래는 83 | 하나도 남김없이 잊고 말아요. 84 | 세월이 물과 같이 흐른 두 달은 85 | 길어둔 독엣 물도 찌었지마는 86 | 가면서 함께 가자 하던 말씀은 87 | 살아서 살을 맞는 표적이외다. 88 | 봄 풀은 봄이 되면 돋아나지만 89 | "나무는 밑구루를 꺾은 셈이요," 90 | 새라면 두 죽지가 상한 셈이라 91 | 내 몸에 꽃필 날은 다시 없구나. 92 | 밤마다 닭소리라 날이 첫시면 93 | "당신의 넋맞이로 나가 볼 때요," 94 | 그믐에 지는 달이 산에 걸리면 95 | 당신의 길신 가리 차릴 때외다. 96 | 세월은 물과 같이 흘러 가지만 97 | 당신을 아주 잊던 말씀이지만 98 | 동무들 보십시오 해가 집니다 99 | 세상의 모든 것은 빛이 납니다 100 | 이제는 주춤주춤 어둡습니다 101 | 예서 더 저문 때를 밤이랍니다 102 | 물 스치던 돌 위엔 물때 뿐이라 103 | 물때 묻은 조약돌 마른 갈숲이 104 | 이제라고 강(江)물의 터야 아니랴 105 | 빨래 소리 물소리 선녀(仙女)의 노래 106 | 잎새 위에 밤마다 우는 달빛이 107 | "때린다, 부순다, 무너 버린다." 108 | -------------------------------------------------------------------------------- /missions/examples/movie-review/sample_data/movie_review/train/train_label: -------------------------------------------------------------------------------- 1 | 5 2 | 7 3 | 10 4 | 10 5 | 10 6 | 10 7 | 10 8 | 10 9 | 10 10 | 10 11 | 10 12 | 10 13 | 10 14 | 10 15 | 10 16 | 10 17 | 10 18 | 10 19 | 10 20 | 10 21 | 10 22 | 10 23 | 10 24 | 10 25 | 10 26 | 10 27 | 10 28 | 10 29 | 10 30 | 10 31 | 10 32 | 10 33 | 10 34 | 10 35 | 10 36 | 10 37 | 10 38 | 10 39 | 10 40 | 10 41 | 10 42 | 10 43 | 10 44 | 1 45 | 6 46 | 9 47 | 10 48 | 10 49 | 10 50 | 10 51 | 10 52 | 10 53 | 10 54 | 10 55 | 10 56 | 10 57 | 10 58 | 10 59 | 10 60 | 10 61 | 10 62 | 10 63 | 10 64 | 10 65 | 10 66 | 10 67 | 1 68 | 8 69 | 8 70 | 10 71 | 10 72 | 10 73 | 10 74 | 10 75 | 10 76 | 9 77 | 10 78 | 10 79 | 0 80 | 1 81 | 1 82 | 1 83 | 1 84 | 3 85 | 5 86 | 7 87 | 8 88 | 10 89 | 10 90 | 10 91 | 10 92 | 10 93 | 10 94 | 10 95 | 10 96 | 10 97 | 10 98 | 10 99 | 10 100 | 1 101 | 10 102 | 10 103 | 10 104 | 10 105 | 10 106 | 10 107 | 10 108 | -------------------------------------------------------------------------------- /missions/kin.md: -------------------------------------------------------------------------------- 1 | ![banner](../res/kin.jpg) 2 | 3 | # 지식iN 질문 유사도 4 | 5 | **네이버 지식iN 질문 중에서 비슷한 질문을 찾을 수 있을까요?** 6 | 7 | 네이버 지식iN은 열린 지식 공유 커뮤니티를 지향하는 서비스로서, 모든 사용자의 지식과 삶이 풍부해지는 정보 공유 공간입니다. 올라온 질문에 대해 다른 사람들이 자발적으로 답을 달아 지식을 주고 받으며 세상을 더 잘 이해할 수 있게 됐습니다. 8 | 9 | 모든 이슈와 호기심의 향연! 세상에 모든 Q&A가 있는 곳 지식iN! 10 | 2017년에는 무려 **20,566,585**개의 질문이 지식iN을 더욱 풍성하게 했습니다. 하지만 이 많은 질문 중에 비슷한 질문이 있습니다. 11 | 12 | 원하는 질문과 답을 찾기 위해 지식iN을 찾는 사람들에게 비슷한 질문이 많아진다는 것은 검색 시간이 늘어나는 것을 의미합니다. 더 좋은 답을 찾기 위해 많은 비슷한 질문을 찾아봐야 하기 때문입니다. 답변을 해 주는 사람들도 동일한 답변을 여러 번 해야 할 경우가 생깁니다. 13 | 14 | 이러한 문제점을 개선하기 위해 여러분들은 트레이닝 데이터를 학습해 한 쌍의 질문이 유사한지를 판단하는 모델을 개발해야 합니다. 15 | 16 | # 데이터 구조 17 | 18 | | 질문1 | 질문2 | 유사 여부 | 19 | | --------------- | ------------------ | :-----: | 20 | | 재즈란 뭔가요? | 재즈란 무엇인가요? | y | 21 | | 재즈란 무엇이죠? | 모든 재즈의종류 | n | 22 | | 영화포스터는 누가 만들어요? | 영화 포스터 제작은 누가 하나요? | y | 23 | | 영화포스터는 누가 만들어요? | 처음으로 만들어진 영화 포스터는? | n | 24 | 25 | # 데이터 위치 26 | 27 | | 종류 | 위치 | 비고 | 28 | | ------------- | ------------ | ---- | 29 | | **예선 1라운드 트레이닝 데이터** | kin_phase1 | NSML에서 지정 | 30 | | **예선 2라운드 트레이닝 데이터** | kin_phase2 | NSML에서 지정 | 31 | | **결선 트레이닝 데이터** | kin_final | NSML에서 지정 | 32 | | **디버깅용 더미 데이터** | [보기](examples/kin/sample_data/kin/train) |   | 33 | 34 | ## 참고 35 | 36 | * 트레이닝 데이터는 NSML을 통해서만 접근 가능합니다. 37 | * 로컬에서 디버깅을 위해 데이터를 사용해야 한다면 디버깅용 더미 데이터를 사용하세요. 38 | * NSML에서 모델을 평가할 때 자동으로 테스트 데이터를 사용합니다. 39 | * 데이터셋에 대한 자세한 설명은 [튜토리얼](tutorial.md#dataset) 문서를 확인해 주세요. 40 | 41 | # baseline 42 | * [examples/kin/example/](examples/kin/example/) 참고 43 | 44 | # 모델 개발 및 실행 45 | 46 | * NSML을 통해 개발한 모델을 실행할 수 있습니다. 47 | * NSML 크레딧을 보유한 만큼 리소스를 사용할 수 있습니다. 48 | * 모델 개발 및 실행에 대한 자세한 설명은 [튜토리얼](tutorial.md#run) 문서를 확인해 주세요. 49 | 50 | # 모델 평가 51 | 52 | * NSML을 통해 개발한 모델을 평가합니다. 53 | * 평가를 완료하면 NSML 리더보드를 통해 순위를 확인할 수 있습니다. 54 | * 모델 평가 대한 자세한 설명은 [튜토리얼](tutorial.md#evaluate) 문서를 확인해 주세요. 55 | 56 | -------------------------------------------------------------------------------- /missions/movie-review.md: -------------------------------------------------------------------------------- 1 | ![banner](../res/movie.png) 2 | 3 | # 영화 평점 예측 4 | 5 | **보고 싶고 알고 싶은 영화의 모든 것! 네이버 영화 평점을 예측해 보세요!** 6 | 7 | 네이버 영화는 영화 정보, 영화 평, 영화 인물 정보를 한 눈에 볼 수 있고, 영화 예매까지 한꺼번에 할 수 있어서 많은 분들이 좋아하는 서비스입니다. 특히 네이버 영화 평점은 개봉 전 영화에 대한 기대평이나 개봉작에 대한 관람 후 평가를 등록하는 기능입니다. 140자 평과 함께 평점을 등록할 수 있어 영화를 좋아하는 많은 사람이 참고하는 정보가 되고 있습니다. 8 | 9 | 영화와 처음 만나는 곳! 네이버 영화는 어떻게 하면 더 신뢰할 수 있는 평점을 제공할 수 있을까 항상 고민하고 있습니다. 어떠한 영화 평을 작성했을 때 그 영화 평에 가장 합당한 평점을 예측할 수 있다면 더 객관적이고 신뢰할 수 있는 평점이 되지 않을까요? 10 | 11 | 여러분은 이를 위해 기존 영화 평과 평점을 학습해, 주어진 영화 평에 가장 알맞는 평점이 몇 점인지 예측하는 모델을 개발해야 합니다. 12 | 13 | # 데이터 구조 14 | 15 | | 영화 평 | 평점| 16 | | ----- | ---- | 17 | | 영화를 이루는 모든 요소가 완전하다 | 10 | 18 | | 너무 흥미롭고 단 한순간도 지루할틈이 없었다 | 9 | 19 | | 이해는 하나 공감은 할 수 없는 영화 | 7 | 20 | | 진짜 이 영화 무슨 내용인지 모르겠네 | 2 | 21 | 22 | **※ 마스킹 정보** 23 | 24 | **영화명**과 **배우명**은 마스킹 처리되어 있습니다.
25 | **mv**로 시작하는 경우 마스킹된 영화명, **ac**로 시작하는 경우 마스킹된 배우명입니다. 26 | 27 | * 영화명 마스킹 예: mv00041958에 대한 좋은 이상향을 심어주는 영화
28 | * 배우명 마스킹 예: ac00440758의 연기가 매우 인상적이었던 고전영화의 명작
29 | 30 | # 데이터 위치 31 | 32 | | 종류 | 위치 | 비고 | 33 | | ------------- | ------------ | ---- | 34 | | **예선 1라운드 트레이닝 데이터** | movie_phase1 | NSML에서 지정 | 35 | | **예선 2라운드 트레이닝 데이터** | movie_phase2 | NSML에서 지정 | 36 | | **결선 트레이닝 데이터** | movie_final | NSML에서 지정 | 37 | | **디버깅용 더미 데이터** | [보기](examples/movie-review/sample_data/movie_review/train) |   | 38 | 39 | ## 참고 40 | 41 | * 트레이닝 데이터는 NSML을 통해서만 접근 가능합니다. 42 | * 로컬에서 디버깅을 위해 데이터를 사용해야 한다면 디버깅용 더미 데이터를 사용하세요. 43 | * NSML에서 모델을 평가할 때 자동으로 테스트 데이터를 사용합니다. 44 | * 데이터셋에 관한 자세한 설명은 [튜토리얼](tutorial.md#dataset) 문서를 확인해 주세요. 45 | 46 | # baseline 47 | * [examples/movie-review/example/](examples/movie-review/example/) 참고 48 | 49 | # 모델 개발 및 실행 50 | 51 | * NSML을 통해 개발한 모델을 실행할 수 있습니다. 52 | * NSML 크레딧을 보유한 만큼 리소스를 사용할 수 있습니다. 53 | * 모델 개발 및 실행에 대한 자세한 설명은 [튜토리얼](tutorial.md#run) 문서를 확인해 주세요. 54 | 55 | # 모델 평가 56 | 57 | * NSML을 통해 개발한 모델을 평가합니다. 58 | * 평가를 완료하면 NSML 리더보드를 통해 순위를 확인할 수 있습니다. 59 | * 모델 평가 대한 자세한 설명은 [튜토리얼](tutorial.md#evaluate) 문서를 확인해 주세요. 60 | 61 | -------------------------------------------------------------------------------- /missions/tutorial.md: -------------------------------------------------------------------------------- 1 | # 네이버 AI 해커톤 2018 NSML 튜토리얼 2 | 3 | 이 튜토리얼은 NSML을 설치하고 로그인하는 방법과 기본적인 명령어를 사용하는 방법, 모델을 구현할 때 참고할 사항을 간략하게 설명합니다. 4 | 5 | NSML에 대한 더욱 자세한 설명은 다음 자료에서 확인할 수 있습니다. 6 | 7 | * [deview 2017 영상](http://tv.naver.com/v/2301994) 8 | * [NIPS 2017 영상](https://www.youtube.com/watch?v=3Qub0wL9Gwc&t=777s) 9 | * [NSML: A Machine Learning Platform That Enables You to Focus on Your Models(논문)](https://arxiv.org/pdf/1712.05902.pdf) 10 | 11 | ## 시작하기 12 | 13 | 1. Quick-Guide : https://github.com/naver/ai-hackathon-2018/blob/master/quick-guide.md 14 | 15 | ### 설치 16 | 17 | 1. [Download NSML](https://hack.nsml.navercorp.com/download)에서 플랫폼에 맞는 클라이언트를 다운로드합니다. 18 | 2. 다운로드한 파일을 압축 해제합니다. 19 | 20 | ### 로그인 21 | 22 | 1. [NSML 웹](https://hack.nsml.navercorp.com)에서 Github 아이디를 이용해 로그인합니다. 23 | 2. 다음 명령어를 실행하여 NSML 클라이언트에 로그인합니다. 24 | 25 | ```bash 26 | $ PATH/TO/CLIENT/nsml login 27 | ``` 28 | 29 | 참고: 로그인은 160시간마다 만료됩니다. 160시간 후에 재시도할 때는 같은 과정으로 다시 로그인해주세요. 30 | 31 | 3. (선택) NSML 클라이언트를 로컬 머신 어디에서나 간단하게 이용할 수 있도록 `~/.bashrc` 혹은 `~/.bash_profile`에 아래와 같이 alias를 생성합니다. 32 | 33 | ```shell 34 | alias cmdyouwant = "/PATH/TO/CLIENT/nsml" 35 | # example 36 | alias nsml="/Downloads/nsml_client.macos.x86_64/nsml" 37 | ``` 38 | 39 | 이 튜토리얼에서는 alias를 `nsml`로 지정했다고 가정하고 튜토리얼을 진행하겠습니다. 40 | 41 | 이제 NSML을 이용하기 위한 준비가 끝났습니다. 42 | 43 | ## 명령어 사용하기 44 | 45 | 사용할 수 있는 명령어 목록을 보고 싶다면 다음 명령어를 실행하여 간단하게 확인할 수 있습니다. 46 | 47 | ```bash 48 | $ nsml 49 | ``` 50 | 51 | 각 명령어의 사용법과 옵션을 확인하고 싶다면 다음 명령어를 실행합니다. 이 튜토리얼에서는 기본적인 옵션만 설명합니다. 52 | 53 | ```bash 54 | $ nsml COMMAND --help 55 | # example 56 | $ nsml login --help 57 | ``` 58 | 59 | 이제 사용할 수 있는 명령어를 살펴보겠습니다. 60 | 61 | ### credit 62 | 63 | 먼저, 여러분에게 주어진 크레딧을 확인해보겠습니다. 64 | 65 | ```bash 66 | $ nsml credit 67 | # User : USER_NAME credit 000 68 | ``` 69 | 70 | 크레딧은 [NSML 웹](https://hack.nsml.navercorp.com)에서 오른쪽 상단의 profile을 클릭하여 확인할 수도 있습니다. 71 | 72 | 크레딧은 하나의 GPU를 1분 사용하면 1만큼 차감됩니다. 남은 크레딧이 없으면 모델을 학습시키려 할 때 `NOT_ENOUGH_CREDIT`이라는 메시지가 표시됩니다. 해커톤을 진행하는 동안 자신에게 남은 크레딧을 수시로 확인하세요. 73 | 74 | ### dataset 75 | 76 | 해커톤을 위해 필요한 데이터는 모두 NSML 플랫폼에 있습니다. `dataset` 명령어를 실행하여 데이터셋 목록을 확인할 수 있습니다. 77 | 78 | ```bash 79 | $ nsml dataset ls 80 | ``` 81 | 82 | 다음과 같은 명령어를 실행하여 특정 문자열로 시작하는 데이터를 찾을 수도 있습니다. 83 | 84 | ```bash 85 | $ nsml dataset search 'kin_*' 86 | ``` 87 | 88 | ### run 89 | 90 | 홈페이지에는 해커톤의 두 문제의 예시가 업로드되어 있습니다. 그 중 지식iN 질문 유사도 모델을 구현한 `lstm.py` 파일을 이용해 설명드리겠습니다. 2개의 GPU를 사용하여 `kin_phase1` 데이터셋으로 이 모델을 학습시켜 보겠습니다. 91 | 92 | ```bash 93 | # example 94 | $ nsml run -d kin_phase1 -g 2 -e main.py 95 | ``` 96 | 97 | * `-d` 옵션은 사용할 데이터셋을 지정합니다. 98 | * `-g` 옵션은 사용할 GPU의 개수를 지정합니다. NSML에서 실행하는 모든 모델은 기본적으로 GPU 한 개가 할당되므로, GPU를 한 개 사용하는 경우 따로 지정하지 않아도 됩니다. 99 | * `-e` 옵션은 소스를 실행할 엔트리 포인트를 지정합니다. 만약 엔트리 포인트가 `main.py`라면 따로 지정하지 않아도 됩니다. 100 | 101 | 이 명령어를 실행하면 다음과 같이 세션이 하나 시작되었음을 알려주는 메시지가 표시됩니다. 102 | 103 | ```bash 104 | ........... 105 | Session YOUR_ID/kin_phase1/SESSION_NUMBER started. 106 | ``` 107 | 108 | 지금부터는 세션 정보인 `YOUR_ID/kin_phase1/SESSION_NUMBER`를 간단하게 `SESSION_NAME`(세션명)이라고 하겠습니다. 109 | 110 | ### 참고: GPU 사용 개수 지정 111 | 112 | `-g` 옵션을 사용하여 GPU 사용 개수를 지정하는 경우, 모델에서 다음과 같이 `from nsml import GPU_NUM`으로 GPU 사용 개수(`GPU_NUM`)를 호출하여 이 값으로 cuda 사용 여부를 판단해야 합니다. 113 | 114 | ```python 115 | # example 116 | from nsml import GPU_NUM 117 | . 118 | . 119 | . 120 | if __name__ == "__main__": 121 | if GPU_NUM: 122 | torch.cuda.manual_seed(1) 123 | ``` 124 | 125 | ### 참고: argument 전달 126 | 127 | 작성한 모델에 별도의 argument가 필요하다면 `run`을 실행할 때 다음과 같이 `-a "--argname value"` 옵션을 사용하여 argument를 전달할 수 있습니다. 128 | 129 | ```bash 130 | $ nsml run -d kin_phase1 -g 2 -e main.py -a "--epochs 1000" 131 | ``` 132 | 133 | ### logs 134 | 135 | 앞에서 실행한 세션의 학습 진행 상황을 살펴보겠습니다. `logs` 명령어를 실행하면 현재까지의 학습 진행 상황을 보여주는 로그가 출력됩니다. 136 | 137 | ```bash 138 | $ nsml logs SESSION_NAME 139 | ``` 140 | 141 | 업데이트되는 로그를 계속 보려면 NSML 웹에서 확인합니다. 142 | 143 | 웹 화면의 왼쪽에는 현재 NSML 플랫폼에 업로드되어 있는 데이터셋의 목록이 보입니다. 여기서 방금 사용한 데이터셋의 `>`를 클릭하면 실행한 세션 목록이 나타납니다. 세션 목록에서 로그를 보려는 세션명을 클릭하면 오른쪽에 해당 세션의 로그가 나타납니다. 144 | 145 | `logs` 명령어는 이미 종료된 세션에도 실행할 수 있습니다. 웹에서는 상태가 **exited**인 세션을 클릭하여 확인할 수 있습니다. 146 | 147 | 작성한 모델에 `print()` 문이 있다면 해당 구문에 의해 출력된 로그도 확인할 수 있습니다. 148 | 149 | ### ps 150 | 151 | 여러 개의 세션을 실행시켰을 때 현재 진행 중인 세션 목록을 보려면 `ps` 명령어를 실행합니다. 152 | 153 | ```bash 154 | $ nsml ps 155 | ``` 156 | 157 | 어떤 argument를 전달하여 실행했는지, 어떤 상태인지 등 세션의 기본적인 정보를 확인할 수 있습니다. 158 | 159 | #### 참고: ps 명령어의 옵션 160 | `ps`명령어는 현재 **실행 중인** 세션만을 보여줍니다. 만약 종료된 세션까지 함께 보려면 `-a`를 입력하여 현재까지 생성한 모든 세션을 확인할 수 있습니다. 161 | 162 | 특정 데이터셋에 관련된 세션만을 확인하고 싶다면 `-d DATASET`을 추가하여 데이터셋에 대해 필터링된 세션을 확인할 수 있습니다. 163 | 164 | 만약 세션의 수가 너무 많아서 보기가 어렵다면 `-n NUMBER` 옵션을 사용해 최신 몇 개의 세션만을 확인할 수 있습니다. 165 | 166 | ### submit 167 | 168 | 이렇게 학습시킨 모델을 평가하고 리더보드에 업로드하는 방법을 알아보겠습니다. 169 | 170 | 현재 NSML 플랫폼에는 모델의 성능을 평가할 수 있는 테스트 데이터도 업로드되어 있습니다. 테스트 데이터는 학습 데이터와 쌍으로 존재하기 때문에 따로 데이터셋을 지정하지 않아도 됩니다. 171 | 172 | `submit` 명령어는 특정 세션의 특정 이터레이션에 해당하는 모델을 이용해 성능을 평가하고 리더보드에 업로드합니다. 다음의 명령어를 실행하여 간단하게 모델을 평가해보세요. 173 | 174 | ```bash 175 | $ nsml submit SESSION_NAME ITERATION 176 | ``` 177 | 178 | 이제 [NSML 웹](https://hack.nsml.navercorp.com)에서 왼쪽의 데이터셋 목록에서 `kin_phase1`를 클릭하면 오른쪽에 리더보드가 나타납니다. 리더보드에서 순위를 확인하세요. 리더보드에서는 자신이 실행한 평가 세션 중 가장 점수가 높은 세션에 대한 정보만 보입니다. 179 | 180 | ### stop 181 | 182 | 백그라운드에서 실행되고 있는 세션을 중지하고 싶다면 `stop` 명령어를 실행합니다. 183 | 184 | ```bash 185 | $ nsml stop SESSION_NAME 186 | ``` 187 | 188 | ### resume 189 | 190 | 멈췄던 세션을 다시 시작하고 싶다면 `resume` 명령어를 실행합니다. 191 | 192 | ```bash 193 | $ nsml resume SESSION_NAME 194 | ``` 195 | 196 | ### fork 197 | 198 | `fork` 명령어를 실행하여 현재 진행 중인 세션을 다른 파라미터로 복제(fork)할 수 있습니다. 199 | 200 | ```bash 201 | $ nsml fork SESSION_NAME -a "--lr 0.02" 202 | ``` 203 | 204 | `fork` 명령어를 실행하여 복제한 후 다시 `ps` 명령어를 실행하면, 방금 시작된 세션이 어느 세션으로부터 복제한 세션인지에 대한 정보를 확인할 수 있습니다. 205 | 206 | ### 참고: submit, fork, resume의 argument 설정 207 | 208 | 다시 지식iN 분류 모델을 살펴보겠습니다. `submit`, `fork`, `resume` 명령어를 실행하려면 다음과 같은 코드 블럭을 모델에 작성해야 합니다. 209 | 210 | ```python 211 | ... 212 | if __name__ == '__main__': 213 | #1 214 | args.add_argument('--pause', type=int, default=0) 215 | ... 216 | #2 217 | if config.pause: 218 | nsml.paused(scope=locals()) 219 | ... 220 | ``` 221 | 222 | 코드 블럭 #1은 NSML에 내부에서 학습된(혹은 학습이 진행 중인) 세션을 불러오기 위해 필요한 부분입니다. 실행할 때 argument를 입력받을 수 있도록 작성한 코드이지만 실제로 `submit`, `fork`, `resume` 명령어를 실행할 때는 따로 `--pause`를 argument로 전달하지 않습니다. 대신 코드 블럭 #2를 모델에 작성함으로써 `submit`, `fork`, `resume` 명령어를 실행할 때 NSML이 모델을 불러옵니다. 223 | 224 | `submit` 명령어를 실행하려면 아래와 같이 한 가지 구현이 더 필요합니다. 225 | 226 | ```python 227 | ... 228 | if __name__ == '__main__': 229 | args.add_argument('--mode', type=str, default='train') 230 | ... 231 | ``` 232 | 233 | 위와 같이 `--mode`를 argument로 지정하면 NSML에서 `submit`을 실행할 때 해당 값을 이용합니다. 즉, `--pause`와 마찬가지로, 실제 실행할 때 따로 argument를 전달하지 않습니다. 234 | 235 | `fork`와 `resume`은 이미 존재하는 세션을 토대로 새로운 세션을 만드는 명령어입니다. 따라서 기존의 모델 중 어느 부분으로부터 새로운 세션을 만들지에 대한 정보가 필요합니다. 이를 위해서는 아래와 같은 새로운 argument가 필요합니다. 236 | 237 | ```python 238 | ... 239 | if __name__ == '__main__': 240 | 241 |    args.add_argument('--iteration', type=str, default='0') 242 | ... 243 | 244 | if config.mode == 'train': 245 | full_iter = FULL_ITER 246 | for it in range(config.iteration, full_iter): 247 | TRAIN_YOUR_MODEL 248 | ... 249 | ``` 250 | 251 | 위와 같이 코드를 작성하면 NSML은 실행할 때 주어지는 이터레이션 정보로부터 새로운 세션을 만들어 학습합니다. 252 | 253 | ### rm 254 | 255 | 여러분이 NSML에서 학습시킨 모델은 삭제되지 않습니다. 종료된 세션까지 확인하고 싶다면 `ps -a` 옵션으로 확인할 수 있습니다. 256 | 257 | ```bash 258 | $ nsml ps -a 259 | ``` 260 | 261 | 이 중 필요없는 세션이 있다면 `rm` 명령어로 삭제할 수 있습니다. 262 | 263 | ```bash 264 | $ nsml rm SESSION_NAME 265 | ``` 266 | 267 | `rm` 명령어를 실행할 때 `SESSION_NAME`에 `*`와 `?` 와일드카드를 사용할 수 있습니다. 268 | 269 | ```bash 270 | # example 271 | $ nsml rm myId/kin_phase1/1* 272 | $ nsml rm myId/kin_phase1/1? 273 | ``` 274 | 275 | ## NSML 웹 사용하기 276 | 277 | [NSML 웹](https://hack.nsml.navercorp.com)에서는 NSML 클라이언트에서는 수행할 수 없는 특별한 기능을 제공합니다. 바로 그래프와 디버깅입니다. 278 | 279 | ### 그래프 280 | 281 | NSML 웹에서는 여러분이 학습시킨 모델에 대한 수치를 TensorBoard에서 확인할 수 있습니다. 이를 위해서는 코드에서 `nsml.report()` 함수를 사용해야 합니다. 지금까지와 마찬가지로 지식iN 분류 모델을 예로 확인해 보겠습니다. 282 | 283 | ```python 284 | ... 285 | 286 | for epoch in range(config.epochs): 287 | 288 | ... 289 | 290 | nsml.report(summary=True, scope=locals(), epoch=epoch, total_epoch=config.epochs, val_acc=val_acc, 291 | train_acc=train_acc, train__loss=train_loss, val__loss=val_loss, min_val_loss=min_val_loss, 292 | step=epoch) 293 | 294 | ... 295 | ``` 296 | 297 | 위 코드는 매 epoch를 기준(`step=epoch`)으로 그래프를 그리도록 구현한 코드입니다. NSML에서 TensorBoard를 이용하여 그래프를 그리고 싶다면 report 함수의 필수 파라미터로 `step=` 값을 입력하고 그 외에 필요한 값을 입력하면 됩니다. 298 | 299 | 이제 모델을 학습시키고 웹에 접속해서 해당 세션을 찾아 클릭해 보세요. 페이지의 오른쪽 화면에서 세션 로그를 확인할 수 있습니다. 여기서 오른쪽 상단에 있는 **Graph** 버튼을 클릭하면 모델에 대한 정보가 그려진 TensorBoard 화면이 나타납니다. 300 | 301 | ### 디버깅 302 | 303 | NSML 웹에서는 여러분이 학습시키고 있는 모델을 디버깅할 수 있습니다. 예시로 지식iN 분류 모델의 코드 일부를 보겠습니다. 304 | 305 | ```python 306 | if __name__ == '__main__': 307 | 308 | ... 309 | config = args.parse_args() 310 | 311 | ... 312 | ``` 313 | 314 | 이 코드에서 `config` 값을 확인하고 싶다면 해당 세션의 로그 화면에서 오른쪽 아래의 **Terminal** 버튼을 클릭한 다음, 입력 창이 나타나면 `config`를 입력합니다. 315 | 316 | ```bash 317 | >>> config 318 | ``` 319 | 320 | ### 모델 다운로드 321 | 322 | 모델을 로컬에서 확인하고 싶다면 웹에서 다운로드할 수 있습니다. 323 | 324 | ## 모델 구현하기 325 | 326 | 이제 모델 구현부를 살펴보겠습니다. 327 | 328 | ### 설정 329 | 330 | 여러분이 이용할 딥러닝 라이브러리와 파이썬 패키지는 `setup.py` 파일에 지정할 수 있습니다. 331 | 332 | 다음은 지식iN 분류 모델의 `setup.py` 파일입니다. 333 | 334 | ```python 335 | #nsml: floydhub/pytorch:0.3.0-gpu.cuda8cudnn6-py3.17 336 | 337 | from distutils.core import setup 338 | setup( 339 | name='nsml Kin query', 340 | version='1.0', 341 | description='nsml', 342 | install_requires =[ 343 | ] 344 | ) 345 | ``` 346 | 347 | 첫 번째 줄에서 `#nsml:`로 지정한 것은 [Docker Hub](https://hub.docker.com)에서 찾은 딥러닝 라이브러리 이미지입니다. 이 값을 지정하지 않으면 PyTorch와 TensorFlow가 포함된 [NSML 기본 이미지](https://hub.docker.com/r/nsml/default_ml/)를 사용합니다. 348 | 지정하고 싶은 이미지가 있다면 Docker Hub에서 찾아 추가하면 됩니다. 349 | 350 | ### 모델 351 | 352 | 지식iN 분류 모델에는 다음과 같이 `nsml.bind()`에 들어가는 함수가 구현되어 있습니다. 만약 `save`, `load`, `infer`와 관련해서 특별히 구현하고 싶은 부분이 있다면 이 부분에 구현한 후 `nsml.save()`, `nsml.load()`, `nsml.infer()`로 호출해서 사용하면 됩니다. 353 | 354 | ```python 355 | def bind_model(model, **kwargs): 356 | def save(filename, *args): 357 | checkpoint = { 358 | 'model': model.state_dict(), 359 | 'optimizer': kwargs['optimizer'].state_dict() 360 | } 361 | torch.save(checkpoint, filename) 362 | 363 | def load(filename, *args): 364 | checkpoint = torch.load(filename) 365 | model.load_state_dict(checkpoint['model']) 366 | if 'optimizer' in kwargs: 367 | kwargs['optimizer'].load_state_dict(checkpoint['optimizer']) 368 | print('Model loaded') 369 | 370 | def infer(input): 371 | print("input:", input) 372 | model.eval() 373 | tensor_seqs, tensor_lengths = load_batch_input_to_memory(input, has_targets=False) 374 | var_seqs = autograd.Variable(tensor_seqs).cuda() 375 | var_lengths = autograd.Variable(tensor_lengths).cuda() 376 | output_prediction = model(var_seqs, var_lengths) 377 | print("prediction:", output_prediction.data.squeeze(dim=1).tolist()) 378 | return output_prediction.data.squeeze(dim=1).tolist() 379 | 380 | nsml.bind(save, load, infer) 381 | . 382 | . 383 | . 384 | if __name__ == "__main__": 385 | ... 386 | model = YOUR_MODEL() 387 | bind_model(model) 388 | # train 389 | . 390 | ``` 391 | 392 | NSML은 사용하는 라이브러리에 따라 동작하는 `save`와 `load`를 지원하지만 `infer` 함수는 직접 작성해야 합니다. `infer` 함수는 `nsml infer`와 `nsml submit`에서 사용되며, 기본 구조는 입력을 받아서 모델의 예측 결과를 반환합니다. 여기서 입력 및 결과물의 형식은 데이터 업로더가 직접 지정한 대로 따라서 만들면, `nsml submit`으로 모델의 성능을 평가하거나 직접 `nsml infer`로 여러 데이터에 대해서 실험해 볼 수 있습니다. 393 | 394 | ## NSML의 세계로 395 | 396 | 이제 NSML을 이용하기 위한 모든 준비가 끝났습니다. 제공된 baseline 모델을 참고하여 모델을 직접 구현해 보세요. 397 | -------------------------------------------------------------------------------- /quick-guide.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Quick guide.. 터미널만 보고 따라하기. (command line을 복사/붙여넣기로 submit까지 5분). 4 | 5 | ``` 6 | 7 | # 해커톤 사이트에서 git clone하기. 8 | ykkim@AL01205606~/demo $ git clone https://github.com/naver/ai-hackathon-2018.git 9 | Cloning into 'ai-hackathon-2018'... 10 | remote: Counting objects: 66, done. 11 | remote: Compressing objects: 100% (51/51), done. 12 | remote: Total 66 (delta 14), reused 58 (delta 11), pack-reused 0 13 | Unpacking objects: 100% (66/66), done. 14 | 15 | # git clone 잘되었나? 16 | ykkim@AL01205606~/demo $ ls 17 | ai-hackathon-2018 18 | 19 | # nsml local 설치: 20 | ykkim@AL01205606~/demo $ pip install git+https://github.com/n-CLAIR/nsml-local.git 21 | Collecting git+https://github.com/n-CLAIR/nsml-local.git 22 | Cloning https://github.com/n-CLAIR/nsml-local.git to /private/var/folders/j0/gyhk9qgd69l9g21bf8b1q5200000gp/T/pip-d5rtkzo6-build 23 | Requirement already satisfied (use --upgrade to upgrade): nsml==0.0 from git+https://github.com/n-CLAIR/nsml-local.git in /Users/ykkim/anaconda3/lib/python3.6/site-packages/nsml-0.0-py3.6.egg 24 | 25 | # nsml CLI 다운로드 (mac에서..) 26 | ykkim@AL01205606~/demo $ curl -L -o cli.tar.gz https://github.com/n-CLAIR/File-download/raw/master/nsml/hack/nsml_client.darwin.amd64.hack.tar.gz 27 | % Total % Received % Xferd Average Speed Time Time Time Current 28 | Dload Upload Total Spent Left Speed 29 | 100 175 100 175 0 0 87 0 0:00:02 0:00:02 --:--:-- 83 30 | 100 9439k 100 9439k 0 0 2359k 0 0:00:04 0:00:04 --:--:-- 5630k 31 | 32 | # tar.gz 압축 풀기. 33 | ykkim@AL01205606~/demo $ tar xvpf cli.tar.gz 34 | x nsml_client.darwin.amd64.hack/ 35 | x nsml_client.darwin.amd64.hack/nsml 36 | x nsml_client.darwin.amd64.hack/README.hack.txt 37 | 38 | # nsml이 있는 위치로 이동 39 | ykkim@AL01205606~/demo $ cd nsml_client.darwin.amd64.hack/ 40 | 41 | # nsml을 경로에 추가 42 | ykkim@AL01205606~/demo/nsml_client.darwin.amd64.hack $ export PATH=$PATH:`pwd` 43 | 44 | # nsml이 동작하는지 확인. 45 | ykkim@AL01205606~/demo/nsml_client.darwin.amd64.hack $ nsml --version 46 | Built: 2018-03-22T00:48:15+09:00 47 | Go: go1.10 48 | GOARCH: amd64 49 | GOOS: darwin 50 | Protocol: 20180321 51 | Revision: c41e9558d212fd200f25ead58863a9ebcb6477e7 (not-modified) 52 | Preconfigured connection: hack.cli.nsml.navercorp.com 53 | 54 | 55 | # kin example code가 있는 디렉토리로 이동 56 | ykkim@AL01205606~/demo $ cd ai-hackathon-2018/missions/examples/kin/example/ 57 | 58 | # dataset 이름 확인 59 | ykkim@AL01205606~/demo/ai-hackathon-2018/missions/examples/kin/example $ nsml dataset ls 60 | Name Size Last Modified Author Description Tag 61 | ------------ -------- --------------- ---------- ---------------- ----- 62 | kin_phase1 3.5 MB 4 hours ago nsml-admin 만료 날짜: 4/9 11:00 63 | movie_phase1 24.06 MB 4 hours ago nsml-admin 만료 날짜: 4/9 11:00 64 | 65 | # kin_phase1과 함께 main.py을 nsml로 보내어 GPU에서 실행 66 | ykkim@AL01205606~/demo/ai-hackathon-2018/missions/examples/kin/example $ nsml run -d kin_phase1 67 | ........... 68 | Session nsml-admin/kin_phase1/3 started. 69 | 70 | # 잘 돌고 있는지 process 상태 확인. (-a: 완료된 것도 포함) 71 | ykkim@AL01205606~/demo/ai-hackathon-2018/missions/examples/kin/example $ nsml ps -a 72 | Name Created Args Status Summary Description 73 | ------------------------- -------------- ------- -------- ------------------------------------------ ------------- 74 | nsml-admin/kin_phase1/3 just now main.py Running epoch=1, epoch_total=10, train/loss=0.688 75 | nsml-admin/movie_phase1/2 4 minutes ago main.py Running epoch=2, epoch_total=10, train/loss=12.804 76 | nsml-admin/kin_phase1/2 14 minutes ago main.py Exited epoch=9, epoch_total=10, train/loss=0.621 77 | nsml-admin/movie_phase1/1 4 hours ago main.py Exited epoch=9, epoch_total=10, train/loss=12.808 78 | nsml-admin/kin_phase1/1 4 hours ago main.py Exited epoch=9, epoch_total=10, train/loss=0.623 79 | 80 | # 실행이 완료되었으면.. nsml model ls 로 적절한 Checkpoint 확인.(학습 중간중간 저장된 model) 81 | ykkim@AL01205606~/demo/ai-hackathon-2018/missions/examples/kin/example $ nsml model ls nsml-admin/kin_phase1/3 82 | Checkpoint Last Modified Elapsed Summary 83 | ------------ --------------- --------- -------------------------------------------------------------- 84 | 0 seconds ago 0.296 train/loss=0.7664164423942565, epoch=0, step=0, epoch_total=10 85 | 1 seconds ago 1.413 train/loss=0.688490229845047, epoch=1, step=1, epoch_total=10 86 | 2 seconds ago 1.434 train/loss=0.6506421864032745, epoch=2, step=2, epoch_total=10 87 | 3 seconds ago 1.425 train/loss=0.6539466977119446, epoch=3, step=3, epoch_total=10 88 | 4 seconds ago 1.422 train/loss=0.647806578874588, epoch=4, step=4, epoch_total=10 89 | 5 seconds ago 1.453 train/loss=0.6433648660778999, epoch=5, step=5, epoch_total=10 90 | 6 seconds ago 1.451 train/loss=0.6380701988935471, epoch=6, step=6, epoch_total=10 91 | 7 seconds ago 1.471 train/loss=0.6320644378662109, epoch=7, step=7, epoch_total=10 92 | 8 seconds ago 1.453 train/loss=0.6266655698418617, epoch=8, step=8, epoch_total=10 93 | 9 seconds ago 1.463 train/loss=0.6218963131308556, epoch=9, step=9, epoch_total=10 94 | 95 | # model선택하였으면, submit 명령으로 leaderboard에 제출. 96 | ykkim@AL01205606~/demo/ai-hackathon-2018/missions/examples/kin/example $ nsml submit nsml-admin/kin_phase1/3 9 97 | ....................ykkim@AL01205606~/demo/ai-hackathon-2018/missions/examples/kin/example $ 98 | ``` 99 | 100 | 약간 더 자세히.. 101 | 102 | https://docs.google.com/presentation/d/1gpCpmVu4lks2kvH_kMJkSRqsr6ZQT8Y1nSac40MzVzI/edit#slide=id.g3638547719_0_0 103 | -------------------------------------------------------------------------------- /res/NSMLHack_web_1000x260_G.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/NSMLHack_web_1000x260_G.jpg -------------------------------------------------------------------------------- /res/cSGPHtzPFQ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/cSGPHtzPFQ.png -------------------------------------------------------------------------------- /res/ckh.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/ckh.jpg -------------------------------------------------------------------------------- /res/kdh.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/kdh.jpg -------------------------------------------------------------------------------- /res/kin 2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/kin 2.jpg -------------------------------------------------------------------------------- /res/kin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/kin.jpg -------------------------------------------------------------------------------- /res/ksh.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/ksh.jpg -------------------------------------------------------------------------------- /res/leaderboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/leaderboard.png -------------------------------------------------------------------------------- /res/movie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/movie.png -------------------------------------------------------------------------------- /res/rank1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/rank1.png -------------------------------------------------------------------------------- /res/rank2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/rank2.png -------------------------------------------------------------------------------- /res/result_kin_final.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/result_kin_final.png -------------------------------------------------------------------------------- /res/result_kin_r2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/result_kin_r2-1.png -------------------------------------------------------------------------------- /res/result_kin_r2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/result_kin_r2-2.png -------------------------------------------------------------------------------- /res/result_movie_final.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/result_movie_final.png -------------------------------------------------------------------------------- /res/result_movie_r2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/result_movie_r2-1.png -------------------------------------------------------------------------------- /res/result_movie_r2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/result_movie_r2-2.png -------------------------------------------------------------------------------- /res/shj.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/shj.jpg -------------------------------------------------------------------------------- /res/smj.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naver/ai-hackathon/939c2b1e87c999c31dee286c6e17864b9698face/res/smj.jpg --------------------------------------------------------------------------------