ch07. decorator

|

Decorator

Decorator의 작동 방식

@decorate
def target():
    print('running target()')

은 다음처럼 동작한다.

def target():
    print('running target()')
  
target = decorate(target)
  • decorate된 함수가 정의된 직후에 실행됨

변수 범위 규칙

  • 함수 scope 내부에 정의되어있지 않은 변수의 경우 global 변수를 이용
  • 지역변수를 함수 내부에 만들면 global 변수를 참조하지 않게됨. 따라서 다음과 같은 코드에서 문제가 생김
b = 6
def f2(a):
    print(a)
    print(b)
    b = 9

>>> f2(1)
1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in f2
UnboundLocalError: local variable 'b' referenced before assignment
  • 이 때는 global b를 추가해서 b가 전역변수라는 것을 알려주면 됨

Closure

  • 함수 본체에서 정의하지 않고 참조하는 비전역(nonlocal) 변수를 포함한 확장 범위를 가진 함수
  • free variable을 얻으려면 fn.__code__.co_freevars를 사용
  • 다음처럼 만들면 에러가 남!
def make_averager():
    count = 0
    total = 0
    
    def averager(new_value):
        count += 1
        total += new_value
        return total / count
    return averager
>>> avg = make_averager()
>>> avg(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in averager
UnboundLocalError: local variable 'count' referenced before assignment
  • count += 1 구문에서 count를 local 변수로 생각했기 때문이다.
  • 앞의 global처럼 nonlocal count, total을 붙여주면 해결!

유용한 decorator들

functools.lru_cache()

  • decorate할 함수가 받는 인수는 모두 hashable해야함
    • dictionary로 결과를 저장하기 때문에…
  • 밑의 코드를 돌려보자!
import functools

def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-2) + fibonacci(n-1)

@functools.lru_cache(maxsize=128, typed=False)
def fibonacci_cache(n):
    if n < 2:
        return n
    return fibonacci_cache(n-2) + fibonacci_cache(n-1)

functools.singledispatch()

  • method overloading과 비슷함
import functools

@functools.singledispatch
def hello(obj):
    raise NotImplemented

@hello.register(int)
def _(i):
    print("hello integer! args: {}".format(i))

@hello.register(str)
def _(s):
    print("hello string! args: {}".format(s))

매개변수화된 Decorator flask의 route decorator

  • flask의 app.route를 대신해서 보자!
def route(self, rule, **options):
    def decorator(f):
        endpoint = options.pop('endpoint', None)
        self.add_url_rule(rule, endpoint, f, **options)
        return f
   return decorator

@app.route('/')
def index_fn():
    return 'hello world'
  • app.route('/')(index_fn) => decorator(index_fn)

tmux cheatsheet

|

Installation

brew install tmux
cd ~/
git clone https://github.com/gpakosz/.tmux.git
ln -s -f .tmux/.tmux.conf
cp .tmux/.tmux.conf.local .

용어

  • prefix: ctrl + b
  • session > window > pane

사용법

Session

  command
create session tmux new -s session_name
delete session tmux kill-session -t session_name
attach tmux attach -t session_name
detach prefix + d
session list tmux ls

Window

  command
new window prefix + c
switch window prefix + <num>
rename window prefix + ,
window list prefix + w

Pane

  command
split horizontal prefix + %
split vertical prefix + "
move pane prefix + q + <num> or prefix + arrow-key
zoom in/out pane prefix + z
resize-pane prefix + :resize-pane -D 10

ch01. python data model

|

Python data model

  • sequence, 반복자 등 언어 자체의 구성단위에 대한 인터페이스를 공식적으로 정의한 것
  • 특별 method들을 통해서 새로 정의할 수 있음
  • 이들은 앞뒤에 __를 붙인다.
  • ex>
    • A[key]A.__getitem__(key)를 호출한다.

__len__, __getitem__

