Monday, July 27, 2020

Latex add directory for figure

In the practice of Latex writing, it is common to use the same figure or figure directory across different projects (papers). Instead of a copy-paste-ing figure directory, which is usually big in size, it is better to just drop a line of latex code to specify where the location of the figure directory. By using this technique, we can avoid increasing memory size by preventing copying the same files/figures used by different tex files.

Here is how.
% for a single directory
\graphicspath{{figures/}} %Setting the graphicspath

% for multiple directories
\graphicspath{{figures1/}{figures2/}{figures3/}} %Setting the graphicspath


Don't forget the slash '/' after the name of the directory.
That's all. It works!

Monday, July 13, 2020

Menginstall static library di (JAIST) cluster

Salah satu kelemahan (sekaligus keunggulan) menggunakan superkomputer atau komputer cluster adalah ketiadaan akses root. Akses root ditiadakan agar user tidak bisa mengutak-atik system. Apa jadinya kalau user bisa masuk /usr, /lib, /etc, dll...? Sistem akan dengan sangat mudah dilumpuhkan, pun tanpa serangan (ketidak sengajaan, ketidaktahuan, dll).

Tidak punya akses ke root artinya tidak bisa menginstall program atau library di sistem. Hanya admin yang bisa melakukannya. Permasalahan yang sering muncul adalah menghadapi admin yang bandel alias strict. Contoh: saya minta di-installkan library A, "Dear Pak Admin, tolong install library A di server/superkomputer." Alih-alih memberi jawaban, biasanya admin ngeles seperti ini, "maaf saya tidak terbiasa menggunakan library A, di kluster sudah tersedia library B." Tamat sudah kalau begini jawabannya. Cari cara lainnya.

Kalau anda sering menggunakan Linux atau Unix, berita baiknya, anda bisa menggunakan library atau program tanpa perlu meningstallnya ke system (/usr/bin). Ini dinamakan library statik. Kita bisa menginstall library di home direktory dan memerintahkan sistem untuk mencari di library home tersebut. Singkatnya begini: Hai sistem, cari librari ini ditempat ini. Berikut dua contoh instalasi library statik: ffmpeg dan libsndfile. Dua-duanya dipakai untuk pemrosesan suara.

ffmpeg

Jika menggunakan komputer biasa, library ini dengan mudah bisa di-install dengan `sudo apt intall ffmpeg`. Di superkomputer atau kluster hal ini tidak bisa dilakukan. Untung ada pre-built statik library ffmpeg yang disediakan oleh https://johnvansickle.com/. Download file-nya, uncompress, dan update $PATH seperti berikut.


wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz
tar -xvf ffmpeg-git-amd64-static.tar.xz

Hasilnya, kita akan memiliki direktory yang berisi program ffmpeg. Misalnya direktori dengan versi berikut: "ffmpeg-git-20200130-amd64-static". Di dalamnya ada direktori bin dan didalam bin ada file program ffmpeg. Jadi kita arahkan $PATH pada lokasi tersebut. Ketik perintah berikut pada terminal.
export PATH="/home/$USER/ffmpeg-git-20200130-amd64-static:$PATH"

Untuk mempermamenkannya, kita bisa letakkan perintah tersebut di .bashrc atau .bash_profile dan kita `source` untuk mengupdate file config bash tersebut. Sangat simpel dan cepat (daripada meminta tolong admin kluster).

libsndfile

Pada contoh kedua saya menggunakan linuxbrew. Brew adalah program seperti apt/apt-get yang didesain untuk Unix (Mac dan Linux). Pertama kita harus menginstall linuxbrew di home direktori cluster.
wget https://raw.githubusercontent.com/Homebrew/install/master/install.sh
bash ./install.sh
Kadang kita perlu mengganti akses permisi dari file install.sh. Jika dibutuhkan, coba dengan `chmod +x install.sh`.
Brew akan memberi pilihan dimana kita menginstall. By default akan diinstall di system (root). Lagi, karena kita tidak punya akses ke root, maka installasi brew kita tempatkan di home direktori (pilih opsi ini dengan Ctrl-D). Nah setelah terinstall, seperti halnya ffmpeg, kita akan memiliki program brew di .linuxbrew/bin. Ini contohnya pada kasus saya.

Singularity tensorflow_1.14.0-gpu-py3.sif:~> ls .linuxbrew/bin/brew 
.linuxbrew/bin/brew
Sekarang kita bisa menginstall program yang tersedia di brew, termasuk ffmpeg dan libsndfile. Libsndfile kita install dengan perintah berikut,

Singularity tensorflow_1.14.0-gpu-py3.sif:~> .linuxbrew/bin/brew install libsndfile 
/home/s1820002/.linuxbrew/Homebrew/Library/Homebrew/brew.sh: line 4: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
/home/s1820002/.linuxbrew/Homebrew/Library/Homebrew/brew.sh: line 4: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory
Updating Homebrew...
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
/home/s1820002/.linuxbrew/Homebrew/Library/Homebrew/brew.sh: line 4: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
No changes to formulae.

/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
/home/s1820002/.linuxbrew/Homebrew/Library/Homebrew/brew.sh: line 4: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory
Warning: libsndfile 1.0.28 is already installed and up-to-date
Karena saya sudah menginstallnya maka brew mengabari kalau libsndfile sudah terinstall dan update. Langkah terakhir adalalah mengupdate #LD_LIBRARY_PATH. Semua library yang terinstall dengan brew akan terinstall di .linuxbrew/lib. Karenanya kita perintahkan LD_LIBRARY_PATH untuk mencari library di situ.

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$HOME/.linuxbrew/lib"

