Thursday, January 21, 2016

리알못: 리눅스 알지도 못하는 사람들을 위한 가이드

스티브 잡스님의 은혜를 받으며 살아가던 저같은 앱등이도 살다보면 리눅스를 써야할 날이 옵니다. 아니, 왔습니다. 저에게 리눅스는 제 컴덕 친구들이나 흐흐거리며 다루는, 혹은 리눅스를 만든 녀석이 메일링 리스트에서 또 누군가랑 싸웠다는 기사를 흘낏 보며 떠올리는, 아주 추상적인 존재였죠. 그러나 학교와 회사의 서버를 써야하고, 그런데 서버는 리눅스로 되어있고, 나는 일개 학생/직원일 뿐이고, 그래서 20년전 MS도스를 쓰던 시절에 혹은 PC통신에서나 쓰던 ls, cd ..같은 명령어를 써보며 마치 내가 뭘 할 줄 아는 것 처럼 이런 저런 디렉토리를 오간 뒤에 결국은 인정했습니다. 아, 이걸 공부해야 하는 구나.

막상 리눅스 책이나 강좌를 보면 수백 페이지 분량의 엄청난 것들이 나옵니다. 리눅스란 무엇이고, 누가 언제 만들었고, 무슨무슨 종류가 있고, 어쩌구 저쩌구... 커널은 뭐고..등등.

이런 내용 다 제끼고! (저도 모를뿐더러; ) 리눅스 초보를 위해 아주 간략히 정리해드리겠습니다. 사실, 네이버 구글 찾으면 어지간한건 다 나옵니다. 그런데 문제는 이거죠. 뭘 찾아야 할지 모른다는 것.

