2017년 11월 3일 금요일

Combining Residual Networks with LSTMs for Lipreading 정리

알아야 할 어휘

  • Viseme
  • Any of a group of speech sounds that look the same, for example when lipreading.
  • '비슴'이라고 발음함.
  • 시각적으로 구분할 수 없는 음소

  • HMM-based, hand-engineered features, 립리딩[11, 12, 13, 14]
  • optical flow, SVM 등의 active appearance spatiotemporal descriptor [16]
  • ???[17, 18]
  • DBN 사용하여 립리딩 21% 성능 향상[22]
  • Deep autoencoder로 얻은 feature를 DCT feature와 함께 붙여 LSTM 학습[23]
  • end-to-end LSTM 사용, GRID DB에서 기존 방법들보다 높은 성능[3]
  • LSTM과 CTC 결합, GRID에서 95.2% 인식률[1]
  • attention mechanism을 사용한 encoder-decoder 방식으로 GRID DB에서 97% 달성[2]

  • 제한된 어휘의 DB에서 립리딩 전문가(사람)을 능가하는 립리딩 알고리즘[1][2]
  • 립리딩 접근 방법 2가지
  • word에 대한 모델링[3][4]
    • 고립 단어 인식에 적합
  • viseme에 대한 모델링[1][2]
    • LVCSR에 대해 적합
  • 최근에는 word 모델을 가지고 LVCSR에 적용해도 좋다는 연구가 있음[7, 8, 9]

Problem

  • DB의 word가 고립되어 있지 않고 발화 내에 있음
  • 그러므로 인식기는 문장 내에서 target word와 무시해야 하는 word를 구분하는 방법을 학습해야 함.
  • 학습 시 인식기에 대해 word boundary를 따로 알려주지는 않음

Proposed

  • 단어 수준 립리딩 state-of-the-art보다 6.8% 높은 성능을 얻음
  • word에 대한 모델이지만 Softmax layer에서 viseme 수준 인식도 가능(How ??)
  • 3 네트워크로 구성
  • front-end
    • frame 시퀀스에 대해 spatiotemporal convolution 수행
  • ResNet
  • Bi-LSTM
  • (마지막 layer) softmax

LRW Database

  • BBC 영상 기반
  • 화자/포즈 매우 다양
  • 타 DB에 비해 target word의 갯수가 매우 많음(500개)
  • 단수/복수(23쌍), 현재/과거(4쌍) 등 viseme
  • DB제작은 전부 자동으로 수행
  • 정답 text는 BBC 자막을 OCR로 얻어냄
  • word가 고립되어 있지 않고 발화 내에 있음
    • 그러므로 인식기는 문장 내에서 target word와 무시해야 하는 word를 구분하는 방법을 학습해야 함.
    • 학습 시 인식기에 대해 word boundary를 따로 알려주지는 않음
  • word 당 clip의 수
  • Training set: 1000
  • Validation, Test set: 50
  • 고정된 duration: 1.28 sec, 25fps frame rate

Deep learning modeling and preprocessing

Facial landmarks and data augmentation

  • [27, 28]에서 사용한 방법의 2D 버전을 사용
  • 66 facial landmark
  • 112 x 112 cropped size
  • 아래는 정확히 어떻게 했다는 것인지 모르겠음.
    • A common cropping is applied to all frames of a given clip, using the median coordinates of each landmark. The frames are transformed to grayscale and are normalized with respect to the overall mean and variance.
  • data augmentation은 training 도중에 수행됨(무슨 뜻인지 모르겠음)
  • 주어진 clip의 모든 프레임에 대해 random cropping(+- 5 pixels) 수평 flip

The block diagram of proposed network

Spatiotemporal front-end

  • Spatiotemporal conv. layer는 RNN 없이도 짧은 duration의 움직임 검출에 대해 좋은 성능을 냄[1]
  • 파라미터의 수: ~16K
  • Fig. 2 참고

Residual Network

  • ImageNet에서 제안된 34-레이어 짜리 사용[31]
  • pretrained model은 ImageNet이나 CIFAR 등의 task에 사용된 것이기 때문에 사용하지 않음.
  • 파라미터의 수: ~21M

Bidirectional LSTM back-end and optimization criterion

  • 파라미터의 수: ~2.4M
  • viseme에 대한 고려 없이, 최적화 criterion 관점에서 몇 가지 접근법이 있음
  • 1. 마지막 LSTM output에 대해 softmax layer를 붙여서 BPTT로 학습 시키는 것
  • 2. 각 time step에 criterion을 적용하는 것.
    • LSTM을 사용한 음성인식과 비슷
    • 음소/viseme label 대신 word label을 각 time step(모든 프레임)에 반복 적용함
    • 이는 word boundary를 모르기 때문임
    • hidden state가 모든 video 시퀀스를 알고 있어야 하기 때문에 bi-LSTM에 적용할 수 있음
  • 2번 방법이 3% 더 좋음
    • 전체 loss는 모든 time step에 대한 aggregated loss
    • word posterior의 negative log의 합