Bisa juga perintah tersebut ditambahkan di .bashrc. Saya juga perlu menambahkan ini dalam .bashrc,
eval $(~/.linuxbrew/bin/brew shellenv)

Seleasai. Sekarang kita bisa menggunakan container tensorflow dengan library LibROSA yang membutuhkan libsndfile untuk membaca file suara.

Studi case di JAIST cluster
Di JAIST cluster, saat kita masuk ke vpcc (cluster yg memiliki gpu) telah tersedia tensorflow-gpu via container (singularity). By default, python yang diload adalah python bawaan Anaconda yang menyebabkan library tidak dapat ditemukan (karena perbedaan path, kemungkinan). Solusinya adalah dengan tidak menggunakan python bawaan anaconda, dan menggunakan python bawaan container/singularity dengan perintah berikut.
module remove py35

Cara tersebut cukup ampuh daripada meminta admin untuk menginstall library (sndfile) di cluster.

Thursday, July 09, 2020

How-to: Install Numba and LibROSA in Jetson AGX Xavier (Ubuntu 18.04)

Installing Numba and Librosa in Jetson AGX Xavier is very painful. To document my experience, I wrote this note. Here is how-to install Numba and Librosa on AGX Xavier.

Device: AGX Xavier Dev Kit (32GB RAM)
Software
OS: Ubuntu 18.04
nvidia-jetpack: Version: 4.4-b186
python: Version 3.6.9
llvm: Version 9.0.1 (and 7.1.0)

First, we need to install llvmlite. We can install either from source or via apt. I installed it from the source as shown below.

cd /tmp
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-9.0.1/llvm-9.0.1.src.tar.xz
tar -xvf llvm-9.0.1.src.tar.xz 
cd llvm-9.0.1.src/
mkdir llvm_build_dir
cd llvm_build_dir
cmake ../ -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="ARM;X86;AArch64"
make -j4
sudo make install
cd bin/
echo "export LLVM_CONFIG=\""`pwd`"/llvm-config\"" >> ~/.bashrc
echo "alias llvm='"`pwd`"/llvm-lit'" >> ~/.bashrc
source ~/.bashrc
python3.6 -m pip install --user -U llvmlite==0.31

If you want to install via apt, do it as follows. I use llvm-7 from Ubuntu repository (llvm-9 fails installing llvmlite 0.31 but success for 0.33).

sudo apt install llvm-7

If you install llvm via apt, you need to specify where llvm-config is located in .bashrc. For example here is mine. First, locate llvm-config.
s1820002@s1820002-desktop:~$ locate llvm-config
/usr/bin/llvm-config-7
/usr/include/llvm-7/llvm/Config/llvm-config.h
/usr/lib/llvm-7/bin/llvm-config

Then add the location of llvm-config to .bashrc.
export LLVM_CONFIG=/usr/lib/llvm-7/bin/llvm-config

Please be remembered that you need to `source .bashrc` after you edit your .bashrc.

As an alternative to using .bashrc, you can make softlink by mapping llvm-config-9 to llvm-config.
$ cd /usr/bin
$ sudo ln llvm-config-9 llvm-config

The installation of llvm must success before installing llvmlite. If installation of llvmlite by the last line on the script above success, it shows like this one,

Collecting llvmlite
Installing collected packages: llvmlite
Successfully installed llvmlite-0.33.0

If you face an error regarding `setuptools`, you may upgrade your setuptools as follows.

python3.6 -m pip install --user -U setuptools

Now, we can install numba. We need numba version 0.48 to install librosa 0.7.2. To install Numba, first, we must disable tbb.h according to this.

sudo mv /usr/include/tbb/tbb.h /usr/include/tbb/tbb.h.bak

Then, install numba as the following:
bagus@s1820002:~$ python3.6 -m pip install --user -U numba==0.48
Collecting numba==0.48
Collecting setuptools (from numba==0.48) Using cached
 https://files.pythonhosted.org/packages/41/fa/60888a1d591db07bc9c17dce2bcfb9f00ac507c0a23ecb827e76feb8f816/setuptools-49.1.0-py3-none-any.whl
Collecting numpy>=1.15 (from numba==0.48)
Collecting llvmlite<0 .32.0="">=0.31.0dev0 (from numba==0.48)
Installing collected packages: setuptools, numpy, llvmlite, numba
Successfully installed llvmlite-0.33.0 numba-0.50.1 numpy-1.19.0 setuptools-49.1.0

Again, it must install numba without fail to be able to install Librosa.
Before installing librosa, the following packages must be installed via apt.
sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev gfortran

Finally, we can install librosa via pip as below.
bagus@s1820002:~$ python3.6 -m pip install --user -U librosa
Collecting librosa
Collecting resampy>=0.2.2 (from librosa)
Collecting numpy>=1.15.0 (from librosa)
Collecting numba>=0.43.0 (from librosa)
Collecting scikit-learn!=0.19.0,>=0.14.0 (from librosa)
Collecting joblib>=0.12 (from librosa) Using cached
 https://files.pythonhosted.org/packages/51/dd/0e015051b4a27ec5a58b02ab774059f3289a94b0906f880a3f9507e74f38/joblib-0.16.0-py3-none-any.whl
Collecting scipy>=1.0.0 (from librosa)
Collecting soundfile>=0.9.0 (from librosa) Using cached
 https://files.pythonhosted.org/packages/eb/f2/3cbbbf3b96fb9fa91582c438b574cff3f45b29c772f94c400e2c99ef5db9/SoundFile-0.10.3.post1-py2.py3-none-any.whl
