파이콘(PyCon) 2018 - 2일차 메모


PyCon(파이콘) 2018 2일차 세션 메모입니다! 일정이 있어 오전 세션만 들었습니다


인공지능 슈퍼마리오의 거의 모든것


동물이 학습하는 방법

  • 동물은 학습 능력이 존재
  • 머리철수반사 : 위험한 물체가 있을것이라 판단하고 하는 반사 행동
  • 여러번 시도하면 후퇴하는 범위가 증가
  • Law of effect : 어떤 행동의 결과가 만족스러우면 다음에도 그 행동을 반복한다. 반대로 만족하지 않으면 그 행동을 하지 않는다.
  • Reinforcement(강화) : 이전에 일어난 행동을 반복하게 만드는 자극
  • Punishment(처벌) : 이전에 일어난 행동을 피하게 만드는 자극

사람이 학습하는 방법

  • Environment에서 Experience를 통해(interaction) 배워나감
  • Reinforcement : 이전에 일어난 행동을 반복하게 만드는 자극
  • Punishment : 이전에 일어난 행동을 피하게 만드는 자극
  • Tap Ball을 통한 강화 학습 진행ㅋㅋㅋㅋㅋ
  • Reinforcement : 성공의 쾌감, 근육의 성장
  • Punishment : 고통

강화 학습

  • 상호 작용을 Computation, 수학적으로 표현
    • Reinforcement learning은 Reward(보상)을 최대화 하는 action(행동)을 선택
    • Learner(배우는자)는 여러 action을 해보며, reward를 가장 높게 받는 action을 찾음
    • 선택된 action이 당장의 reward 뿐만 아닌, 다음의 상황 또는 다음 일어나게 될 reward에도 영향을 끼칠수도 있음
  • Exploitation : 가장 좋아보이는 상황
  • Exploration : 현재 가장 좋은 상황은 아니지만 먼 미래를 위해 탐험
  • 풀이는 공에 관심이 없고(Exploration x) 셀이는 관심이 있음(Exploration)
    • Reward : 간식
    • 셀이는 탭볼을 칠 수 있음
  • State-value
    • 어떤 상황을 value로 측정
  • State-Action Value Function
    • 내가 할 수 있는 Action들의 가치를 측정
  • Optimal Policy가 목표

슈퍼마리오