Implementation details

  • Titan X
  • SGD 학습, 0.9 momentum
  • softmax layer를 제외한 모든 conv. layer와 linear layer에 BN 적용
  • dropout은 사용하지 않음(ResNet recipe가 아니기 때문)
  • 초기 lr: 0.0005 / 최종 lr: 0.00005 (log scale로 감소)
  • validation set에 대해 3 epoch 동안 성능이 좋아지지 않으면 학습 중단
  • 15~20 epoch에서 수렴

전체 시스템 Training 방법

  • 1) Bi-LSTM 대신 temporal conv. back-end 사용
  • 2) 1)이 수렴 후 temporal conv. back-end를 없애고 Bi-LSTM을 붙여 학습
  • front-end와 ResNet 부분의 weight를 고정하여 5 epoch 동안 학습
  • 3) 2)를 end-to-end 학습
  • temporal conv. back-end와 Bi-LSTM back-end의 성능 비교 했음

Experiments

Baseline results

  • 현재 state-of-the-art는 multi-tower VGG-M[4]
  • Top-1: best score로 추정한 단어의 정확도
  • Top-N: N best score 중 정답 단어가 있는 것을 맞춘 것으로 쳤을 때 정확도

Results using proposed network

  • N1: 2D conv. ---> ResNet ---> temporal conv.
  • 각 단계 사이에 BN--ReLU--MaxPooling(1/2로 사이즈 축소됨)
  • N2: 3D conv. ---> ResNet ---> temporal conv.
  • N3: 2D conv. ---> DNN ---> temporal conv.
  • ResNet의 성능을 알아보기 위한 실험
  • DNN은 ResNet과 같은 파라미터를 가지도록 세팅함. 결과적으로 파라미터의 수가 같은데도 ResNet이 좋은 성능을 냄.


  • N4: 3D conv. ---> ResNet ---> Bi-LSTM
  • N5: 3D conv. ---> ResNet ---> 2 layers Bi-LSTM

  • N6: 3D conv. ---> ResNet ---> 2 layers Bi-LSTM
  • N5의 weight들을 starting point로 해서 end-to-end 학습
  • Fig.2 부분의 concatenate layer가 addition layer인 형태
  • (그러면 N5는 end-to-end로 학습하지 않고 front-end와 ResNet은 고정하고 Bi-LSTM만 학습했다는 얘기인가?)
    • N7: 3D conv. ---> ResNet ---> 2 layers Bi-LSTM(concatenate layer instead of addition layer)
  • N6과 구조는 거의 같고 학습 방식도 end-to-end임. N6의 addition layer를 concatenate layer로 교체(Fig.2와 같음)

Discussion and error analysis

  • baseline(VGG.M) vs. N1
    • 8.5% 향상
  • N1 vs. N2(3D conv.)
  • 3D conv.가 짧은 구간의 움직임을 강조해주어(왜?) 5.0% 성능 향상
  • 등등 각 요소를 하나씩 붙일 때마다 좋아짐

  • 음소가 많이 들어 있는 단어는 잘 맞춤
  • viseme이 많이 들어있으면 잘 틀림
  • 선행 단어, 후행 단어에 대해 조음 결합 현상이 일어나는 단어들에서 주로 틀림
  • 맨 앞과 맨 끝 부분의 viseme을 인식하는 것은 어려움

2017년 10월 22일 일요일

arrayfire batch multiplication implementation

github repo

arrayfire batch matmul

arrayfire batch matmul

matrix batch multiplication for arrayfire using cublas.

support data type, structure

The function names are af::matmul3CNN, af::matmul3CTN, af::matmul3CNT.

The '3' means "third dimension".

'N' means "normal", 'T' means "hermitian transformed".

You can read cublas gemm for detail.

The matrix batch multiplication performs below.

A(input matrix): (n x m x l) B(input matrix): (m x k x l) C(output matrix): (n x k x l) <= matmul3CXX(A x B)

And af::matmul3CXX needs 3 matrix arguments: A, B, C.

These all of 3 matrics must be prepared(allocated).

| |type |dimension | |--|----------------|-----------| |A |af::array(c32, c64) |(n x m x l)| |B |af::array(c32, c64) |(m x k x l)| |C |af::array(c32, c64) |(n x k x l)|