Collecting decorator>=3.0.0 (from librosa) Using cached
 https://files.pythonhosted.org/packages/ed/1b/72a1821152d07cf1d8b6fce298aeb06a7eb90f4d6d41acec9861e7cc6df0/decorator-4.4.2-py2.py3-none-any.whl
Collecting six>=1.3 (from librosa) Using cached
 https://files.pythonhosted.org/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.whl
Collecting audioread>=2.0.0 (from librosa)
Collecting llvmlite<0 .34="">=0.33.0.dev0 (from numba>=0.43.0->librosa)
Collecting setuptools (from numba>=0.43.0->librosa) Using cached
 https://files.pythonhosted.org/packages/41/fa/60888a1d591db07bc9c17dce2bcfb9f00ac507c0a23ecb827e76feb8f816/setuptools-49.1.0-py3-none-any.whl
Collecting threadpoolctl>=2.0.0 (from scikit-learn!=0.19.0,>=0.14.0->librosa) Using cached
 https://files.pythonhosted.org/packages/f7/12/ec3f2e203afa394a149911729357aa48affc59c20e2c1c8297a60f33f133/threadpoolctl-2.1.0-py3-none-any.whl
Collecting cffi>=1.0 (from soundfile>=0.9.0->librosa)
Collecting pycparser (from cffi>=1.0->soundfile>=0.9.0->librosa) Using cached
 https://files.pythonhosted.org/packages/ae/e7/d9c3a176ca4b02024debf82342dab36efadfc5776f9c8db077e8f6e71821/pycparser-2.20-py2.py3-none-any.whl
Installing collected packages: six, numpy, scipy, llvmlite, setuptools, numba, resampy, threadpoolctl, joblib, scikit-learn, pycparser, cffi, soundfile, decorator, audioread, librosa
Successfully installed audioread-2.1.8 cffi-1.14.0 decorator-4.4.2 joblib-0.16.0 librosa-0.7.2 llvmlite-0.33.0 numba-0.50.1 numpy-1.19.0 pycparser-2.20 resampy-0.2.2 scikit-learn-0.23.1 scipy-1.5.1 setuptools-49.1.0 six-1.15.0 soundfile-0.10.3.post1 threadpoolctl-2.1.0

Now everything seems good. We can do audio processing in Jetson AGX. Librosa is the best audio library in python so far. Having it installed on Jetson is a basic requirement.

BONUS: Installing TensorFlow
Step-by-step:
1. Install the following packages.
sudo apt-get install libhdf5-serial-dev hdf5-tools libhdf5-dev zlib1g-dev zip libjpeg8-dev
2. Install/upgrade testresources
python3.6 -m pip install --user -U testresources
3. Installing other python dependencies
python3.6 -m pip future==0.17.1 mock==3.0.5 h5py==2.9.0 keras_preprocessing==1.0.5 keras_applications==1.0.8 gast==0.2.2 futures protobuf pybind11
4. Install tensorflow.
python3.6 -m pip install --user --pre --extra-index-url https://developer.download.nvidia.com/compute/redist/jp/v43 'tensorflow<2' 
output:
Successfully installed absl-py-0.9.0 astor-0.8.1 google-pasta-0.2.0 grpcio-1.30.0 importlib-metadata-1.7.0 markdown-3.2.2 opt-einsum-3.2.1 tensorboard-1.15.0 tensorflow-1.15.2+nv20.3.tf1 tensorflow-estimator-1.15.1 termcolor-1.1.0 werkzeug-1.0.1 wrapt-1.12.1 zipp-3.1.0
5. Test the GPU device.
import tensorflow as tf
tf.test.gpu_device_name()
output:
>>> tf.test.gpu_device_name()
2020-07-10 16:01:36.242822: W tensorflow/core/platform/profile_utils/cpu_utils.cc:98] Failed to find bogomips in /proc/cpuinfo; cannot determine CPU frequency
2020-07-10 16:01:36.244367: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x37b6c3f0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-07-10 16:01:36.244536: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
2020-07-10 16:01:36.259171: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcuda.so.1
2020-07-10 16:01:36.432077: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:950] ARM64 does not support NUMA - returning NUMA node zero
2020-07-10 16:01:36.432674: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x37a81480 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices:
2020-07-10 16:01:36.432768: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Xavier, Compute Capability 7.2
2020-07-10 16:01:36.433580: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:950] ARM64 does not support NUMA - returning NUMA node zero
2020-07-10 16:01:36.433892: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1639] Found device 0 with properties: 
name: Xavier major: 7 minor: 2 memoryClockRate(GHz): 1.377
pciBusID: 0000:00:00.0
2020-07-10 16:01:36.433987: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.0
2020-07-10 16:01:36.467839: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10.0
2020-07-10 16:01:36.496813: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcufft.so.10.0
2020-07-10 16:01:36.534413: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcurand.so.10.0
2020-07-10 16:01:36.576197: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcusolver.so.10.0
2020-07-10 16:01:36.600464: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcusparse.so.10.0
2020-07-10 16:01:36.688185: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudnn.so.7
2020-07-10 16:01:36.688573: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:950] ARM64 does not support NUMA - returning NUMA node zero
2020-07-10 16:01:36.690082: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:950] ARM64 does not support NUMA - returning NUMA node zero
2020-07-10 16:01:36.690253: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1767] Adding visible gpu devices: 0
2020-07-10 16:01:36.690456: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.0
2020-07-10 16:01:38.484495: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1180] Device interconnect StreamExecutor with strength 1 edge matrix:
2020-07-10 16:01:38.484668: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1186]      0 
2020-07-10 16:01:38.484715: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1199] 0:   N 
2020-07-10 16:01:38.485215: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:950] ARM64 does not support NUMA - returning NUMA node zero
2020-07-10 16:01:38.485695: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:950] ARM64 does not support NUMA - returning NUMA node zero
2020-07-10 16:01:38.485953: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1325] Created TensorFlow device (/device:GPU:0 with 23699 MB memory) -> physical GPU (device: 0, name: Xavier, pci bus id: 0000:00:00.0, compute capability: 7.2)
'/device:GPU:0
Source:
[1] https://github.com/jefflgaol/Install-Packages-Jetson-ARM-Family
[2] https://forums.developer.nvidia.com/t/install-python-packages-librosa-jetson-tx2-developer-kit-problem/126337/5
[3] https://learninone209186366.wordpress.com/2019/07/24/how-to-install-the-librosa-library-in-jetson-nano-or-aarch64-module/