class myObject:
    def __init__(self):
        self._arr = [1,2,3]

    def __len__(self):
        return len(self._arr)

    def __getitem__(self, position):
        return self._arr[position]

vector를 만들어보자

from math import hypot

class Vector:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __repr__(self):  # 객체를 문자열로 표현
        return 'Vector({!r}, {!r})'.format(self.x, self.y)

    def __abs__(self):  
        return hypot(self.x, self.y)

    def __bool__(self):
        return bool(abs(self))

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Vector(x, y)

    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)

    def __rmul__(self, scalar):  # scalar가 왼쪽에 오는 곱셈을 가능케 해줌
        return Vector(self.x * scalar, self.y * scalar)

>>> b = Vector(1,2)
>>> a = Vector(3,4)
>>> a+b
Vector(4, 6)
>>> a*3
Vector(9, 12)
>>> abs(a)
5.0
>>> bool(a)
True

vim 설정

|

install neovim

OSX

brew install neovim/neovim/neovim

Linux

apt-add-repository ppa:neovim-ppa/stable
apt-get update
apt-get install neovim
apt-get install python-dev python-pip python3-dev python3-pip
pip3 install --user neovim

alias 추가

  • vi 대신 nvim을 쓰기위해…
    mkdir -p ${XDG_CONFIG_HOME:=$HOME/.config}
    mkdir ~/.vim
    touch ~/.vimrc
    ln -s ~/.vim $XDG_CONFIG_HOME/nvim
    ln -s ~/.vimrc $XDG_CONFIG_HOME/nvim/init.vim
    
  • zshrc나 bashrc에 적절히 추가
    alias vi="nvim"
    

install node, yarn

OSX

brew upgrade node
brew install yarn

Linux

curl -sL https://deb.nodesource.com/setup_11.x | sudo -E bash -
apt-get install nodejs

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
apt-get update
apt-get install yarn

install Vundle and setup vimrc

install Vundle

git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim

vimrc

  • neovim이 아닌 경우 다음 두가지를 수정해주어야한다.
    • set rtp+=~/.config/nvim/bundle/Vundle.vim -> ~/.vim/bundle/Vundle.vim
    • call vundle#begin('~/.config/nvim/bundle') -> call vundle#begin()
" Vundle Setting "
set nocompatible
filetype off

set rtp+=~/.config/nvim/bundle/Vundle.vim
call vundle#begin('~/.config/nvim/bundle')

Plugin 'VundleVim/Vundle.vim'
Plugin 'scrooloose/nerdtree'
Plugin 'cocopon/iceberg.vim'
Plugin 'neoclide/coc.nvim'
Plugin 'posva/vim-vue'
Plugin 'shime/vim-livedown'
call vundle#end()

filetype plugin indent on    " required

set nu

if has("autocmd")
  au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif

" Syntax Highlighting "
syntax on

set autoindent                      " 이전 라인 들여쓰기 하면 개행시 다음 라인에도 자동 적용 "
set smartindent                     " autoindent 와 비슷 몇몇 c언어의 문법에 대해 좀더 똑똑하게 들여 쓰기를 적용 "
set cindent                         " 좀더 똑똑하게 c 언어의 문법에 맞게 들여 쓰기 적용 "

set scrolloff=4                     " 스크롤 할때 위아래 줄 유지, 화살표 아래로 내리다 보면 아래에서 4줄 유지한 상황에서 스크롤 됨 "
set tabstop=4                       " 탭을 4칸 "
set softtabstop=4                   " tab키를 입력 하였을때 입력될 너비 "
set shiftwidth=4                    " 자동 들여쓰기 4칸 "
" file에 따라 다르게 적용 "
autocmd FileType html setlocal ts=2 sts=2 sw=2
autocmd FileType css setlocal ts=2 sts=2 sw=2
autocmd FileType javascript setlocal ts=2 sts=2 sw=2
autocmd FileType vue setlocal ts=2 sts=2 sw=2
set shiftround                      " "
set expandtab                       " 탭대신 스페이스 "