precaution

It doesn't support real number matrix transpose.

example

int main(void)
{
    af::setBackend(AF_BACKEND_CUDA);

    cublasHandle_t handle;
    cublasCreate(&handle);

    cudaError_t cudaStat;

    cudaStat = cudaSetDevice(0);
    if (cudaStat != cudaSuccess) {
        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
        return 0;
    }

    float Adata[4] = { 1, 2, 3, 4 };
    float Bdata[4] = { 5, 6, 7, 8 };

    auto A = af::array(2, 2, Adata, afHost).as(c32);
    auto B = af::array(2, 2, Bdata, afHost).as(c32);

    af_print(A);
    af_print(B);
    af_print(af::matmul(A, B));

    /*
    expect
        (23.0000,0.0000)          (31.0000,0.0000)
        (34.0000,0.0000)          (46.0000,0.0000)
    */

    // arrayfire matmul

    auto batchA = af::tile(A, 1, 1, 2);
    auto batchB = af::tile(B, 1, 1, 2);
    auto batchC = af::constant(0.0f, 2, 2, 2, c32);

    af_print(af::matmul3CNN(handle, batchA, batchB, batchC)); // it returns batchC.

    /*
    expect
         (23.0000,0.0000)          (31.0000,0.0000)
         (34.0000,0.0000)          (46.0000,0.0000)
         (23.0000,0.0000)          (31.0000,0.0000)
         (34.0000,0.0000)          (46.0000,0.0000)

    */
    return 0;
}

2017년 9월 24일 일요일

공부삼아 Kaldi copy-feats 프로그램을 뜯어보자

아래 검색어로 찾아보았다.

  • how to use kaldi library
  • how to use kaldi library on source code
  • kaldi library 日本語
  • kaldi 日本語 
쓸만한 사이트가 없다. 

직접 소스코드 읽어서 공부해야 함. 

copy-feats 소스코드를 공부하고, 소스코드를 약간 고쳐서 빌드를 시도해보자. 

소스코드는 아래에 


프린트해서 종이에 메모하였다.
 

gcc가 copy-feats를 빌드하는 과정이 어디 있는지 찾아보자.

src/featbin/Makefile

copy-feat을 빌드하는 Makefile이다.


​Makefile 내용을 캡쳐해서 여기서 주석 달기






SUBDIRS를 빌드하는 부분이다. .PHONY 타겟에 대해 아래를 참고했다.

http://pinocc.tistory.com/131



전부 빌드되는 거라면 나만의 디렉토리를 따로 만들어서 거기다가 copy-feats.cc를 이동하고, src/hybin 을 만들었다.

 make에 수동으로 Makefile 말고 다른 파일을 빌드하도록 전달할 수 있는지 찾아보았다.
(디폴트가 Makefile일 수도 있기 때문)

make 명령 시 target의 이름을 직접 넣어주면 그 타겟의 위치부터 make를 시작함

그러므로 기존 src/Makefile의 내용에 따로 타겟을 만들면 됨.



src/hybin/Makefile을 만들었다.​



copy-feats를 빌드하고, 작동을 확인한다.



아래 오타를 제보하자. 

http://kaldi-asr.org/doc/group__table__group.html#ga0b3ec62400216b77be81739825c9ce28 

아래 인수 중 wxfilename이 rxfilename으로 바뀌어야 함​

2017년 9월 7일 목요일

Complex double binary to matlab converter

WaveManager: C/C++ buffer <-> PCM format wav file converter

2017년 8월 18일 금요일

Kaldi Toolkit을 사용한 음성인식 시스템의 구조 ppt(shinozaki lab ppt 번역)

이 글은 저의 예전 블로그의 글을 옮긴 것입니다.

칼디 관련 튜토리얼 중 좋은 자료가 없나 찾아보다가, 도쿄공업대학 시노자키 교수님 연구실에 있는 튜토리얼 자료를 발견하였습니다. 분량이 그렇게 많지 않아, pdf를 ppt로 변환하여 번역을 해보았습니다.

원본의 URL입니다.

Kaldiツールキットを用いた 音声認識システムの構築(Kaldi 툴킷을 사용한 음성인식 시스템의 구축)

Shinozaki 교수님 연구실의 주소입니다.

http://www.ts.ip.titech.ac.jp/

혹시 오역이나 잘못된 부분이 있으면 연락주시기 바랍니다.

제 이메일 주소입니다.

gogyzzz@gmail.com

HTK installation on ubuntu 16.04

Emotion Recognition using GMM-HMM in Kaldi