Friday, July 03, 2020

Outline: Persepsi pendengaran manusia dan pemodelannya

Berikut adalah outline catatan kuliah "Human Perceptual Systems and its Models" yang diajarkan oleh Prof. Unoki di JAIST pada tahun 2018. Agar tidak menguap begitu saja, catatan-catatan tersebut saya cantumkan di sini. Kuliah ini sangat berguna bagi mereka yang ingin mempelajari bagaimana sistem pendengaran manusia bekerja (auditory system) serta model komputasinya.
  1. Pengantar persepsi manusia dan pemodelannya
  2. Pengolahan sinyal auditori
  3. Representasi suara dan pemrosesannya
  4. Analisa sinyal suara dan teknik sintesis
  5. Fisiologi dari peripheral auditori dan pemodelannya
  6. Ketidaklinearan sistem pendengaran
  7. Atensi, hubungannya dengan cocktail party problem dan deeplearning
  8. Ketidaksinkronan mata dan telinga: Efek McGurk
Opsional:  
 Satu hal yang paling menarik dari kuliah tersebut adalah bagaimana membuat model yang meniru (imitate) bagaimana sistem pendengaran manusia bekerja. Meski tidak semua dapat dimodelkan dengan eksak, dan tidak semua model yang meniru cara kerja manusia lebih baik dari model lain (misal, deep learning), model dengan hasil terbaiklah yang dipakai. Dan biasanya model terbaik tersebut merupakan kompromi antara peniruan cara kerja manusia dan, misalnya, deep learning.

Catatan kuliah ini juga disimpan di Github pada alamat berikut: https://github.com/bagustris/perseptual.

Monday, June 22, 2020

Menghapus dan mengganti data NaN pada Numpy

Data NaN (Not a Number) sangat menjengkelkan; bisa dibilang sampah. Data ini, bisa dari pengukuran atau simulasi, tidak dipakai dalam pengolahan data dan perlu dihilangkan atau diganti. Ya, dua cara tersebut (menghapus atau mengganti data NaN) merupakan dua cara agar data yang terkontaminasi NaN bisa diproses. Oya, data NaN ini juga bisa merupakan data outlier, misal ketika mengukur suhu rentang 23-27 derajat celcius kita mendapatkan data pengukuran 127 celcius yang tentu saja tidak masuk akal. Bisa juga data NaN ini berupa nilai "0" karena kegagalan sensor pengukuran.

Menghapus Data NaN di Numpy

Misalkan kita memiliki 10 data pengukuran dari tiga sensor.  Pertama, kita mencari elemen NaN sebagai berikut.
In [1]: import numpy as np 
In [2]: a = np.array([[1, 2, 4], [1, 2, 1], [np.nan, 1, 2], [1, 2, np.nan], [2, 1, 1]])
In [3]: np.isnan(a).any()
Out[3]: True
In [4]: np.where(np.isnan(a))                                                                           
Out[4]: (array([2, 3]), array([0, 2]))

Dari output ipython tersebut kita mengetahui bahwa data NaN berada pada (2, 0) dan (3, 2). Ingat Python mengindeks dari 0. Untuk menghapus baris (row) yang berisi NaN, gunakan perintah berikut:

In [3]: b = a[~np.isnan(a).any(axis=1)] 

Algoritma menghapus NaN pada satu baris di atas dapat dijelaskan sbb:
1. Mencari indeks data NaN dengan np.isnan.
2. Mencari data jika ada NaN dengan np.any.
3. Mencari data jika ada NaN pada kolom (axis=1, karena yang kita hapus barisnya).
4. Membalik hasil pencarian pada (1-3) dengan ~, dengan kata lain, cari data yang bukan NaN.

Untuk lebih jelasnya, perhatikan setiap output perintah berikut:
In [57]: np.isnan(a)                                                                                     
Out[57]: 
array([[False, False, False],
       [False, False, False],
       [ True, False, False],
       [False, False,  True],
       [False, False, False]])
In [58]: np.isnan(a).any()                                                                               
Out[58]: True
In [59]: np.isnan(a).any(axis=1)                                                                         
Out[59]: array([False, False,  True,  True, False])
In [60]: ~np.isnan(a).any(axis=1)                                                                        
Out[60]: array([ True,  True, False, False,  True])

In [61]: a[~np.isnan(a).any(axis=1)]                                                                     
Out[61]: 
array([[1., 2., 4.],
       [1., 2., 1.],
       [2., 1., 1.]])
Baris untuk memfilter data NaN disebut fancy indexing. Inilah salah satu hal yang paling membedakan Numpy dengan List python. Dengan teknik ini kita bisa memfilter suatu array dengan array lainnya. Contohnya data dengan index NaN ini. Permasalahan menghapus data yang berisi NaN selesai.