env = gym_super_mario_bros.make(‘SuperMarioBros-v0')
env.reset()
env.render()
  • World & Level
    • env = gym_super_mario_bros.make('SuperMarioBros-<world>-<level>-v<version>')
    • 버전별로 이미지를 전처리(버전4는 뭉그러트림)
  • 깃발에 가까워지면 +, 목표에 도착하면 +
  • 목표 달성을 못하면 -, 시간이 지나면 -, 깃발에서 멀어지면 -

  • env.action_space.n : 256개인데 너무 많음. 필요한 것만 따로 처리

  • env.step은 액션을 받아서 마리오의 상황을 받음
    • info : 디버깅을 위한 정보

  • eps_max : 아무 행동이나 막 함
  • memory를 생성해서 사용

  • loss를 줄이기! supervised learning과 다르게 자신이 선택한 액션 중 가장 좋아보이는 것을 정답으로 둠
  • Double DQN
    • 이미지 4장이 input
    • 1장만 들어가면 전 상황을 알 수 없음
    • Q-Network를 통해 Action value 얻음
    • Exploitation, Exploration를 고민한 후, Action
    • Replay Memory
  • 5000 에피소드를 하니 4일 소요, 깃발에 도착함!
  • 다른 환경
    • Deepmind Lab, Sonic, OpenAI, Starcraft, Minecraft, DQN, DDQN, Rainbow DQN, DDPG

추천 시스템을 위한 어플리케이션 서버 개발 후기


추천 시스템

  • 우리가 소비하는 데이터를 새로운 방법(경험)으로 추천
  • UX, UI 관점에서도 봐야하는 Task
  • 복잡한 문제지만 2가지 맥락으로 보면
    • 아이템 추천
    • 개인화 추천
  • 시나리오
    • 바나나를 보고 있을 때, 어떤 것이 적합할까? 원하는 것이 뭘까? 맥락을 이해해서 유사도를 생성
    • 상품의 상태(품절 유무) 선호도로 필터링해서 상품을 보여줌
  • 필요한 정보
    • 활동 정보 : 좋아요, 싫어요, 산 것/본 것
    • 관계, 유사도, 거리
    • 상품 정보 : 상품명, 재고량, 가격, 판매처
    • disliked한 것을 5개 제외하고 status okay인 20개를 추출!

직접 만들기!

  • 어플리케이션 서버 요구 사항 분석
    • 실시간 분석
      • 실시간 개인화 추천
      • OLAP에 가까움
      • 복잡한 필터링, 비지니스 로직, 온라인 기계학습
      • 이게 가장 중요! 추천 퀄리티를 위해
      • 미리 계산하는 것은 매우 비효율적
    • OLTP
      • 관계형 분석 기능을 제공해 낮은 지연시간을 보장
    • 데이터베이스
      • 메모리에 적재할 순 없음
      • 유사도/메타/이력데이터적재
      • NoSQL
      • 수평 확장이 용이해야 하고 대량의 데이터에도 안정적 성능 유지 필요
  • 솔루션 조사
    • ArangoDB : MongoDB의 차세대
    • Dgraph : 차세대.. 허나 버전이 이제 1점대
  • 실시간 분석
    • 어려운 로직
      • 결과가 없으면 같은 카테고리내 다른 상품을 보여줬으면 좋겠어요
      • 본 거는 빼주세요.그런데 3번 정도 봐야 빠졌으면 좋겠어요
    • 대용량 개인화 추천, 온라인 기계학습
  • 속도 및 성능
    • 데이터베이스 작업을 단순화하고, 복잡한 로직을 더 효과적으로 구현
    • 데이터베이스별로 쿼리 속도가 달라서 따로 만드는 것이 좋다 판단
  • 확장성 및 안정성
    • 대용량 데이터베이스의 특성 + 실시간 분석 2가지를 하나로 하기 어려움
  • 완결성
    • API를 사용하는 입장에서 추가 작업없이 바로 사용할 수 있도록!

아키텍쳐

  • mysql에 있는 정의된 룰(스키마) 로드
  • 새로운 서비스에 적용하려면 스키마만 추가하면 됨

개발 후기

  • 만들면서 겪은 문제
  • Tornado vs Sanic
    • 항상 legacy가 발목..
    • Sanic의 장점
      • 코드 가독성 증가, LOC 감소
      • 성능 : 2배 이상의 퍼포먼스
  • asyncio.Future
    • 어떻게 사용하는지에 따라 퍼포먼스가 다름
    • 위 코드는 비동기콜을 순차적으로 진행해서 context switching에선 효율적일 수 있찌만 개개의 속도는 비슷
    • 아래 코드는 단일 리퀘스트를 여러개로 뿌려줘서 속도 상승
  • 데이터베이스 프로파일링
    • 거의 네트워크 부분(DB 조회)에서 시간이 더 소요
    • sanic-motor를 사용
    • MongoDB에서 $filter 연산을 사용
    • $group은 앱 서버에서 처리하는 것이 수배 빠름
    • DB를 모두 믿지는 말자!
  • 꼼꼼한 캐싱
    • 데이터베이스 조회 비용이 비싸니 최대한 캐싱을 꼼꼼히!
    • Redis가 1개 로컬 아래에 앱이 붙어있는 구조
    • 다양한 쿼리를 날릴 경우 중복 질의 존재
      • 캐쉬를 세세하게 적용
      • 프로세스 내의 임베디드 캐싱을 하면 프로세스간 중복 요청도 처리됨(1대만 쓰니까!)
    • 슈퍼노드를 해결을 위해 인스턴스 내 캐시가 필요
      • DB가 샤딩으로 쪼개두고 모든 request가 골고루 퍼지길 기대
      • 그러나 1번 샤딩만 죽는 케이스가 발생
      • 쿼리에 특정 요청이 많이 들어오는 것은 아닌데? 이상하네
      • 정말 Hot한 포도가 있음..!
      • 가끔 방문한 유저는 정보가 없어서 유사한 사람을 찾아서 보여줌(콜백 사용)
      • 그 콜백이 있던 곳이 1번이었음
      • 샤딩 내 캐싱으로 해결
  • 복잡한 필터링
    • 제거하기는 쉽게 할 수 있음
    • 뒤로 밀어내기
      • rolling 기능 구현
      • 빌트인 프로시져로 처리
      • 룰에 파이썬 코드를 심고 런타임 컴파일을 사용. @filter
  • 설정 배포
    • 한번 만들면 룰(스키마)만 추가함
    • 버켓을 바꾸기 위해 마라톤 앱을 껐다 키면 리퀘스트 유실이 있을 수 있음
    • App을 순차적 재시작해도 리퀘스트 유실 가능
    • 따라서 GUNICORN을 사용해 KILL SIGTERM, 안전하게 앱 재시작
  • 퍼포먼스

마지막

  • 파이썬으로도 가능!!!
  • 실시간 어플리케이션 서버의 병목은 대부분 네트워크 IO
  • CPU 연산은 수치 연산에 최적화된 라이브러리 잘 활용하기

이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)




© 2017. by Seongyun Byeon

Powered by zzsza