set textwidth=100                   " 글자수 100자 이상이면 자동 개행 "

set hlsearch                        " / ? 명령등으로 찾은 문자열을 하이라이트"
set incsearch                       " 글자를 치면 그에 맞는것을 치는 동안 보여주기 "

filetype on                         " 파일 종류에 따른 구문을 강조 표시 "

set ls=2                            " 항상 status 라인을 표시 "

set ut=300000                       " 몇 milliseconds 후에 swap 파일 생성 5분 "
set uc=100                          " 몇 글자 이상 써야 swap 파일 생성 "

" For python http://www.vim.org/scripts/script.php?script_id=790 "
let python_version_2=1              " python 2 문법"
let python_highlight_all=1          " 모든 강조 기능을 on"

" Color scheme
if !has('gui_running')
    set t_Co=256
endif

colorscheme iceberg
let g:lightline = { 'colorscheme': 'iceberg' }
set laststatus=2
set noshowmode

" Key Map "

" NERDTree "
nmap <leader>n :NERDTree<CR>

""""""""""""""""" COC """""""""""""""
" if hidden is not set, TextEdit might fail.
set hidden

" Some server have issues with backup files, see #649
set nobackup
set nowritebackup

" Better display for messages
set cmdheight=2

" Smaller updatetime for CursorHold & CursorHoldI
set updatetime=300

" don't give |ins-completion-menu| messages.
set shortmess+=c

" always show signcolumns
set signcolumn=yes

" Use tab for trigger completion with characters ahead and navigate.
" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" Use <c-space> for trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()

" Use <cr> for confirm completion, `<C-g>u` means break undo chain at current position.
" Coc only does snippet and additional edit on confirm.
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"

" Remap keys for gotos
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" Use K for show documentation in preview window
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if &filetype == 'vim'
    execute 'h '.expand('<cword>')
  else
    call CocAction('doHover')
  endif
endfunction

" Highlight symbol under cursor on CursorHold
autocmd CursorHold * silent call CocActionAsync('highlight')

" Remap for rename current word
nmap <leader>rn <Plug>(coc-rename)

" Remap for format selected region
vmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)

augroup mygroup
  autocmd!
  " Setup formatexpr specified filetype(s).
  autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
  " Update signature help on jump placeholder
  autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end

" Remap for do codeAction of selected region, ex: `<leader>aap` for current paragraph
vmap <leader>a  <Plug>(coc-codeaction-selected)
nmap <leader>a  <Plug>(coc-codeaction-selected)

" Remap for do codeAction of current line
nmap <leader>ac  <Plug>(coc-codeaction)
" Fix autofix problem of current line
nmap <leader>qf  <Plug>(coc-fix-current)

" Use `:Format` for format current buffer
command! -nargs=0 Format :call CocAction('format')

" Use `:Fold` for fold current buffer
command! -nargs=? Fold :call     CocAction('fold', <f-args>)


" Add diagnostic info for https://github.com/itchyny/lightline.vim
let g:lightline = {
      \ 'colorscheme': 'wombat',
      \ 'active': {
      \   'left': [ [ 'mode', 'paste' ],
      \             [ 'cocstatus', 'readonly', 'filename', 'modified' ] ]
      \ },
      \ 'component_function': {
      \   'cocstatus': 'coc#status'
      \ },
      \ }


" Using CocList
" Show all diagnostics
nnoremap <silent> <space>a  :<C-u>CocList diagnostics<cr>
" Manage extensions
nnoremap <silent> <space>e  :<C-u>CocList extensions<cr>
" Show commands
nnoremap <silent> <space>c  :<C-u>CocList commands<cr>
" Find symbol of current document
nnoremap <silent> <space>o  :<C-u>CocList outline<cr>
" Search workspace symbols
nnoremap <silent> <space>s  :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent> <space>j  :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent> <space>k  :<C-u>CocPrev<CR>
" Resume latest coc list
nnoremap <silent> <space>p  :<C-u>CocListResume<CR>