Mengganti Data Nan di Numpy

Bagaimana jika kita tidak ingin menghapus dana NaN, tapi mengubahnya..? Misal, dalam pengukuran suhu, suhu yang tidak terbaca sensor kita anggap sebagai suhu 25 derajat celcius.
Berikut data dummy pengukuran tiga sensor suhu.

In [52]: a = np.random.uniform(23, 28, [10, 3])                                 

In [53]: a                                                                      
Out[53]: 
array([[27.78837233, 23.24395001, 23.57374599],
       [24.19978931, 23.25094801, 24.49294423],
       [26.73693715, 23.16475293, 25.96576384],
       [26.70315233, 24.85865614, 25.3510446 ],
       [25.31885087, 27.42903322, 25.26193883],
       [25.68032566, 27.06242615, 27.0408585 ],
       [26.64473586, 27.56036335, 24.49159284],
       [24.90196938, 26.00082306, 25.70781393],
       [26.58828295, 25.36263426, 27.6251521 ],
       [24.63801191, 24.23193679, 26.99034562]])

Kita tambahkan 5 data NaN secara acak.
In [54]: a.ravel()[np.random.choice(a.size, 5, replace=False)] = np.nan         

In [55]: a                                                                      
Out[55]: 
array([[27.78837233,         nan,         nan],
       [24.19978931, 23.25094801, 24.49294423],
       [26.73693715, 23.16475293, 25.96576384],
       [26.70315233, 24.85865614, 25.3510446 ],
       [        nan, 27.42903322, 25.26193883],
       [25.68032566, 27.06242615, 27.0408585 ],
       [26.64473586, 27.56036335,         nan],
       [24.90196938, 26.00082306, 25.70781393],
       [26.58828295,         nan, 27.6251521 ],
       [24.63801191, 24.23193679, 26.99034562]])

Terlihat 5 data NaN pada baris 0, 4, 6, dan 8 (indeks mulai dari 0). Kita ganti data NaN tersebut dengan 25.0 derajat celcius. Perintah yang digunakan adalan np.nan_to_num(a, nan=25.0).

In [56]: np.nan_to_num(a, nan=25.0)                                             
Out[56]: 
array([[27.78837233, 25.        , 25.        ],
       [24.19978931, 23.25094801, 24.49294423],
       [26.73693715, 23.16475293, 25.96576384],
       [26.70315233, 24.85865614, 25.3510446 ],
       [25.        , 27.42903322, 25.26193883],
       [25.68032566, 27.06242615, 27.0408585 ],
       [26.64473586, 27.56036335, 25.        ],
       [24.90196938, 26.00082306, 25.70781393],
       [26.58828295, 25.        , 27.6251521 ],
       [24.63801191, 24.23193679, 26.99034562]])

Cukup sederhana, jika argumen nan=25.0 tidak ditambahkan, maka data NaN akan diganti dengan angka "0" (default). Jika ingin mengganti dengan angka lain, misal 25.5, tinggal mengganti nan=25.5. Selesai permasalahan mengganti data NaN pada Numpy array.
 
Untuk Pandas (dataframe) silahkan baca di sini.

Saturday, June 20, 2020

Konversi file svg ke pdf via terminal

Ekstensi pdf sangat fleksibel, baik digunakan secara independen maupun ketika di "embedd" ke dalam file lain, misalnya Latex. Gambar yang baik (resolusinya) kebanyakan bukan dalam format pdf, tapi (contohnya) SVG. Konversi yang cepat (dalam hitungan detik) dibutuhkan agar kita tidak perlu membuka program berbasis grafis (seperti InkScape atau Adobe Illustration) untuk konversi dari SVG ke PDF. Berikut solusinya.

# install program jika belum terinstall
$ sudo apt-get install librsvg2-bin
$ rsvg-convert -f pdf -o output.pdf input.svg

Cara ini menghemat waktu sekitar 10 menit dari cara konvensional (berbasis grafis). Selain itu, aplikasi berbasis grafis sering "mend-distract" kita untuk mengerjakan sesuatu yang lain di aplikasi tersebut.

Thursday, June 11, 2020

Benchmarking Intel-based Numpy packages

Intel has their own distribution (modified version) of Numpy, Scipy, and scikit-learn packages. They claim that these packages are optimized from those existing packages. To prove this claim, I made a little following benchmark. I used two similar machines MBP 2012 and Lenovo G580. Both have similar specs, i7-3520 processors, and 16GB RAM. The following code I used to benchmark.

Saturday, June 06, 2020

Outline: Logika bahasa ilmiah

Berikut adalah outline dari beberapa resume kuliah "Scientific Discussion" yang diajar oleh Prof. Preining pada 2019 di JAIST. Agar tidak menguap begitu saja, saya membuat outline (daftar isi/tulisan) yang pernah saya buat untuk merangkum isi kuliah tersebut. Dalam Bahasa Indonesia, "scientific discussion" lebih pas diterjemahkan sebagai "logika bahasa ilmiah" atau "logika diskusi ilmiah", karena isinya banyak berupa prinsip logika yang dipakai dalam diskusi ilmiah.