그래서 아주 간략히, 정말 간략히 개념만 설명합니다. 더 자세하고 훌륭한 설명은 다시한번 구글링 하시길 바랍니다.


  • 리눅스? 유닉스?
    • 리눅스는 유닉스의 한 종류입니다. 아니 정확하게 따지면 유닉스와 유사한 뭐라고 하는데 그냥 리알못들은 그런가보다 하고 넘어갑니다. 
  • 무얼 설치해야하나요?
    • 혹시 직접 설치해야 한다면 linux ubuntu download를 구글링하셔서 맨 위 링크를 누르세요. 여러 버전이 나올텐데 LTS (Long Term Support) 버전을 쓰세요. 지금은 14.04네요.
  • 알아야할 명령어 목록
    • $ ls - list
      • 디렉토리의 내용을 보여줌
    • $ pwd - print working directory
      • 현재 디렉토리의 위치를 알려줌
    • $ less some_text_file.txt
    • $ more some_txt_file.txt
      • 텍스트 파일의 일부를 후다닥 볼 수 있음.
    • $ tail some_text_file.txt
    • $ head some_text_file.txt
      • 마찬가지. 텍스트 파일의 맨 앞/맨 뒤를 출력해줍니다.
    • $ touch temp.abc
      • 저 파일이 없다면 temp.abc라는 파일을 생성합니다. 파일의 내용은 비어있습니다.
      • 파일이 있다면 저 파일을 한번 툭 건드려주게됩니다. 결과적으로 파일의 '최종 수정한 날짜'가 현재 시간으로 바뀝니다.
    • $ mkdir directory_name
      • 디렉토리를 만듭니다.
    • $ rmdir directory_name
      • 디렉토리를 삭제합니다.
    • $ cp file.txt new_file.txt
      • 파일을 복사합니다.
    • $ mv file.txt new_name.txt
      • 파일을 이동합니다. 이 명령어를 이용해 이름을 바꿀 수 있습니다. 
    • $ echo 'blah blah
      • blah blah 라고 출력합니다.
    • $ cat files.
      • 여러 파일을 붙입니다.
    • $ tar, zip
      • 파일 압축/해제.
    • $ wget url
      • url의 파일을 다운받습니다.
    • $ chmod, chown
      • 파일/디렉토리의 권한을 바꿔줍니다.
    • $ sudo 
      • 각종 커맨드 앞에 sudo를 붙여주면 super user의 권한으로 뭔가를 하게됩니다. 수퍼 유저는 다시말해 admin, 관리자 계정입니다. 따라서 이걸 하려면 관리자 계정의 권한을 갖고있어야합니다.
    • $ top
      • 작업관리자입니다. 아주 유용하죠.
    • $ iotop, iostat
      • top과 비슷한데 각종 기기간의 입출력 내역을 보여줍니다.
    • $ nohup
      • $ nohup python main.py > log_file_name.txt &
      • 커맨드 실행 내역의 결과를 log_file_name.txt 에 저장합니다.
      • 서버에 접속해서 이걸로 커맨드를 실행하면 그 이후에 접속을 끊어도 커맨드가 계속 실행되게 됩니다. 아주 유용하죠. 
      • 그럼 중간에 실행을 중지하고싶다면?
    • $ kill, pkill
      • pkill python
      • kill 12345
      • pkill python은 실행중인 파이썬을 전부 종료합니다.
      • kill 12345는 프로세스 아이디 12345를 종료합니다.
      • 프로세스 아이디는 top 을 실행하면 왼쪽에서 볼 수 있습니다.
    • $ screen
      • nohup과 비슷한데, 저는 더 유용하게 쓰고있습니다.
      • 쉽게말해 가상의 스크린을 여러개 띄워놓고 필요할 때 해당 스크린에 접속해서 사용하는 것 입니다.
      • screen -S screen_name 으로 새 스크린을 만들고,
      • 새 스크린 내부에서는 ctrl+a, d 를 눌러서 밖으로 나올 수 있습니다.
      • screen -x 를 하면 스크린 목록을 볼 수 있습니다.
      • screen -x screen_name 으로 기존에 만들어놓은 스크린에 다시 들어가서 일을 할 수 있습니다.
      • 서버에 접속해서 일하실 땐 디폴트로 스크린을 하나 만들어서 들어가서 쓰시면 중간에 접속이 끊어져도 서버에서 실행중인 프로세스가 종료되지 않아서 좋습니다.
    • [tab]
      • tab키는 정말 중요합니다.
      • 디렉토리에서 abdefefsdsdfsdfsdcscs.sh 라는 파일을 실행하고 싶다면...
      • 다 타이핑 하지 마시고, 앞에 몇개만 타이핑한 뒤 [tab]키를 눌러보세요.
      • 만일 디렉토리에
        • abc123.txt, abc456.txt, ddd.txt
      • 이렇게 3개의 파일이 있다고 하면,
        • a 까지 치고 탭을 누르면
          • $ a [tab]
        • abc까지 자동 완성이 됩니다.
          • $ abc
        • 여기서 추가로 1을 타이핑하고 탭을 누르면
          • $ abc1 [tab]
        • abc123.txt가 자동완성이 됩니다.
          • $ abc123.txt
        • 왜냐면 abc로 시작하는 파일이 두개가 있기때문이죠. 즉, ddd.txt의 경우 훨씬 쉬워지죠. d로 시작하는 파일은 저것 하나뿐이므로...
          • $ d [tab]
        • 을 누르면
          • $ ddd.txt
        • 라고 자동 완성이 됩니다.

Monday, January 4, 2016

음성/음악신호+머신러닝 초심자를 위한 가이드 [1편]

음성/음악신호+머신러닝 초심자를 위한 가이드 전체 게시물은 여기를 클릭하세요.

소개

음성, 음악신호를 이용해 이러쿵저러쿵~~처리를 하고 머신러닝으로 뚝딱~ 하는 프로그램을 짜고싶다 (짜야한다..)! 그런데,

i) 오디오 신호 처리는 알지만 머신러닝을 몰라요.
OR
ii) 머신러닝은 알지만 오디오 신호 처리는 몰라요.

에 해당하시는 분들을 위해 간단한 포스팅을 씁니다. 예를 들면 아이 울음 소리를 번역하는 어플, 음악에서 자동 기타 코드 인식 등의 경우가 있겠죠.


가정:

- 문제: 아이 울음 소리를 번역하자! 이 아이가 a.배고파서 우는지 b.졸려서 우는지 이 두 가지만 고려.
- 사용 언어: 파이썬.
- 데이타: 아이 울음소리가 녹음된 파일 100개 (1.wav, 2.wav, ..., 100.wav)
- 라벨링: 되어있음. (파일명이 짝수면 배고픔, 홀수면 졸림)

가장 전통적인, 전형적인, 그리고 어지간한 성능을 보여주는 방법인 Feature extraction (특징값 추출) + classifier (분류기)의 조합을 시도해봅시다.
[방법 1] MFCC를 특징값으로 사용 + Logistic regression classifier를 써서 분류 - 가장 간단한 방법입니다.


[방법 1 - 단계a. 특징값 추출 Feature extraction]


* 준비물: 파이썬 패키지: librosa (documentation), 컴퓨터, 두뇌, 시간, 손가락, 공기, 지구 등.

- - 설치방법 생략.

* librosa.core.load

를 써서 오디오 파일을 읽어온다.
> y, sr = librosa.load('data/baby_cry.wav')

- - arguments 설명
- - - sr=22050 : input 샘플링 주파수입니다. 아마도 갖고있는 오디오 파일의 샘플링 주파수는 22050이 아닐 확률이 큽니다. 이렇게 값을 설정해주는 것은 11025 Hz 까지의 값만 써도 된다는 가정을 한 것이죠. 잘 모르시면 그냥 두세요.
- - - mono=True : 스테레오 음원일경우 모노로 바꿔준다는 말입니다. 역시 그냥 두시면 됩니다. 대부분의 경우 모노면 충분합니다. 이 글의 타겟이시면 스테레오 음원이 필요한 경우가 아닐거에요.
- - - offset, duration: 오디오 파일의 특정 구간만 쓰실경우 설정하시면 됩니다. 그러나, 초심자라면 이걸 쓰지 마시구요, 갖고있는 오디오 파일에서 의미있는 구간만 미리 잘라놓으세요. 예를들어 음원이 60초인데 아기 우는 소리가 20~35초에 있다면 그 부분만 남기고 나머지는 버려서 15초로 만들어놓고 쓰시면 됩니다.

* librosa.feature.mfcc

를 써서 오디오 신호를 mfcc로 바꾼다.
> mfcc = librosa.feature.mfcc(y=y, sr=sr)

- - arguments 설명
- - - n_mfcc=20 : mfcc 계수의 개수입니다. mfcc가 가장 활발하게 쓰이는 음성 인식에서는 대략 이 값을 수십개 (20~50)로 설정하고 씁니다. 즉 그정도면 충분하다고 알려져있습니다. 다만 주어진 상황과 목표에 따라 그 값은 다를 수 있습니다. 우선 20으로 두시면 됩니다.
- - mfcc란?
- - mfcc는 음성/음악 인식에서 가장 널리 쓰이는 특징값입니다. 자세한 설명은 위키를 참조.
mfcc 프레임 기반 특징값입니다. 즉, 각 프레임 (대체로 수 십 ms)마다 하나의 mfcc vector가 나오게 됩니다.
위의 코드를 실행하면 mfcc는 2차원 어레이가 할당됩니다. 즉

> print mfcc.shape 

를 하시면 (20, number_of_frames)이 나오게 됩니다.

이제 이 특징값을 써서 분류기를 활용해봅시다.


[방법 1 - 단계b. 분류기 Classifier]


* 분류기 Classifier

분류기란, 말그대로 분류를 해주는 기..;;입니다. 예를 들어, 20차원의 mfcc 벡터를 입력으로 하면 요 애기가 배고파서 우는지, 졸려서 우는지를 알려주는 녀석이죠. 즉 y = f(mfcc) 으로 표현해보면 f( )가 분류기에 해당하고, y는 그 결과입니다. y는 [0, 1] 중에 하나를 고르는걸로 우리가 설정해놓을 수 있죠. 즉 0=배고프다, 1=졸리다. 이렇게 설정해놓고 그에 맞춰서 트레이닝을(기계를, 혹은 알고리즘을 학습시키는 것을) 해 주는 것이죠. 좀 더 일반적으로는