jedi, neovim install

  • pip install neovim jedi python-language-server

PluginInstall

  • vi에 들어가서
    • :PluginInstall
    • :call coc#util#install()
    • :CocInstall coc-python
    • :CocInstall coc-json
    • :CocInstall coc-vetur

CocConfig

  • :CocConfig로 들어가서 다음처럼 세팅해줌
    • python.jediPath는 알아서 잘 깔린 곳으로 넣어준다.
{
    "python.jediPath": "/Users/hyeongseokoh/.pyenv/versions/general-3.7.2/lib/python3.7/site-packages/",
    "languageserver": {
        "python": {
            "command": "python",
            "args": [
                "-mpyls",
                "-vv",
                "--log-file",
                "/tmp/lsp_python.log"
            ],
            "trace.server": "verbose",
            "filetypes": [
                "python"
            ],
            "settings": {
                "pyls": {
                    "enable": true,
                    "trace": {
                        "server": "verbose"
                    },
                    "commandPath": "",
                    "configurationSources": [
                        "pycodestyle"
                    ],
                    "plugins": {
                        "jedi_completion": {
                            "enabled": true
                        },
                        "jedi_hover": {
                            "enabled": true
                        },
                        "jedi_references": {
                            "enabled": true
                        },
                        "jedi_signature_help": {
                            "enabled": true
                        },
                        "jedi_symbols": {
                            "enabled": true,
                            "all_scopes": true
                        },
                        "mccabe": {
                            "enabled": true,
                            "threshold": 15
                        },
                        "preload": {
                            "enabled": true
                        },
                        "pycodestyle": {
                            "enabled": true
                        },
                        "pydocstyle": {
                            "enabled": false,
                            "match": "(?!test_).*\\.py",
                            "matchDir": "[^\\.].*"
                        },
                        "pyflakes": {
                            "enabled": true
                        },
                        "rope_completion": {
                            "enabled": true
                        },
                        "yapf": {
                            "enabled": true
                        }
                    }
                }
            }
        }
    }
}

Neural Arithmetic Logic Units

|

논문 링크

아이디어

  • output이 numerical일 때 extrapolation도 잘되는 네트워크를 만들고 싶음
    • 0.png
    • 이게 현재의 activation function들의 한계
  • extrapolation을 잘 하려면, primitive 수학 연산들을 할 수 있는 linear activation가 있어야하지 않을까?
  • 해서 다음과 같은 것들을 만들었음
    • 1.png
    • 2.png
    • $W$는 [-1, 0, 1] 사이의 값을 갖기를 원했음
      • 그러면 NAC($a = Wx$)는 덧셈, 뺄셈이 가능한 모듈이 됨
      • 근데 gradient도 잘 흐르고 유사하게 가기위해 저런 식으로 만들었다함.

실험

  • in/output이 모두 numeric인 실험
    • 3.png
    • extrapolation이 굉장히 잘된다.
    • 노란색 부위는 왜 그런지 모르겠네…
  • Mnist 10개를 넣고 인식/덧셈 연산하는 테스트
    • 4.png
    • input은 numeric이 아니며, output이 numeric
    • 덧셈과 identity니까 NAC가 더 잘됨
    • NALU는 왜 addition에서 에러가 클까…
  • 숫자를 영어로 읽은 것을 숫자로 translation하는 태스크
    • 5.png
    • NALU가 더 잘된다.
    • 중간에 prediction 결과를 찍어본 것
      • 6.png
  • program evaluation은 건너뛴다. 아마 위의 translation이 되는 것을 보고 확장해서 테스트해봤을 것 같은데..
  • 도착 시간을 주고 그 시간에 도착하면 reward를 주는 환경
    • 7.png
    • action space: {UP, DOWN, LEFT, RIGHT, PASS}
    • convnet output과 도착해야할 시간이 concat해서 LSTM에 들어감