Materi kuliah tersebut sangat cocok untuk membangun alur berpikir dalam berbahasa ilmiah, baik tulisan maupun lisan (lebih dikhususkan pada tulisan, namun bisa diaplikasikan secara lisan/ucapan, less formal). Klik setiap baris item outline di bawah ini untuk membaca artikel dengan judul tersebut.

  1. Menjadi logis: Menyiapkan akal untuk logika
  2. Menjadi logis: Prinsip dasar logika
  3. Argumen: Bahasa logika [1]
  4. Argumen: Bahasa logika [2]
  5. Sumber pemikiran tidak logis
  6. Prinsip-prinsip pemikiran tidak logis
  7. Logika dan percakapan-nya Grice (implikatur) beserta kritiknya
  8. Panduan berpikir kritis
Tulisan-tulisan tersebut cukup menarik karena sejatinya bukan tulisan saya. Namun, ulasan dari buku-buku dan makalah yang benar-benar berbobot. Beruntung saya pernah mendapatkan kuliah tersebut. 

Jika ada tulisan baru saya dengan tema yang sama/mirip, akan saya tambahkan dalam outline di atas.

Monday, May 18, 2020

Pentingnya bersih-bersih setiap hari...

Pada suatu ketika, di sela-sela belajar bahasa Jepang (kursus gratis man-to-man diadakan oleh volunteer), guru saya bertanya, "Bagus-san, kamu bersih-bersih tiap berapa hari sekali?" Saya menjawabnya, "Seminggu sekali, sensei." Sensei saya menimpali "Are, Takebi-sensei, mainichi souji shimasu". Itu si Takebi-sensei bersih-bersih rumahnya tiap hari. Takebi-sensei yang berada di belakang saya mengangguk dan menimpali, "hai, mainichi souji shimasu." Orang jepang suka yang bersih dan suka bersih-bersih. Bahkan saya curiga, pekerjaan mereka cuma bersih-bersih.

Mari berhenti sejenak dari membaca tulisan ini dan melihat dua video pendek berikut yang dibuat oleh vlogger amatir Jepang.



Saturday, May 09, 2020

Ketidaksinkronan telinga dan mata: Efek McGurk

Efek McGurk adalah salah satu contoh nyata pemrosesan multimodal manusia (human multimodal perception). Sederhananya, jika apa yang diperdengarkan berbeda dengan apa yang diperlihatkan, maka otak kita akan menerimanya dengan berbeda juga.

Yang diperdengarkan (audio): BA-BA-BA
Yang diperlihatkan (visual): GA-GA-GA
Yang terdengar: DA-DA-DA

Ini adalah sebuah ilusi. Sistem multimodal persepsi manusia tidak bekerja sendiri-sendiri (misal penglihatan sendiri, pendengaran sendiri), namun bekerja bersama-sama untuk menghasilkan persepsi (dalam hal ini persepsi pendengaran). Ketika sensor bekerja secara simultan (mata dan telinga) maka informasi dari keduanya akan diproses oleh otak dan hasilnya, terjadilah ilusi, apa yang terdengar (DA) bukan sebenarnya (BA). Video di bawah ini menjelaskan dengan singkat dan padat tentang efek McGurk.




Efek McGurk pada Audio-Textual

Adakah efek McGurk pada Audio-textual? Saya meyakininya ada, namun belum ada bukti empiris hal itu terjadi. Sederhana saja, jika pada audio-visual fenomena tersebut ada, kenapa tidak pada audio-textual? Misal Si A mengatakan "Dia marah", namun si B mendengar "Dia ramah". Alhasil, si B kemudian menimpali "Ah enggak, dia enggak ramah sama sekali." Pernah kan kita dalam situasi seperti ini? Fenomena ini asyik kalau dibuat eksperimennya. Semoga kelak saya (atau orang lain) bisa melakukannya.

Penutup

Efek McGurk mengajarkan kepada kita: Apa yang kita dengar dan kita lihat belum tentu benar!.

Wednesday, May 06, 2020

10 tips for writing a truly terrible journal article

This post is a summary of tutorial video on research academy at Elsevier:
https://researcheracademy.elsevier.com/writing-research/writing-skills/10-tips-writing-truly-terrible-journal-article.
Visit the link for a more complete explanation. This writing is just a short version of what I heard.

Bear in mind, the following 10 sure-fire ways guarantee your paper won’t be accepted (NOT THE OPPOSITE). So, to make your paper to be accepted, DO THE OPPOSITE WAYS. You already have been warned.

The 10 tips (minute 13:31)

1. Refuse to read the previous literature published in your field.

Every scientific paper should add knowledge to the field. In other words, it should contain novelty. Failure to read previously reported findings means a rejection for you.

2. Take the lazy route and plagiarize (including your previous own article)

Don't make a double submission because of laziness waiting review. Don't plagiarize others including your own. If you submit an article from conference to journal (with a major change of contributions), cite and state your previous works. Plagiarism is a crime no matter how small it is.

3. Omit key article components.

Scientific article follows strict rules and components. One of the well-known is IMRaD model (Intro, Method, Results, and Discussion; conclusions is optional).

4. Disrespect previous publications.

Example of disrespecting previous publications: plagiarism, repeating paper without adding novel contribution, not citing previous papers, etc.

Saturday, May 02, 2020

Mengedit video dan audio untuk keperluan konferensi virtual

Di musim pandemi seperti sekararang ini, banyak seminar/konferensi dialihkan menjadi online/virtual. Tulisan ini akan membahas teknik presentasi online/virtual berbasis perangkat lunak  gratis, khususnya yang berjalan di sistem operasi berbasis Linux.

Perangkat yang dibutuhkan/digunakan antara lain: Beamer atau Impress atau Google Slide, SimpleScreenRecorder atau OBS Studio, ffmpeg dan audacity. Jadi setidaknya kita menggunakan empat perangkat, misal Beamer > OBS > ffmpeg > Audacity, atau, Impress > SimpleScreenRecorder > ffmpeg > Audacity. Diagram alir dari langkah-langkah yang dilakukan dapat digambarkan pada gambar di bawah ini.