판단 = f(특징값)

으로 쓸 수 있겠죠?
Logistic regression, SVM, decision tree, random forest, neural networks 등 분류기의 종류는 아주아주 많습니다.

* Logistic regression

(거의) 제일! 간단한! 분류기입니다.

*준비물: 파이썬 패키지: scikit-learn

열심히 설치하시면 됩니다.
$ pip install sklearn

* scikit-learn의 linear model의 LogisticRegression

를 쓰겠습니다.  (예제 참고)

1 > from sklearn import linear_model 
2 > logreg = linear_model.LogisticRegression()
3 > logreg.fit(X_train, y_train)
4 > y_test_estimated = logreg.predict(X_test)

요 네 줄의 코드가 핵심입니다. 그러나! 그 전에!

* X_train, y_train, x_test, y_test

머신 러닝 알고리즘의 트레이닝에선 반드시! 교차 검증 (Cross-validation)을 해야합니다.
쉽게말해, 100개의 음악 파일중 짝수는 배고픈, 홀수는 졸린 울음소리였죠? 그렇다면 2,4,6,8,..., 60 까지, 총 30개의 배고픈 울음 소리와 1,3,5,7,...,59까지, 총 30개의 졸린 울음 소리를 모아서 총 60개를 트레이닝 셋으로 두고, 나머지 40개를 테스트 셋으로 두죠. 그게 뭐냐구요? 쉽게 말하면 우리의 알고리즘 학생에게 기계학습을 열심히 시키는데, 1~60까지로 공부를 시키고 (트레이닝), 잘 이해 했는지를 61~100번으로 시험을 보는겁니다 (테스트). 왜 이렇게 하냐면, 이렇게 안하면 다들 시험에 나오는 것만 공부하고, 그래서 시험은 잘 보지만 막상 써먹을 수가 없게 되기 때문입니다.  즉, 이렇게 학습시킨 알고리즘으로 어플을 만들면 진짜로 사용자의 아기가 울었을때는 왜 우는지 전혀 맞출 수 없는거죠. (이걸 과적합/오버피팅/Overfitting이라고 합니다.)
그래서 우린 어떻게 하냐면요,

- 1~100의 wav 파일의 MFCC를 전부 구합니다.
- - 원래는 파일 하나당 여러 프레임이 존재하고, 따라서 파일 하나당 여러 개의 MFCC 벡터가 존재합니다.
- - - 귀찮으니 이걸 평균내서, 파일 하나당 하나의 MFCC 벡터를 만들었다고 합시다. 그러면 우린 총 100개의 MFCC 벡터를 갖고있지요. (n_mfcc=20, 즉 벡터는 20차원이라고 하죠.)
- 또, 아까 말했듯이 짝수는 배고픈 (=0), 홀수는 졸린(=1) 울음 소리에요.
자 이제,

- - - X_train은 60-by-20이 되도록 만드세요. 즉, 각 row는 각각의 mfcc가 되는거죠. 1번파일부터 60번 파일까지 순서대로~
- - - Y_train은 60-by-1 numpy 어레이로 하구요. 즉, 길이가 60인 [1,0,1,0,.....1,0] 이 되겠죠?
- - - X_test는 40-by-20이 됩니다. 여기엔 61번파일부터 100번 파일까지의 mfcc값을 넣습니다.
- - - Y_test는 40-by-1이구, 역시 [1,0,...1,0]인데 길이가 40이죠.
그리고 나서, 위의 코드를 돌리면! 그리고 나서,

5 > print y_test_estimated

를 통해 값을 보셔도 되고, 아무튼 열심히 y_test와 y_test_estimated를 비교하시면 됩니다.

*정리

"MFCC를 특징값으로 사용했고, 60:40으로 train set/test set을 나누었고, logistic regression을 이용해 분류(classification)를 했습니다."
- (MFCC,) training set, test set, logistic regression, classification 이 무엇인지 간략한 개념을 이해하셨으면 성공!
- 과연 방법 2를 쓰게될지는 모르겠습니다만 여튼 도움이 되었으면 좋겠습니다.