Diagram alir proses peremakan presentasi virtual
Di akhir tulisan, saya akan demokan dua hasil perekaman dengan teknik yang saya jelaskan di artikel ini.

Thursday, April 23, 2020

Dos and Don'ts in Academic Presentation


Before reading this article it is suggested to read the previous article on 201 presentation skills (in Bahasa, right-click in Chrome and click translate, to make it in English).

This article is a resume/summary of the book "Conferencing and Presentation" by Michael Guest, particularly on Part IV (chapter 12-16). The book itself is free and can be downloaded from the Springer  Nature website. The following dos and don'ts focus on a practical manner from opening to closing. Before entering this structure, however, formulae to formulaic academic phrases serve is listed as building blocks of academic discourse. These formulae including,
  1. Occupy a mid-point between ‘general English’ and specialist terminology;
  2. Contain constituents that are flexible (i.e., excluded vs. ruled out, possibilities vs. results);
  3. Have cross-disciplinary academic application;
  4. Are utilized in both written and spoken modes;
  5. Hold long-term (intrinsic) value for academics/professionals;
  6. Mark entry or membership into the academic discourse community.
Having those formulaic phrases, Let's start the practical implementation of those phrases in the academic presentation.

1. Opening
Don'ts:
  • My name is X, and my presentation is entitled Y. (this and next three are too slight)
  • Hello everyone.
  • My topic today is X. (This and below are too much casual)
  • Today I’m going to present about X.
  • I’ll present on X, OK?
  • OK, so, I’ve just changed the title to show... X.
  • I’m gonna talk about something that is very hot ‘n sexy...

Monday, April 06, 2020

Berpindah ke vscode (dari gEdit)

Hidup itu harus dinamis, tidak harus saklek pada satu hal (tool/perangkat). Ketika ada perangkat lain yang lebih mudah, meskipun awalnya saya membencinya, maka kita harus berpindah ketika ternyata perangkat tersebut memberikan kemudahan dan kecepatan dari perangkat lama.

Kali ini saya berbicara tentang "editor", perangkat lunak yang digunakan untuk mengetik. Contoh editor sederhana adalah notepad di Windows. Di Linux, sejak pertama kali menggunakannya secara intensif tahun 2009 sampai sekarang, editor bawaan dari Gnome, yakni gEdit, adalah editor default saya, selain vim. Dua hal utama yang saya gunakan dengan editor: (1) mengkoding Python, dan (2) membuat manuskrip dengan Latex. Hal-hal lainnya adalah menulis dengan markdown, txt, dan format-format lainnya. Jadi, editor yang saya gunakan paling tidak harus mendukung Python dan Latex, dan gEdit sudah mendukung keduanya dengan beberapa kekurangan (code completion, snippets, dll).

Setelah mencoba beberapa editor lain: Atom, Sublime text, Spyder, PyCharm, dan vscode, akhirnya saya memutuskan vscode sebagai editor saya untuk seterusnya. Tulisan ini mengupas kenapa saya berpindah dari gEdit ke vscode.


Saturday, March 28, 2020

New article every weekend?

Time is short, writing is hard, and papers are long.
-Write it Up, p. 3

Writing is hard, everyone agrees on this statement. But, what about statement "Everyone can write"? Most people will disagree with that statement. Yes, while all students in higher education (undergraduate and above) must submit their thesis to obtain their degree, not all of them being a writer after it. Writing is important in all aspects of life. It is a basic skill to survive in the modern era. Without it, someone will suffer to explain their idea, their thinking. Yes, writing is thinking (another thinking is speaking), As quoted by a page in a book below, writing is a way to communicate our thinking to others. The better we communicate our idea, our thinking, the easier it will be accepted by people.

Writing is thinking, from a book: The craft of research

Why Writing?

Wednesday, March 25, 2020

Apa bedanya training, validasi, development dan test set ?

Dalam sebuah seminar/konferensi ilmiah, saya bertanya kepada pemateri: Kenapa data yang dipakai untuk validasi dan test sama? Menurut beliau, istilah validasi dan test dalam machine learning sama. Menurut saya ini salah. Data validasi tidak boleh dipakai untuk test (karena tentu saja, hasilnya akan lebih bagus). Data validasi sama dengan data development, keduanya, validation dan development, merupakan istilah yang sama untuk "tuning model" dari hasil training.

Partisi data Training, Validasi, dan Test (sumber gambar: disini)

Merujuk pada StackOverflow:

Wednesday, February 26, 2020

Menghitung rataan dengan mengabaikan nilai nol di Python Numpy

Ada kalanya kita ingin menghitung nilai rata-rata dari suatu data, namun kita ingin mengabaikan (skip) jika
ada nilai 0 (atau kosong, atau NaN, Not a Number) dalam data tersebut. Screencast di bawah ini menjelaskan tentang hal tersebut.

Monday, February 17, 2020

多様性の尊重

みなさん、こんにちは。 私はバグスと申します。北陸先端科学技術大学院大学の留学生です。
今日は「多様性の尊重」についてお話ししたいと思います。 まず、多様性って何ですか? 
多様性というのは、性別、年齢、人種、障害の有無、性的嗜好、宗教などの違いを言います。
英語ではDiversityです。世界中に、多様性を持った人々が住んでいます。

今から人間の多様性について3つのポイントをお話ししたいと思います。
1つめは、多様性というのは、自然で必然的なことです。そして避けられないことです。
まず、言葉の多様性について考えてみましょう!
日本人は皆、同じ言葉を話しているように思いますが、方言というものがありますよね。
例えば北海道と沖縄の言葉は違います.
金沢で生まれて長い間住んでいる人は、金沢弁を話すと思います。
そして東京の人は東京弁で話します。あとは、関西弁、九州弁、東北弁とか・・・
石川県内容でも加賀と能登では違います。
私が石川県に来て、気がついた方言は、言葉の最後を長くのばしたり、“じ”を使うことです。
例えば「それで」を「それでぇ~」とか「けれども」を「けどぉ~」。
「すごいね」を「すごいじ~」・・・こんな感じです。

2つめは、人間の多様性は避けることができないので、どうすればみんなと上手くやって
いけるのでしょうか? 大切なことは、多様性を尊重することだと思います。
あらゆるバックグラウンドを持つ人々と協力しながらやっていくべきです。
すべての人々に尊厳と敬意をもって接するべきです。男性、女性の区別なく平等に接するべきです。
そして、いろいろな意見や考えを尊重し、自分の中にある偏見や行いを見つめ直す必要があります。

3つめは、なぜ、多様性ってあるのでしょうか? なぜ、1種類の人間だけではないのでしょうか?
例えば、全部、日本人だったらどうでしょうか? それじゃ、問題がありますよね。
そしてもし、すべての人が男性だったら、どうやって次の世代に続けていけるのでしょうか?
だから、男性と女性、年配と若者、日本人と外国人がいるのです。多様性があるから、
お互いを知り、学ぶことができるのだと思います。
みんなが違うから国が発展するのではないでしょうか?
一人一人の長所を生かさないと発展できません。多様性に学ぶべきことがたくさんあります。

最後に、なぜ、神様は私たちに多様性を与えたのでしょうか?
神様は私たちがお互いを知ることができるように多様性をつくり、そこから私たちは学び、
助け合うためだと思います。私たちは外見で判断されるのではなく、行動と心で判断されるべきなのです。
私はお互いの多様性を尊重しあって、皆が生き生きと気持ちよく生きていけたら、と思います。
以上です。本日はありがとうございました。


---
*) この書き込みは石川県でスピーチコンテストを用です。

Tuesday, January 14, 2020

Manuscript preparation workflow


Here is my manuscript preparation workflow:

1. Spellcheck
I use gEdit for my (latex) writing, it has built-in spellcheck (install via `sudo apt install aspell-en`, if
it doesn't appear like below).
gEdit spell check

2. Grammar check
For free, I use textidote. For the paid version, I used Grammarly (also available for free with limited capability). Read this link on how to use textidote (in Indonesian language, right click > translate to English if you use Google Chrome). Another tool is proselint.
https://bagustris.blogspot.com/2019/06/mengecek-grammar-dan-spellchek-bahasa.html

3. Common error detector

Thursday, January 09, 2020

Winter vacation: Kumamoto dan Saga-ken

Ishikawa-ken, penghujung tahun 2019

Senin adalah awal pekan, awal memulai pekerjaan. Namun tidak dengan senin itu. Senin itu adalah awal liburan. Bergegas dia meninggalkan apatonya, mengejar bis untuk ke stasiun. Bus shuttle berangkat jam 8:55, dan lima menit sebelum bis itu berangkat, dia sudah berada di dalamnya. Dari Nomi, kota tempat kampusnya berada, menuju Komatsu, stasiun dimana dia memulai perjalanan, ditempuh selama 30 menit dengan shuttle kampus tersebut. Hari ini adalah hari terakhir shutle beroperasi sebelum liburan tahun baru. Shuttle akan beroperasi lagi tanggal tiga Januari, tepat dimana dia pulang dari liburan. Untuk sekedar liburanpun dia mengatur jadwalnya sedemikan rupa sehingga transportasi dapat diperolehnya senyaman mungkin.

Jadwal shuttle selama winter 2019/2020

Di Komatsu, dia sampai jam 9:30. Masih ada waktu 45 menit sebelum kereta pertama tujuan Fukui berangkat. Dia pun membeli tiket juhacchi kippu (18kippu), tiket free-pass khusus kereta api JR yang berlaku selama lima hari, se-jepang, asalkan masih kereta JR, maksimal tipe kereta api ekspress, bukan tipe atasnya (limited express, shinkansen). Setelah mengantongi tiket, dia pun berkeliling, memperhatikan lalu lalang orang-orang di stasiun Komatsu. Banyak orang menjemput saudaranya, atau temannya. Tahun baru serasa lebaran di Indonesia.


Dari Komatsu dia mengambil kereta tujuan Fukui. Dari Fukui berpindah ke Tsuruga. Masing-masing sekitar satu jam. Dari Tsuruga dia bisa lebih lama di kereta, sekitar 2.5 jam, ganti kereta di Himeji menuju Aioi, ganti kereta di sana menuju Okayama, tujuan terakhirnya hari itu. Nahas, dia ketinggalan melewatkan kereta di Aioi. Akhirnya dia memutuskan untuk tetap di kereta sampai tujuan akhir, Banshu-Ako. Dari sana dia berpindah ke kereta menuju Okayama. Jadwal kedatangannya di Okayama mundur sejam dari yang diperkirakan. Seharusnya jam 17.02, kenyataanya dia sampai di Okayama jam 18.30

Rute dari Himeji ke Okayama via Banshu-Ako. Harusnya perjalanan bisa lebih singkat jika berhendi di Aioi, kemudian oper kereta tujuan Okayama.