Tuesday, December 27, 2022

Mengikuti Sekolah Mengemudi Di Jepang

Tulisan ini adalah catatan pengalaman saya mengikuti sekolah mengemudi di Jepang di awal tahun 2022.

Kenapa driving school?

Ada tiga jalur untuk mendapatkan SIM di Jepang, yakni:

1. Jalur Sekolah (自動車学校, jidousha gakko)

2. Jalur Konversi (外免切替, gaimen kirikae)

3. Jalur Umum (普通一種一般試験, futsu isshu ippan shiken)

Dari ketiga jalur di atas, kenapa saya memilih jalur driving school?

1. Saya belum pernah 'pegang' mobil secara formal dan tidak punya SIM A untuk dikonversi.

2. Meski saya bisa saja belajar sendiri kemudian lewat jalur formal, namun waktunya akan sangat lama (1-2 tahun) kalau pakai jalur umum. Waktu tempuh ini juga berlaku untuk mereka yang sudah bisa (bahkan pandai menyetir).

3. Jalur driving school adalah yang paling cepat meski paling mahal.

Oya, ada dua tipe driving school di Jepang: driving school yang punya lisensi untuk tes tulis 50 soal dan praktek, dan driving shool yang tidak punya lisensi tersebut. Saya memilih driving school tipe pertama.

Pendaftaran

Satu-satunya kelemahan jalur driving school adalah biaya pendaftaran yang mahal, yakni sekitar 336,000 yen. Namun, seperti telah saya sampaikan di atas, jalur ini adalah yang tercepat. Saya hanya butuh sekitar dua bulan dari hari pertama les nyetir sampai dengan mendapatkan SIM resmi (bukan SIM belajar atau kari menkyou). 

Untuk info kursus mengemudi yang saya ikuti adalah sebagai berikut.

Nama : Tsuchiura Driving School (Tsuchiura Jidouka Gakkou)

Web: https://tsuchikyo.menkira.jp/

Alamat: 

〒300-0843 茨城県土浦市中村南 4-1-20

TEL 029-841-0577

Tips saat mendaftar: Jika anda bisa bahasa Jepang sehari-hari, jangan bilang kalau tidak bisa bahasa Jepang. Cukup bilang 日本語は大丈夫です。

Gambar 1. Mobil yang digunakan untuk latihan (Toyota)


Alur  

Ada empat tahapan atau langkah untuk mendapatkan SIM untuk semua jalur di atas.

1. Tes Praktek I untuk Kari Menkyou

2. Tes Tulis 50 soal

3. Tes Praktek II

4. Tes Tulis 100 soal

Jika keempat langkah di atas lulus, maka SIM bisa didapatkan. Jika langkah 1-2 terpenuhi, maka SIM belajar (kari menkyou) bisa didapatkan. Jika ada satu saja langkah di atas yang gagal, maka SIM tidak bisa didapatkan. Untuk mengulang setiap langkah ada biaya tambahan, untuk semua jalur. Kasus saya gagal sekali pada tes 50 soal dan mengulang dan membayar biaya test tsb (1700 yen untuk sekali tes).

Kelas

Hari Pertama

Hari pertama ini bisa dibilang fullday. Jam pertama dimulai  jam 9:50 dan berakhir jam 17:50. Istirahat dua kali, jam 11:15-11:50 dan jam 12:50-13:30. Ada tiga kelas (学会, gakkai)sekaligus, yakni kelas 1, 6, dan 9. Oya, total ada 26 kelas yang dibagi menjadi dua periode (sebelum dan setelah kari menkyou/SIM belajar). Di kelas pertama tadi dikenalkan pengertian kendaran (車, kuruma) yang meliputi mobil (自動車), sepeda (自転車), dan sepeda motor (モトバイク). Poin-poin penting kelas 1 meliputi: seat belt, child seat, driving license, dan surat kelayakan kendaraan (車検). Poin-poin penting kelas 6 membahas banyak tentang perempatan (tata cara belok, berhenti, lurus). Kelas 9 lebih banyak membahas tentang pejalan kali, zebra cross, mengemudi di samping pejalan kali, sepeda, kursi roda dan sejenisnya.  Pada hari pertama ini ada dua (jam) praktek. Praktek pertama dengan simulator meliputi: persiapan sebelum mengemudi (cek depan dan belakang), menyetel kursi, menstarter mobil, memindahkan handle dari P, ke R, N, D, S, B (sambil menginjak rem), belok kanan dan belok kiri (tangan dalam keadaan lurus untuk putaran setir > 180 derajat). Praktek kedua adalah dengan mobil asli setelah melalui simulator.

Hari Kedua

Pada hari kedua ada dua kelas dan dua praktek. Kelas pertama adalah kelas 8 membahas tentang perempatan meliputi cara berpindah jalur, menyalip, dan belok kiri kanan. Praktek pertama di hari kedua ini (praktek ketiga secara total) adalah latihan belok (putaran) kanan, kebalikan dari hari pertama. Belok kanan dan kiri berbeda, putaran belok kanan lebih sedikit dari belok kiri. Kelas kedua yakni kelas 10 membahas tentang jenis-jenis SIM (ada tiga: kelas 1, kelas 2, SIM belajar), jenis-jenis SIM dari berat kendaraan dan pelanggaran lalu lintas beserta hukumannya. Setiap melanggar, selain tindakan langsung (tilang) berupa uang, pelanggar akan dikenakan poin. Jika poin tersebut sudah mencapai batas, SIM akan dicabut baik sementara atau permanen. Pada praktek kedua saya berlatih belok kanan dan kiri (sasetsu dan usasetsu). Praktek ini juga meliputi implementasi kelas 8 yakni cara berpindah jalur: lihat room mirror, side mirror, nyalakan sein, hitung tiga detik, tengok kanan, pindah jalur. Praktek kedua ini sangat penting untuk membiasakan menyetir.

Hari ketiga

Hari ketiga mirip dengan hari sebelumnya: dua kelas dan dua praktek. Kelas pertama dimulai dari buku "Rules of the Road" hal 114 berkaitan dengan menyalip, kapan dilarang menyalip, di mana dilarang menyalip dan sejenisnya. Contohnya larangan menyalip adalah ketika mobil di depan kita juga mau menyalip. Contoh tempat dilarang menyalip adalah tanjakan. Kelas kedua berkaitan dengan mobil-mobil emergensi: ambulans, pemadam kebakaran, dan polisi (untuk mengutamakan mobil tersebut). Praktek pertama naik tanjakan dan pindah lajur kanan (berhenti sejenak, rem tangan, gas pelan, lepas rem tangan, bel, reteng kanan, D-->S, turun sambil injak rem pelan-pelan, berhenti, S --> D. Praktek kedua di tikungan S dan J. Poin penting praktek kedua ini adalah injakan rem dan kapan memutar dan mengembalikan handle dengan melihat jalan.

Hari keempat

Skema hari keempat sama dengan hari sebelumnya, dua teori (kelas) dan dua praktek. Kelas pertama berkaitan lampu lalu lintas (merah, kuning, hijau dengan empasis kuning harus berhenti pada dasarnya, kecuali sudah melewati garis putih). Lamu lalu lintas di Jepang berbeda dengan Indonesia, meski hijau tidak serta merta jalan, menunggu mobil dari arah lawan, jika kosong baru bisa jalan. Kelas kedua berkaitan dengan rambu-rambu lalu lintas (secara garis besar dibagi dua, rambu di pinggir jalan dan rambu di permukaan jalan). Praktek pertama dan kedua sama, course seperti gambar di bawah. Bedanya, praktek pertama mbak instrukturnya gaul (pernah tinggal di Jakarta tujuh tahun), sedangkan praktek kedua mbak instrukturnya judes.

Hari keenam

Hari keenam hanya dua praktek. Dua-duanya sama, praktek kedua mengulang praktek pertama. Praktek ini adalah gladi resik untuk praktek I. Rutenya seperti gambar di bawah.

Gambar 2. Rute Latihan / Tes Praktek I


Tes Tulis 50 Soal (Hari ketujuh)

Hari ketujuh adalah test untuk step 1. Tes ini merupakan test praktek dengan course C sesuai gambar. Untuk mengambil tes ini harus lulus pre-test online 1, 2, dan 3. Masing-masing test online untuk step 1 berisi 50 soal benar atau salah. Untuk lulus harus memiliki skor (benar) minimal 45. Ada trik khusus untuk test online ini. Setelah test akan muncul review atas jawaban benar dan salah. Highlight semua pertanyaan dan jawaban kemudian print di browser dalam bentuk pdf. Ketika mengulang lagi, tinggal melihat jawaban yang benar. Meski pertanyaannya acak, ada banyak pertanyaan yang sama untuk tiap pre-test tersebut sehingga file pdf sebelumnya sangat membantu untuk mencari jawaban yang benar. Dari test praktek saya mendapat masukan untuk menginjak rem lebih halus dan tidak mendadak. Setelah test praktek adalah test tulis. Meski saya sudah lulus tiga pre-test online di test tulis ini saya tidak lulus. Saya gagal di tes pertama 50 soal untuk mendapatkan kari menkyou. Walhasil saya harus mengulang dan membayar pendaftaran 1700 yen. Jadwal short-term plan saya juga langsung berubah menjadi basic plan.


Hari ke delapan dan seterusnya lupa tidak tercatat, tapi catatan berikut di bawah ini cukup bermanfaat.


Tes Praktek I

Tes praktek I ini secara umum mudah karena hanya di lintasan di dalam driving school (tidak keluar ke jalan raya). Beberapa hal yang perlu diperhatikan adalah saat sebelum mengemudi (cek spion tengah, side mirror) kemudian toleh kanan kiri dan start. Minimal kecepatan pada jalan lurus adalah 40 km,/jam sekali saja. Kecepatan pada saat belok maksimal 15 km/jam. Belokan S juga diujikan pada tes praktek I ini.

Mikiwame

Mikiwame adalah semacam gladi resik untuk tes praktek (II). Jadi materinya hampir sama dengan test praktek II. Pada mikiwame ini saya mengendarai mobil di rute yang akan dijadikan test, termasuk juga mengendarai mobil di arena di dalam driving school. Beberapa teknik yang di-teskan antara lain houkohenkan (putar balik) dan parkir. Pada hari tes, dua dari teknik tersebut akan dipilih salah satu secara acak.

Tes Praktek II

Meski berhasil pada tes praktek II ini, ada banyak pelajaran yang bisa di ambil. Utamanya adalah untuk "mendahulukan yang mudah daripada yang sulit" (無理しないでください). Kasus pertama pelajaran tersebut ketika berada di perempatan untuk belok kanan. Di Jepang, belok kanan tidak bisa langsung meski lampunya hijau, jadi mobil harus maju pelan-pelan sampai di tengah perempatan menunggu mobil dari arah kiri kosong (atau panah kanan hijau menyala pada lampu lalu lintas). Karena mobil di depan saya maju, saya juga ikut maju di belakangnya. Di akhir test, instruktur mengatakan bahwa saya terlalu mempersulit diri. Baiknya, menunggu di belakang zebra cross, tidak perlu mengikuti mobil di depan ke tengah perempatan. Kasus kedua ketika putar balik (Gambar 2, bagian kiri atas), saya beberapa kali maju dan mundur untuk mengatur agar mobil pas di tengah (seperti parkir). Di akhir instruktur mengatakan, karena bukan parkir, kamu gak perlu bersusah payah mengatur mobil, intinya mobil bisa putar balik (mundur, belok kiri, dan belok kanan). Alhamdulillah meski agak susah saya lulus di tes praktek II ini.

Tes Tulis 100 soal di Mito: 

LULUS!

Ini adalah tes terakhir, bukan di driving school tapi di menkyou senta (Mito-shi). Alhamdulillah saya langsung lulus di tes pertama ini. Tipsnya banyak-banyak buku "Master of your driving in Japan" saja. Penantian kelulusan ini mirip-mirip ujian, menunggu nomor kita ada di layar monitor (lulus) atau tidak. Alhamdulillah nomor saya muncul di layar, langsung dapat SIM hari itu juga (setelah tes mata dan mengikuti arahan-arahan lainnya). Qodarullah, sehari setelah dapat SIM saya langsung dapat mobil. Alhamdulillah.

Gambar 3. Nomor ujian saya, 162, muncul di layar menandakan kelulusan ujian SIM di Jepang


P.S: Jika anda ingin mengikuti driving school di Tsuchiura Driving School, anda bisa memasukkan nama saya dan alamat saya  untuk mendapatkan potongan biaya 7000 yen (referral). Silahkan email saya di (btatmaja[at]gmail[dot]com) untuk mendapatkan alamat saya.

Friday, November 25, 2022

Konversi Fail Stereo ke Mono Dari Direktori Berisi Banyak Fail Suara

Skrip berikut dapat merubah fail suara stereo ke mono dari suatu direktori (termasuk subdirektori di dalamnya) yang diberikan.
Input: Direktori/folder
Output: Fail berakhiran "_mono" dengan direktori yang sama terhadap input (termasuk subdirektori)
#!/usr/bin/env python3
import os
import argparse
import glob
from pydub import AudioSegment

def stereo2mono(files):
    """Convert all files from stereo to mono.
    Note: this would effectively also create a copy of files that were already in a mono format
    Parameters
    ----------
    files : iterable
        Sequence of files
    Example use:
    ```
    $ python3 stereo2mono.py -f /path/to/audio/files/
    ```
    Then you may remove the files that do not contain the '_mono' tag with: 
    $ find . -name "*-??.wav" -delete # for emovo
    """
    for f in files:
        print(f"Converting {f}")
        # Load audio
        sound = AudioSegment.from_wav(f)
        # Convert to mono
        sound = sound.set_channels(1)
        # Save file
        stem, ext = os.path.splitext(f)
        sound.export(f'{stem}_mono{ext}', format='wav')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Convert stereo to mono')
    parser.add_argument('-f', '--folder', 
        type=str, help='Path to wavfiles')
    args = parser.parse_args()
    files = glob.glob(args.folder + '**/*.wav', recursive=True)
    stereo2mono(files)
Contoh penggunaan
# Konversi ke mono
python3 stereo2mono.py -f tensorflow_datasets/downloads/extracted/ZIP.emovo.zip/EMOVO/
# menghapus file yang bukan mono
$ pwd
/home/bagus/tensorflow_datasets/downloads/extracted/ZIP.emovo.zip/EMOVO/
$ find . -name "*-??.wav" -delete
Referensi gist:
1. https://gist.github.com/bagustris/40b406d99820207bc804a020db169f7e

Friday, September 09, 2022

Installing TexLive 2022 on Ubuntu 22.04 under Multipass

Multipass is a game changer. It looks like a virtual environment for python or a virtual box for OS, but for Ubuntu instances only (the hosts can be Windows and MacOS). This short writing documented my effort to enable the installation of TexLive 2022 for adding IEEE header and footer for camera-ready APSIPA 2022.

Host environment

bagus@L140MU:~$ snap --version
snap    2.56.2
snapd   2.56.2
series  16
ubuntu  20.04
kernel  5.15.0-46-generic
bagus@L140MU:~$ multipass --version
multipass   1.10.1
multipassd  1.10.1

Steps

1. Install multipass (refer to this link for detail).
2. Create an instance with Jammy (Ubuntu 22.04)
multipass launch jammy --disk 10G 
Launched: famed-chaffinch

2. Login to Jammy's shell (change the name of instance)
 multipass shell famed-chaffinch
3. Update Jammy
 sudo apt update
4. Install texlive and required packages
sudo apt install texlive-base texlive-fonts-extra texlive-fonts-recommended texlive-publisher
5. Try on the desired latex template
$ wget https://www.apsipa2022.org/APSIPA_ASC_2022_Template.zip
$ sudo apt install unzip
$ unzip APSIPA_ASC_2022_Template.zip
$ cd APSIPA_ASC_2022_Template/Latex
$ pdflatex PaperSample_Guideline_tex.tex
...
Output written on PaperSample_Guideline_tex.pdf (3 pages, 126525 bytes).
Transcript written on PaperSample_Guideline_tex.log.
That's all. For 20.04, it will throw to an infinite recursion loop due to the lower fancy version. The only solution is to install newer Latex on Ubuntu 22.04 under multipass. For real cases, you may need to mount your local directory (which contains TEX files) to an instance with `multipass mount`.
$ multipass mount $HOME famed-chaffinch

Tuesday, August 23, 2022

Acoustic Feature Extraction with Transformers

The example in Transformers' documentation here shows how to use the wav2vec 2.0 model for automatic speech recognition. However, there are two crucial issues in that example. First, we usually use our data (set) instead of their (available) dataset. Second, we need to extract acoustic features (the last hidden states instead of logits). The following is my example of adapting Transformers to extract acoustic embedding given any audio file (WAVE) using several models. It includes the pooling average from frame-based processing to utterance-based processing for given any audio file. You don't need to perform the pooling average if you want to process your audio file in frame-based processing (remove the `.mean(axis=0)` in the variable `last_hidden_states`).

Basic syntax: wav2vec2 base model

This is the example from the documentation. I replaced the use of the dataset with the defined path of the audio file ('00001.wav').

from transformers import Wav2Vec2Processor, Wav2Vec2Model
import torchaudio
import torch
# load model
processor = Wav2Vec2Processor.from_pretrained("facebook/wav2vec2-base-960h")
model = Wav2Vec2Model.from_pretrained("facebook/wav2vec2-base-960h")

# audio file is decoded on the fly
array, fs = torchaudio.load("/data/A-VB/audio/wav/00001.wav")
input = processor(array.squeeze(), sampling_rate=fs, return_tensors="pt")

# apply the model to the input array from wav
with torch.no_grad():
    outputs = model(**input)

# extract last hidden state, compute average, convert to numpy
last_hidden_states = outputs.last_hidden_state.squeeze().mean(axis=0).numpy()

# print shape
print(f"Hidden state shape: {last_hidden_states.shape}")
# Hidden state shape: (768,)


The syntax for the wav2vec2 large and robust model

In this second example, I replace the base model with the large and robust model without finetuning. This example is adapted from here. Note that I replaced 'Wav2Vec2ForCTC' with 'wav2vec2Model'. The former is used when we want to obtain the logits (for speech-to-text transcription) instead of obtaining the hidden states.

from transformers import Wav2Vec2Processor, Wav2Vec2Model
import torch
import torchaudio

# load model
processor = Wav2Vec2Processor.from_pretrained(
    "facebook/wav2vec2-large-robust-ft-swbd-300h")
model = Wav2Vec2Model.from_pretrained(
    "facebook/wav2vec2-large-robust-ft-swbd-300h")

# audio file is decoded on the fly
array, fs = torchaudio.load("/data/A-VB/audio/wav/00001.wav")
input = processor(array.squeeze(), sampling_rate=fs, return_tensors="pt")

with torch.no_grad():
    outputs = model(**input)

last_hidden_states = outputs.last_hidden_state.squeeze().mean(axis=0).numpy()
# printh shape
print(f"Hidden state shape: {last_hidden_states.shape}")
You can replace "facebook/wav2vec2-large-robust-ft-swbd-300h" with "facebook/wav2vec2-large-robust-ft-libri-960h" for the larger fine-tuned model.

 For other models, you may need to change `Wav2Vec2Processor` with `Wav2Vec2FeatureExtractor` for processor variable. In my case, this is needed for the following models:
  • facebook/wav2vec2-large-robust
  • facebook/wav2vec2-large-xlsr-53

The syntax for the custom model (wav2vec-R-emo-vad)

The last one is the example of the custom model. The model is wav2vec 2.0 fine-tuned on the MSP-Podcast dataset for speech emotion recognition. This last example differs from the previous one since the configuration is given by the authors of the model (read the code thoroughly to inspect the details). I replaced the dummy audio file with the real audio file. It is assumed to process in batch (with batch_size=2) by replicating the same audio file.

import torch
import torch.nn as nn
from transformers import Wav2Vec2Processor
from transformers.models.wav2vec2.modeling_wav2vec2 import (
    Wav2Vec2Model,
    Wav2Vec2PreTrainedModel,
)
import torchaudio


class RegressionHead(nn.Module):
    r"""Classification head."""

    def __init__(self, config):

        super().__init__()

        self.dense = nn.Linear(config.hidden_size, config.hidden_size)
        self.dropout = nn.Dropout(config.final_dropout)
        self.out_proj = nn.Linear(config.hidden_size, config.num_labels)

    def forward(self, features, **kwargs):

        x = features
        x = self.dropout(x)
        x = self.dense(x)
        x = torch.tanh(x)
        x = self.dropout(x)
        x = self.out_proj(x)

        return x


class EmotionModel(Wav2Vec2PreTrainedModel):
    r"""Speech emotion classifier."""

    def __init__(self, config):

        super().__init__(config)

        self.config = config
        self.wav2vec2 = Wav2Vec2Model(config)
        self.classifier = RegressionHead(config)
        self.init_weights()

    def forward(
            self,
            input_values,
    ):

        outputs = self.wav2vec2(input_values)
        hidden_states = outputs[0]
        hidden_states = torch.mean(hidden_states, dim=1)
        logits = self.classifier(hidden_states)

        return hidden_states, logits


def process_func(
    wavs,
    sampling_rate: int
    # embeddings: bool = False,
):
    r"""Predict emotions or extract embeddings from raw audio signal."""

    # run through processor to normalize signal
    # always returns a batch, so we just get the first entry
    # then we put it on the device
    # wavs = pad_sequence(wavs, batch_first=True)
    # load model from hub
    device = 'cpu'
    model_name = 'audeering/wav2vec2-large-robust-12-ft-emotion-msp-dim'
    processor = Wav2Vec2Processor.from_pretrained(model_name)
    model = EmotionModel.from_pretrained(model_name)

    y = processor([wav.cpu().numpy() for wav in wavs],          
                   sampling_rate=sampling_rate,
                   return_tensors="pt",
                   padding="longest"
        )
    y = y['input_values']
    y = y.to(device)


    y = model(y)

    return {
        'hidden_states': y[0],
        'logits': y[1],
    }


## test to an audiofile
sampling_rate = 16000
signal = [torchaudio.load('train_001.wav')[0].squeeze().to('cpu') for _ in range(2)]

# extract hidden states
with torch.no_grad():
    hs = process_func(signal, sampling_rate)['hidden_states']
print(f"Hidden states shape={hs.shape}")

Please note for all models, the audio file must be sampled with 16000 Hz, otherwise, you must resample it before extracting acoustic embedding using the methods above. It may not throw an error even if the sampling rate is not 16000 Hz but the results, hence, is not valid since all models were generated based on 16 kHz of sampling rate speech datasets. 

You may also want to extract acoustic features using the opensmile toolkit. The tutorial for Windows users using WSL is available here: http://bagustris.blogspot.com/2021/08/extracting-emobase-feature-using-python.html.

Happy reading. Don't wait for more time to apply these methods to your own audio file.

Wednesday, August 17, 2022

Siapa yang seharusnya membersihkan sampah B?

Andaikan sebuah eksperimen pikiran sebagai berikut.

A mengadakan suatu acara (panitia acara). B mengikuti acara tersebut (peserta acara). Jika B membuang sampah secara sembarangan di saat mengikuti acara tersebut, siapa yang wajib membersihkannya?

Jika anda masih menjawab A. Kita tambahkan kasus lain seperti ini.

B berada di rumahnya sendiri. B membuang sampah secara sembarangan di rumahnya sendiri. Siapa yang seharusnya membersihkan sampah B?

B yang seharusnya membuang sampahnya sendiri, tak peduli dimanapun. Selama itu sampahnya, maka dia sendiri yang wajib membuangnya, bukan orang lain.

Monday, August 01, 2022

Maksimal jumlah referensi self-citation

Best practice jumlah self-citation pada makalah akademik adalah 10% dari total jumlah referensi. Sumber lain membolehkan 7-20%  [1]. Untuk saya pribadi, jumlah maksimalnya adalah berdasarkan tabel dan rumus di bawah ini.

Number of references Max. self-citation
1-10 1
11-20 2
21-30 3
... ...
91-100 10

Contoh, jumlah referensi: 24, maksimal self-citation: 3.


Rumus

$$ n\_cite=10\% \times ceil(n\_ref/10) \times 10 $$

Dimana n_cite adalah jumlah maksimal self-citation and n_ref adalah jumlah referensi.


Kenapa self-citation?

Karena biasanya kita meneliti dan menulis makalah akademik tidak dari nol, tapi dari penelitian-penelitian kita sebelumnya. Disinilah self-citation masuk.

Alasan kedua adalah untuk mendongkrak h-indeks (Scopus, G-scholar, WOS) peneliti yang bersangkutan.


Referensi: 

[1] https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3049640/#:~:text=Self%2Dcitation%20ranges%20from%207,with%20many%20authors%20%5B13%5D.

Tuesday, July 05, 2022

Teknik Mendaki di Jalan Datar: Flat Foot

Catatan berikut merupakan teknik mendaki di jalan datar. Memangnya ada tekniknya untuk berjalan di jalan yang datar? Ada. Pada perjalanan panjang, menggunakan teknik berikut akan meminimalisir tenaga yang dikeluarkan, sekaligus meminimalkan kecapekan. Dua teknik yang penting adalah postur dan cara berjalan (ayunan kaki).

Postur

Bentuk postur berikut harus digunakan pada jalanan datar.

  1. Tegak/lurus. Berbeda dengan jalan naik yang mencondongkan badan ke depan atau teknik turun seperti gorilla, pada jalan posisi tubuh adalah tegak lurus.
  2. Menegakkan kepala. Kadang kita lupa untuk menegakkan kepala dengan menunduk melihat jalan, atau mendongak melihat pemandangan. Teknik utama pada jalan datar adalah menegakkan kepala.

Teknik Berjalan

  1. Flat foot / mendatarkan kaki. Ini adalah teknik utama berjalan di jalan datar. Sesuai namanya, flat foot mengayunkan lagi sedatar mungkin saat mengangkatnya dan menjejakkan ke tanah. Kalau berjalan normal, kita mengangkat kaki dengan pangkal kaki atau tumit (tumit menyentuh tanah terakhid) dan menjejak dengan jari kaki. Pada flat foot baik mengangkat dan menginjak dengan kaki yang datar. Lihat gambar di bawah untuk lebih jelasnya.
  2. Teknik mengangkat kaki dengan flat foot [1]

    Teknik menjejak kaki dengan flat foot [2]

  3. Mengangkat kaki serendah mungkin. Teknik terakhir adalah mengangkat kaki serendah mungkin, agar tidak capek (lebih tinggi mengangkat kaki lebih banyak tenaga yang dibutuhkan).

Lihat video tutorial berikut untuk prakteknya.

Referensi:

  1. https://sp.yamap.com/cw-x/

Friday, June 24, 2022

Membuka dan menyimpan file json

MENYIMPAN file JSON
Studi kasus
Misalkan kita ingin menyimpan dataset berikut (RAVDESS Speech) dalam format json yang berisi file dan labelnya (data speech emotion recognition). Untuk keperluan tersebut kita ingin memisahkan antara data training ('train_meta_data.json') dan data test ('test_meta_data.json'). Skrip berikut memenuhi tujuan tersebut.
import os
import glob
import json

data_dir = '/data/Audio_Speech_Actors_01-24/'
files = glob.glob(os.path.join(data_dir, 'Actor_??', '*.wav'))
files.sort()

data_train = []
data_test = []

for file in files:
    lab = os.path.basename(file).split('-')[2]
    if int(file[-6:-4]) < 20: # speaker 1-19 for training
        data_train.append({
            'path': file,
            'label': lab
        })
    else:                     # speaker 20-24 for test
        data_test.append({
            'path': file,
            'label': lab
        })

with open("train_meta_data.json", 'w') as f:
        json.dump(data_train, f)

with open("test_meta_data.json", 'w') as f:
        json.dump(data_test, f)

MEMBUKA file JSON
import json
filepath = '/data/Audio_Speech_Actors_01-24/train_meta_data.json'
with open(filepath, 'r') as f:
     data_train = json.load(f)

Tuesday, May 10, 2022

Benchmarking SSD: INTEL SSDPEKNW020T8 (NVMe)

Berikut adalah hasil benchmarking SSD INTEL SSDPEKNW020T8 tipe NVMe. 

Name: INTEL SSDPEKNW020T8 
Capacity: 2TB 
Link: 
Format partisi: FAT 

Spec 



Hasil

Catatan: 
- Format yang dibenchmark kali ini adalah FAT, bisa jadi untuk ext4 dan xfs akan lebih cepat.
- SSD NVMe intel ini terlihat lebih stabil dibanding WDC, dengan kecepatan baca/tulis yang mirip. Lihat disini untuk hasil benchmark dengan SSD NVMe WDC: https://bagustris.blogspot.com/2017/01/mengganti-hdd-dengan-ssd-cd-rom-dengan.html#more

Tuesday, April 26, 2022

Writing for impact, not for impact factor

Nowadays, research is measured by publication. Publish or perish. The pressure for researchers to publish is now more than ever. As a result, there are tons of research publications. Most of them may be garbage; only a small portion has an impact. So, what is the impact in research?

Impact factor

At first, I thought that "writing for impact is writing for impact factor" (since "impact" is measured by "impact factor"). By this definition, the author will seek for writing to the Journal which has high impact factors due "impact" is defined by the calculation of impact factor. In fact the (impact factor calculation is based on citations and the number of publications)[https://en.wikipedia.org/wiki/Impact_factor]. Hence, writing for impact factor is no more than writing for citations. I changed my mind recently, writing for impact is not writing for impact factor. The impact is different with (calculation of) impact factor. Now, some journals and conferences requested this "social impact" as an additional section in the author's manuscript [1, 2]. It is good. By this method (requesting to show the impact of their research), the impact of research now is clearer than before.

Kinds of social impact

Now, when asked to write the social impact of my writing, I am thinking of what social impact will be in my manuscript. Reference [1] requested explicitly what is the definition of "positive impact" for authors. A positive impact could be one of the following (my own definition).

1. Readers change their perspective. For instance, the paper entitled "Toward a consensus on symbolic notation of harmonics, resonances, and formants in vocalization" proposed a new standard notation for fundamental frequency (in acoustics), i.e., by writing it as $f_o$ (ef-ow) instead of F0, $F_0$ or $f_0$ (ef-zero). This paper has a big social impact on the (acoustic) community.

2. Readers can learn. Many papers show their method clearly so the readers can learn and get the benefit from reading the paper. An instance is a paper entitled "CALFEM as a Tool for Teaching University Mechanics."

3. Readers can replicate. Open science is making a difference. Anyone can replicate the experiment of the authors. This kind of research is game-changing. Even big companies like Google, Microsoft, and Meta open their research publicly along with open repositories to replicate the research. Most of my research is also open science, one example is a paper entitled "Deep Multilayer Perceptrons for Dimensional Speech Emotion Recognition".

4. Readers can improve the result. One way to improve the current result is by explicitly proposing further directions. This statement usually is placed in the Conclusions or before this section.

5. A policy can be taken. This is the highest impact, a policy can be taken from a research result. For instance, to fight global warming (based on specific data), the government changes the policy to abandon the use of coal and move to nuclear energy. Or, based on the risk of nuclear energy, the government encourages the use of wind and solar energy.


Hope this opinion will change your minds; do not write for impact factor (only), but do write for real (social) impact.


Reference:

[1] https://s4sg-workshop.github.io/

[2] https://acii-conf.net/2022/authors/submission-guidelines/

Friday, April 22, 2022

Basic Audio Manipulation With Torchaudio

Recently, I moved my audio processing toolkit from librosa (and others) to Torchaudio. This short writing documented the very basics of torchaudio for audio manipulation: read, resample, and write an audiofile.

Load audio file (read)

The process of loading (reading) an audio file is straightforward, just pass the audio path to `torchaudio.load`. We need to import the needed modules first. Most audio files can be loaded by torchaudio (WAV, OGG, MP3, etc.).
import torchaudio
import torchaudio.transforms as T
wav0, sr0 = torchaudio.load("old_file_48k.wav", normalize=True) 
where wav0 is the output tensor (array) and sr0 is the original sampling rate. Argument `normalize=True` is optional to normalize the waveform. Note that one of my colleagues (a student) found that using `librosa.util.normalize()` resulted in better normalization (peak to peak waveform is -1 to 1) than this torchaudio normalization.
 

Resample

Resample a sampling rate to another sampling rate is done by a Class; the output is a function. Hence, we need to pass the old tensor to the resampler function. Here is an example to convert 48k tensor to 16k tensor.
sr1 = 16000
resampler = T.Resample(sr0, sr1)
wav1 = resampler(wav0)

Save as a new audio file (write)


The process of saving files is also straightforward, just pass the file name, tensor, and sampling rate in order.
torchaudio.save('new_file_16k.wav', wav1, sr1)
Then the new audio file appeared in the current directory. Just set the path and file name if you want to save it in another directory.
 

Reference:

[1] https://pytorch.org/tutorials/beginner/audio_preprocessing_tutorial.html

Tuesday, April 19, 2022

Tiga Tipe Ilmuwan..

Berdasarkan dialog Peter Gruss (rektor OIST) dan Kazuhiko Nakamura (CEO AIST) [1], yang pertama menjelaskan tentang tiga golongan ilmuwan sebagai berikut.

  1. Ilmuwan murni (pure scientist) seperti Albert Einstein
  2. Ilmuwan murni ini hanya memikirkan dan meriset apa yang dipikirkannya, tanpa memikirkan dampak luasnya (impak jangka panjang). Einstein pada saat meneliti teori relativitas tidak terpikirkan tentang teknologi global positioning system (GPS), padahal konsep relativitas tersebut penting untuk penemuan GPS lima puluh tahun setelah teori relativitas terbit.
  3. Ilmuwan aplikatif (use-inspired scientist) seperti Pasteur
  4. Yang dipikirkan oleh ilmuwan jenis ini adalah "Apa yang bisa saya lakukan untuk meningkatkan aspek tertentu kehidupan manusia?". Basisnya adalah ilmu, tujuannya mencari aplikasi dari ilmu tersebut. Contohnya adalah penelitian untuk mengembangkan teknik diagnostik baru, terapi, obat baru, seperti yang dilakukan Pasteur untuk menemukan antibiotik.
  5. Insinyur (engineer) seperti Thomas Alfa Edison
  6. Ilmuwan jenis ini hanya berkutat sedikit pada sains, yang penting bagaimana aplikasinya. Edison hanya fokus pada bagaimana cara menemukan bola lampu entah bagaimana caranya/ilmunya.
Jika anda ilmuwan (atau ingin menjadi ilmuwan), tipe ilmuwan manakah yang anda inginkan? Saya lebih tertarik pada tipe ketiga karena kontribusinya (impak sosial) lebih nyata.

 

Referensi:

[1] https://www.youtube.com/watch?v=bGA9p3x4qx0

Thursday, April 14, 2022

Menemukan dan Menghapus file (ekstensi tertentu, ukuran tertentu)

Menemukan fail

Pola: find [nama-direktori] -name [nama-file]

Contoh

pc060066:~$ find . -name tes.txt
./tes.txt

Tanda titik setelah find menunjukkan current directory (dalam hal ini /home/$USER).

Menemukan dan menghapus fail

Pola: find [nama-direktori] -name [nama-file-yang-dihapus] -delete

Contoh

pc060066:~$ cp tes.txt tes-del.txt
pc060066:~$ find . -name tes-del.txt
./tes-del.txt
pc060066:~$ find . -name tes-del.txt -delete
pc060066:~$ find . -name tes-del.txt
Terlihat file yang dihapus (tes-del.txt) tidak ada setelah perintah di atas.


Menemukan dan menghapus fail ekstensi tertentu

Pola: find [nama-direktori] -name ['*.ext'] -delete

pc060066:~$ mkdir test
pc060066:~$ cd test
pc060066:test$ ls
pc060066:test$ touch test{1..5}.txt
pc060066:test$ ls
test1.txt  test2.txt  test3.txt  test4.txt  test5.txt
pc060066:test$ touch readme.md
pc060066:test$ ls
readme.md  test1.txt  test2.txt  test3.txt  test4.txt  test5.txt
pc060066:test$ find . -name '*.txt'
./test1.txt
./test3.txt
./test2.txt
./test5.txt
./test4.txt
pc060066:test$ find . -name '*.txt' -delete
pc060066:test$ ls *.txt
ls: cannot access '*.txt': No such file or directory
Jangan lupa single quote diantara ekstensi ('*.txt'); untuk ekstensi lainnya tanda quote ini tidak perlu. Contohnya *.wav. Kita juga bisa mencari (dan menghapus) file ekstensi tertentu dengan nama tertentu. Contohnya menemukan (dan menghapus) file dengan nama berakhiran *_cd16k.wav.


Menemukan dan menghapus fail ukuran tertentu

Pola: find [nama-direktori] -name [nama-file-opsional] -size [ukuran, -, +] -delete

Contoh:
pc060066:test$ find . -size 4c
./test8.txt
pc060066:test$ find . -size 4c -delete
pc060066:test$ ls
1001_DFA_ANG_XX.wav  test1.txt  test3.txt  test5.txt  test7.txt
readme.md            test2.txt  test4.txt  test6.txt
pc060066:test$ find . -size -10c # find below 10 bytes
./test6.txt
./test1.txt
./test3.txt
./readme.md
./test2.txt
./test5.txt
./test4.txt
pc060066:test$ find . -size -10c -delete # delete below 10 bytes
pc060066:test$ ls
1001_DFA_ANG_XX.wav  test7.txt
pc060066:test$ find . -size +10c -delete # delete above 10 bytes
pc060066:test$ ls
Jadi tanda "-" untuk kurang dari dan "+" untuk lebih dari ukuran file yang dikehendaki. Tidak ada tanda maka hasilnya pada rentang nilai tersebut. Misal 10c untuk 10 bytes, 10k untuk 10 kilobytes, termasuk 10001 bytes sampai dengan 10999 bytes. 

Menghapus file kosong

Pola: find [nama-direktori] -empy -delete
Contoh:
pc060066:test$ find . -empty
./test10.txt
./test6.txt
./test1.txt
./test3.txt
./test2.txt
./test8.txt
./test5.txt
./test9.txt
./test4.txt
./test7.txt
pc060066:test$ find . -empty -delete
pc060066:test$ ls

Menghapus direktori kosong

Pola: find [nama-direktori] -d -empty -delete 

Contoh:
pc060066:test$ ls -ltr
total 20
drwxrwxr-x 2 bagus bagus 4096  4月 14 15:33 test_dir_5
drwxrwxr-x 2 bagus bagus 4096  4月 14 15:33 test_dir_4
drwxrwxr-x 2 bagus bagus 4096  4月 14 15:33 test_dir_3
drwxrwxr-x 2 bagus bagus 4096  4月 14 15:33 test_dir_2
drwxrwxr-x 2 bagus bagus 4096  4月 14 15:33 test_dir_1
pc060066:test$ find . -type d
.
./test_dir_5
./test_dir_4
./test_dir_2
./test_dir_1
./test_dir_3
pc060066:test$ find . -type d -empty
./test_dir_5
./test_dir_4
./test_dir_2
./test_dir_1
./test_dir_3
pc060066:test$ find . -type d -empty -delete
pc060066:test$ ls
Bedakan dengan perintah sebelumnya untuk file, untuk direktori kita perlu argumen "-type d".

Menemukan dan menghapus kecuali


Pola: find [nama-direktori] not -name [kecuali] -delete

Contoh:
find . not -name "*_mono.wav" -delete
Argumen "not" bisa diganti dengan tanda seru "!" agar lebih singkat. Untuk folder yangt tidak kosong (directory is not empty), kita perlu menggunakan "rm -fr" sebagai pengganti argumen "-delete".
find . -mindepth 1 ! -name "kecuali-direktori1" ! -name "*.py" ! -name "KECUALI.md" ! -name "kecuali-direktori2" -exec rm -rf {} +

Monday, April 11, 2022

Menuju Masyarakat 5.0 melalui riset dan pengembangan teknologi informasi

Setelah era revolusi industri (society 3.0) dan teknologi informasi (society 4.0) zaman kini menuju Masyarakat 5.0 (society 5.0). Apa itu Masyarakat 5.0? Tulisan ini menjelaskan secara singkat Masyarakat 5.0 dan beberapa contoh di dalamnya.

Masyarakat 5.0

Masyarakat 5.0 adalah kelanjutan masyarakat 4.0 dan sebelumnya. Untuk lebih jelasnya tentang pembagian masyarakat 1.0 - 4.0 silahkan lihat gambar di bawah ini. Era pertama masyarakat 1.0 merupakan masyarakat pemburu (mungkin masih ada sampai saat ini!). Mereka hidup berkumpul dan berburu. Masyarakat 2.0 adalah masyarakat agraria. Mereka bercocok tanam untuk memenuhi hidupnya. Masyarakat 3.0 menggunakan mesin (uap) untuk memperbaiki kehidupan sebelumnya dan mempercepat proses untuk kehidupan: proses pembangunan, pembuatan makanan, dan transportasi. Masyarakat 4.0 menggunakan teknologi informasi untuk memperbaiki kehidupan sebelumnya. Berkirim surat secara online (email), bertransaksi secara online dan beberapa hal lainnya. Di era 4.0 hampir semua hal sudah bisa dilakukan secara online, namun ada gap besar di dalam prosesnya. Belum ada sensor yang mengambil data secara terstruktur, belum ada data yang distandarkan secara global dan berukuran besar, belum ada pengolahan yang full otomatis. Tantangan itulah yang akan dijawab oleh masyarakat 5.0.


Gambar 1. Masyarakat 1.0 sampai dengan 4.0 [1]

Masyarakat 5.0, seperti terlihat pada Gambar 2, memanfaatkan keberlimpahan big data, yang ditangkap oleh Internet of Thing (IoT) yang tersambung ke banyak sensor. Big data ini menjadi input untuk artificial intelligence (AI) yang bertindak sebagai classifier untuk menghasilkan output berupa pengetahuan yang memudahkan hidup dan menjadi solusi dari permasalahan masyarakat. Contoh sederhana, ketika ada masyarakat yang sakit dia tidak perlu langsung ke rumah sakit. Cukup menggunakan smartphone atau PCnya, yang memiliki beberapa sensor kesehatan, untuk meminta diagnosa ke AI dan divalidasi oleh dokter di rumah sakit (Gambar 3). Teknologi informasi digunakan secara besar pada Masyarakat 5.0 untuk memudahkan hidup.
Gambar 2. Masyarakat 5.0 yang berorientasi pada kehidupan manusia yang lebih baik [1]
 

Beberapa contoh lainnya 

Gambar 4. Masyarakat medis 5.0 [1]


Gambar 3 mengilustrasikan contoh pada paragraf sebelumnya tentang Masyarakat 5.0 untuk diagnosa penyakit. Lebih lanjut lagi, di Gambar 4, jika dirasa kesehatan pasien memerlukan tindakan langsung oleh dokter, maka pasien tersebut bisa pergi ke rumah sakit (RS) dengan autonomous vehicle yang disediakan oleh RS. Teknologi autonomous (self-driving) vehicle ini akan menggantikan transportasi umum. Dengan otomasi transportasi umum, maka tingkat kecelakaan akan bisa ditekan seminimal mungkin. Kurir akan digantikan oleh drone. Pesawat, kereta api, bis dan transportasi lainnya akan lebih aman dan nyaman dengan kehadiran teknologi otomasi ini. 

Gambar 5. Autonomous vehicle Masyarakat 5.0 [1]


Di sisi lain, pemanfaatan teknologi informasi dan teknologi pada bidang perawatan (maintenance), seperti ditunjukkan oleh Gambar 5, akan memudahkan masyarakat. Tidak perlu lagi ada campur "tangan" (dalam arti benar-benar tangan) manusia untuk mengecek langsung, mengarahkan kendaraan, menginspeksi jembatan dan gedung-gedung tinggi, teroworongan dan sebagainya. Inspektor cukup memantau "kesehatan" infrastruktur tersebut melalui smartphone, PC, dan sejenisnya. 

Gambar 6. Masyarakat 5.0 di bidang maintenance [1]


Di sisi keuangan, transfer dana yang kini bisa dilakukan secara online akan berganti ke pembayaran cashless dengan biaya transfer yang seminimal mungkin. Teknologi blockchain akan memangkas waktu dan harga disamping meningkatkan keamanan dan kenyamanan transfer, baik nasional maupun internasional (ini yang saya masih ragu). 

Gambar 7. The future is cashless [1]

Tantangan

Riset saya, yang sebagian besar mulai diarahkan ke teknologi informasi, kini juga diarahkan untuk menjawab tantangan Masyarakat 5.0 (yang telah mulai direncakanan oleh Abe saat menjabat PM Jepang, dalam program abenomics). Diantara tantangan terbesarnya adalah: tingkat kelahiran yang turun dan masyarakat tua yang meningkat (di Jepang), antisipasi pada perubahan struktur industri dan membuat nilai kustomer baru, mempromosikan implementasi sosial pada teknologi (human-machine interaction, otomasi). Untuk mencapai hal tersebut riset saya akan fokus pada IoT dan akuisisi data, pengolahan data besar, dan AI/deep learning untuk mengolah data tersebut.


Referensi: 
[1] Realizing Society 5.0, https://www.japan.go.jp/abenomics/_userdata/abenomics/pdf/society_5.0.pdf

Thursday, April 07, 2022

Terpaksa Berdzikir

Sudah lama saya tidak menulis tentang agama.

Senada dengan teknik di tulisan saya ini untuk memaksa belajar kanji, aka Terpaksa Belajar Kanji, aka belajar kanji otomatis, teknik berikut ini bisa memaksa kita berdzikir: memasang wallpaper screen lock handphone yang berisi dzikir.

Saya dapat inspirasi dari sini.


Di akhir ceramahnya, dai tersebut menyarankan jamaah untuk mengganti wallpaper screen lock HPnya dengan wallpaper (yang bermuatan) dzikir. Dan saya segera melaksakannya. Ini penampakannya.



Dalam kasus saya, saya tidak perlu mengganti wallpaper. Hanya mengganti "lock screen owner info" (Xiaomi, setting >> lock screen >> lock screen format >> lock screen owner info >> [tambahkan kalimat dzikir, misal subhanallah... :D]).

Teknik lain yang bisa memaksa berdzikir:

  1. Menjadikan dzikir sebagai password
  2. Memasang tulisan doa/dzikir di dinding 
  3. Memasang wallpaper laptop, tablet, dll dengan kalimat dzikir

Semoga, suatu saat, kita (baca: saya) bisa berdzikir dengan tanpa terpaksa, insyaAllah. Harus bisa. Pasti bisa.

Wednesday, April 06, 2022

New Paper: Survey on bimodal speech emotion recognition ...

Finally, the final version of my paper appeared in Elsevier. This is my second paper in Speech Communication Journal (currently it is Q1, IF: 2.0, CiteScore:4.8, h5-index: 28, google top 20). This one is open access in contrast to the previous subscription paper. Here is the link. For short descriptions, you can read through this passage.

https://doi.org/10.1016/j.specom.2022.03.002

Abstract

Speech emotion recognition (SER) is traditionally performed using merely acoustic information. Acoustic features, commonly are extracted per frame, are mapped into emotion labels using classifiers such as support vector machines for machine learning or multi-layer perceptron for deep learning. Previous research has shown that acoustic-only SER suffers from many issues, mostly on low performances. On the other hand, not only acoustic information can be extracted from speech but also linguistic information. The linguistic features can be extracted from the transcribed text by an automatic speech recognition system. The fusion of acoustic and linguistic information could improve the SER performance. This paper presents a survey of the works on bimodal emotion recognition fusing acoustic and linguistic information. Five components of bimodal SER are reviewed: emotion models, datasets, features, classifiers, and fusion methods. Some major findings, including state-of-the-art results and their methods from the commonly used datasets, are also presented to give insights for the current research and to surpass these results. Finally, this survey proposes the remaining issues in the bimodal SER research for future research directions.

 

Method

This is my first survey/review paper. I divided the contents into the building blocks of SER. First, I show the background of shifting from unimodal acoustic analysis to bimodal acoustic-linguistic information fusion. The rest is a comparison of more than a hundred papers. The most interesting part is that I summarized the comparison in several tables highlighting current state-of-the-art results (SOTA).

Result

The most important results are Table 3, Table 4, and Table 5. Here is a screenshot of Table 3 which list the current SOTA for the IEMOCAP dataset.
iemocap


Take home message

  1. There are several challenges listed in the paper
  2. Can we extract linguistic information without text? Yes, it can. Read here (actually it is included in the challenges part of my review paper, and someone already did it).

Citation

Don't forget to cite my paper as below if you get the benefit of reading that paper for your own manuscript.
Atmaja, B. T., Sasou, A., & Akagi, M. (2022). Survey on bimodal speech emotion recognition from acoustic and linguistic information fusion. Speech Communication, 140, 11–28. https://doi.org/10.1016/j.specom.2022.03.002

Wednesday, March 30, 2022

Mencoba Docker

Setelah sekian lama ingin mencoba docker, kali ini saya benar-benar mencobanya. Selama ini saya bisa menghindari docker karena venv dan conda tidak pernah gagal. Karena kali ini conda gagal mendukung GPU di tensorflow 1.15, maka mau tidak mau Docker menjadi solusi terbaik. 

Docker
Gambar 1. Diagram alir ketika venv gagal, berlanjut ke conda, berlanjut ke docker. Selama venv berhasil membuat environment yang diinginkan saya akan memakainya sebagai pilihan pertama, jika tidak baru mencoba conda dan docker, secara bertahap. 

Docker Untuk Menginstall Software (Paket/Library) Baru

Sampai saat ini saya masih memakai Ubuntu 16.04 untuk laptop-laptop pribadi dan Ubuntu 20.04 untuk laptop-laptop kantor. Permasalahan pada OS lama adalah kegagalan untuk menginstall software versi baru. Kasus saya adalah menginstall paket opensmile python versi terbaru (versi 2.4.1) yang membutuhkan library glibc di atas versi 2.31. Library glibc ini tidak bisa diupate. Pernah sekali saya mengupdatenya dan system saya (Centos 7) langsung rusak dan harus install ulang. Docker adalah solusinya.
 
# asumsi docker sudah terinstall
$ docker run -it ubuntu bash
# jika ada masalah permission, lakukan: sudo chmod 666 /var/run/docker.sock
$ apt update
$ apt install python3
$ apt install python3-pip
$ python3 -m pip install opensmile
$ apt install libsndfile1 libsndfile1-dev
$ apt install sox
$ apt insalll ffmpeg
root@6e7dd3cbfee1:/# python3
Python 3.8.10 (default, Mar 15 2022, 12:22:08) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import opensmile
>>> opensmile.__version__
'2.4.1'
>>> exit()
root@6e7dd3cbfee1:/# ldd --version ldd
ldd (Ubuntu GLIBC 2.31-0ubuntu9.7) 2.31
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

Menyimpan file docker dengan commit

Docker tidak didesain untuk menyimpan file, untuk menyimpan file (dan perubahan/update) dari docker yang sedang berjalan dan docker-docker sebelumnya gunakan perintah commit berikut.
Format:
docker commit CONTAINER_ID IMAGE
$ docker ps -a # bisa juga dengan ps -l untuk docker yang sedang berjalan
$ dokcer commit ef7d7090e3c7 ubuntu:opensmile

Docker Untuk Menginstall Software Lama (Tensorflow 1.15 dengan GPU support) 


Skenario: Saya ingin menjalankan kode di repository berikut: Efficient Bigan, dengan GPU RTX 3090, yang saat itu (saat repo itu dibuat dengan tensorflow 1.15) belum diproduksi.
Solusi:
# asumsi docker belum terinstall
$ sudo apt install docker.io
$ curl https://get.docker.com #install curl jika belum ada
$ sudo systemctl --now enable docker
  
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
      && curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add - \
      && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
$ sudo apt update
$ docker images      # list images docker 	 	
REPOSITORY                  TAG             IMAGE ID       CREATED       SIZE
nvcr.io/nvidia/tensorflow   22.04-tf1-py3   8b2abbd886f0   2 years ago   9.51GB
$ docker run --gpus all -it --rm nvcr.io/nvidia/tensorflow:22.04-tf1-py3
$ git clone https://github.com/houssamzenati/Efficient-GAN-Anomaly-Detection.git
$ cd Efficient-GAN-Anomaly-Detection
$ python3 main.py gan mnist run --nb_epochs=10 --label=0 
______   _____       _____       ____                                                                                                                   
|_     `.|_   _|     / ___ `.   .'    '.                                                                                                                 
  | | `. \ | |      |_/___) |  |  .--.  |                                                                                                                
  | |  | | | |   _   .'____.'  | |    | |                                                                                                                
 _| |_.' /_| |__/ | / /_____  _|  `--'  |                                                                                                                
|______.'|________| |_______|(_)'.____.'                                                                                                                 
                                                                                                                                                         
                                                                                                                                                         
[09:48:37 INFO @AnomalyDetection] Running script at gan.run_mnist                                                                                        
2022-03-30 09:48:37.916727: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0        
[09:48:37 WARNING @tensorflow] Deprecation warnings have been disabled. Set TF_ENABLE_DEPRECATION_WARNINGS=1 to re-enable them.                          
[09:48:38 WARNING @tensorflow] From /TA/demo/Efficient-GAN-Anomaly-Detection/gan/run_mnist.py:4: The name tf.ConfigProto is deprecated. Please use tf.com
pat.v1.ConfigProto instead.                                                     
...
2022-03-30 09:48:44.229713: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublas.so.11
2022-03-30 09:48:44.683684: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudnn.so.8
[09:48:51 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 0 | time = 7s | loss gen = 0.7218 | loss dis = 1.3530 
[09:48:54 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 1 | time = 3s | loss gen = 0.7747 | loss dis = 1.2383 
[09:48:57 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 2 | time = 3s | loss gen = 0.8793 | loss dis = 1.0877 
[09:49:01 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 3 | time = 3s | loss gen = 1.0170 | loss dis = 0.9235 
[09:49:04 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 4 | time = 3s | loss gen = 1.1724 | loss dis = 0.7746 
[09:49:07 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 5 | time = 3s | loss gen = 1.3378 | loss dis = 0.6493 
[09:49:11 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 6 | time = 3s | loss gen = 1.5056 | loss dis = 0.5522 
[09:49:14 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 7 | time = 3s | loss gen = 1.6597 | loss dis = 0.4744 
[09:49:17 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 8 | time = 3s | loss gen = 1.7992 | loss dis = 0.4116 
[09:49:21 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 9 | time = 3s | loss gen = 1.8616 | loss dis = 0.3848 
[09:49:21 WARNING @GAN.train.mnist.fm.0] Testing evaluation...
[09:54:19 INFO @GAN.train.mnist.fm.0] Testing : mean inference time is 1.5292
Testing | PRC AUC = 0.7183

Me-mount direktori 

Alih-alih membuat commit setiap kali kita mengedit, kita bisa memount direktori saat memanggil docker.
Skenario: Mengedit file diluar docker, mengeksekusi file (misal python) didalam docker. Caranya adalah sebagai berikut.
$ docker run --gpus all -it --mount type=bind,source=/TA,target=/TA tf1.15:py3
Dimana `source` adalah sumber direktori, dan `target` adalah target direktori. Image docker sebelumnya sudah saya commit menjadi `tf1.15` dengan tag `py3`. 

Menambahkan docker ke sudoers

Ketika membuka docker, terlihat bahwa tanda di baris kiri terminal adalah sharp #, ini menandakan kita masuk sebagai super user (sudo). Karenanya ada error saat membuka docker pertama kali (harus chmod 666 dulu). Solusi ini hanya berjalan sementara, untuk solusi permanen kita bisa menambahkan docker ke grup sudoers sebagai berikut.
# menambahkan grup baru bernama docker
$ sudo groupadd docker
# menambahkan $USER ke grup docker
$ sudo usermod -aG docker $USER
# merefresh grup
$ newgrp docker
Demikian tutorial singkat docker ini, semoga bermanfaat.

Referensi;
[1] https://docs.docker.com/engine/install/linux-postinstall/

Monday, March 28, 2022

Tools I used for (accelerating) science and research 2022

I made seven publications this year (April 2021 - March 2022) and eight publications last year (April 2020 - March 2021). Here is the list of the tools (and their description) for accelerating my research.

The list is ordered based on its importance.

1. OS: Ubuntu (the most useful part: stfp inside nautilus)

2. vscode (both python and latex, also remote editing)

3. ssh with byoubu (open multiple sessions of the terminal in one instance)

4. Libreoffice (draw, calc, impress, writer)

5. Inkscape (for editing plots)

6. Simplenote (to make notes)

7. Grammarly (paid, mostly inside vscode)

8. Gnumeric (spreadsheet-like)

9. Insync (paid, to host one drive, google drive, dropbox, etc)

10. pdfcrop (to crop your image, automatically!!)

11. clipit (clipboard manager )

12. Mendeley (reference manager, automatic BIB file creation)


Tuesday, March 15, 2022

Permasalahan Ekuitas Jurnal Open Access

Jurnal dengan skema Open Access (OA) terlihat fair: jika anda (penulis) ingin tulisannya bebas diunduh (didownload), maka harus membayar article processing charge (APC). APC ini tidak murah, jurnal dimana saya mengirim tulisan saya, yakni Speech Communication, mematok USD 2390 untuk APC-nya. Daftar APC lengkap untuk jurnal Elsevier ada di sini. Jika tulisan kita diterima, maka kita bisa memilih subcription fee agar terhindar dari APC. Konsekuensinya, orang yang mau mengunduh tulisan kita harus membayar (melanggan) baik secara pribadi ataupun secara institusi. Catatan (baik) pentingnya, proses review tidak bergantung pada pilihan publikasi ini, baik open access atau subcription fee. Acceptance rate dari jurnal-jurnal Elsevier tetap kompetitif, sekitar 20-30% dari total 100% submisi.

Kembali kita tulis logika sederhananya.

Jika anda penulis ingin tulisan anda gratis diunduh, anda harus membayar APC. Jika tidak, maka pengunduh yang harus membayar biaya unduhannya.

Statement di atas terlihat logis, namun ada permasalahan mendasar pada logika di atas.

Permasalahan

Bagaimana dengan penulis yang tidak memiliki dana untuk membayar APC padahal open science / open research itu seharusnya tetap diberlakukan (wajib) bagi mereka? Disinilah ketidakadilan (inequity) itu nampak.

Saya pun belum menemukan solusi untuk hal ini; pun demikian ada rekomendasi dari ON-MERRIT yang bisa dibaca di sini. Ada jurnal open access di [1] yang bebas APC, namun (mungkin) reputasinya dipertanyakan. Penerbit tentunya tidak mau rugi, namun harus tetap profesional dalam mencari biaya operasional perusahaan mereka.

Note:

1. Ada jurnal open access yang bebas biaya APC,  daftarnya ada di URL ini.

Tuesday, February 22, 2022

Haram menggunakan "nggih..." (dalam komunikasi Bahasa Indonesia)

Komunikasi antar rekan (kerja) merupakan hal penting dalam menjaga hubungan antar rekan kerja sekaligus ujung tombak penyelesaian pekerjaan. Bayangkan kalau dalam bekerja (tim) kita tidak berkomunikasi dengan rekan kerja. Namun ada satu keberatan yang saya rasakan ketika berkomunikasi dengan rekan kerja di +62 di kalangan orang Jawa (saya juga Jawa): penggunaan kata "nggih". Kenapa saya keberatan dengan penggunaan kata  nggih dalam komunikasi formal, semi formal, dan non-formal? Berikut alasannya.


1. Melecehkan bahasa Indonesia

Alasan pertama adalah pelecehan bahasa Indonesia. Salah satu kriteria untuk "memuliakan" bahasa adalah tidak mencampuradukkan bahasa satu dengan bahasa yang lain. Bahasa Indonesia dengan bahasa Inggris, bahasa Indonesia dengan bahasa Jawa. Kecuali kata tersebut tidak ada padanannya. Contoh: Itu tidak important. Apakah "important" tidak ada dalam bahasa Indonesia? Ada, "penting". Akan lebih baik mengatakan/menyatakan "itu tidak penting".


2. Tidak perlu

Alasan kedua, (jika misalnya alasan pertama telah dipenuhi) adalah bahwa penggunaan "nggih" tidak perlu. Dalam komunikasi formal, semi formal, dan non formal, kita perlu menggunakan bahasa yang datar. Sebisa mungkin tidak mengandung emosi (tapi ada empati bila perlu).

Contoh:

Minto tolong dikirim ke saya dokumen persyaratannya.

Minta tolong dikirim ke saya dokumen persyaratannya nggih...


Nggih pada contoh kedua tidak perlu. Contoh pertama tanpa nggih lebih singkat, menghindari pelecehan bahasa, dan ketidakperluan kata tambahan.


3. Berkesan memerintah

Alasan ketiga dan paling krusial dari larangan penggunaan nggih adalah: "berkesan memaksa atau memerintah".

Contoh:

Minto tolong dikirim ke saya dokumen persyaratannya.

Minta tolong dikirim ke saya dokumen persyaratannya nggih...


Alurnya seperti ini. Memerintah biasanya dilakukan oleh atasan ke bawahan. Namun, karena si pengirim pesan ini setara atau bahkan bawahan, maka tidak bisa memerintah rekan kerjanya, sehingga dipakailah kata "nggih.." tadi. Karena kata "nggih" itu kromo inggil dan dilakukan oleh bawahan ke atasan, jadi dengan menggunakan kata "nggih" si pengirim pesan menutupi pemaksaan/perintah dalam pesannya dengan kata "nggih" tersebut.


Kondisi khusus agar terkesan sopan

Alasan-alasan di atas khusus ditujukan untuk komunikasi dengan rekan kerja. Untuk orang lain (bukan rekan kerja), penggunaan nggih bisa saja digunakan agar terkesan sopan. Seperti yang dikicaukan teman saya berikut.



Sanggahan: Saya bukan ahli bahasa dan tulisan ini merupakan pendapat saya pribadi berdasarkan argumen di atas untuk diterapkan di kalangan internal saya  (meski saya mengklaim pendapat ini juga bersifat umum).

Saturday, February 05, 2022

Fuzzy search with FZF

`history` itu penting. Dengannya kita bisa mencari perintah-perintah apa saja yang telah kita panggil. Berikut contohnya.
$ history
# output
..
 1978  cd
 1979  cd github/CSS
 1980  cd github/CCS/
 1981  git pull
 1982  cd scripts/
 1983  ls
 1984  cp create_csv_split.py create_csv_split_ccs.py
 1985  code create_csv_split_ccs.py 
 1986  python3.8 -m IPython
 1987  cd
 1988  ls /groups/gac50538/
 1989  cd github/CSS/
 1990  ls
 1991  cd ..
 1992  ls
 1993  cd CCS/
 1994  ls
 1995  code csv/train_dataset_ccs.csv 
 1996  python3 -m IPython
 1997  python3 -m IPython
 1998  ssh 192.168.244.64
 1999  history
Lebih mudah lagi, perintah `history` bisa kita panggil dengan jalan pintas Ctrl-R. Kita bisa menggunakan Ctrl-R lagi untuk berputar (cycle) ke `history` selanjutnya. 

FZF 

FZF membuat `history` terlihat usang. Atau bisa saja dikatakan memambah kemampuan `history` agar lebih bertenaga lagi: "fuzzy search". Perhatikan potongan video berikut.
sudo apt install fzf
fzf
# Ctrl-R
Untuk bisa menggunakan fitur tersebut, yakni mengganti Ctrl-R dari `history` ke `fzf`. Kita perlu tambahkan dua baris berikut ke .bashrc.
source /usr/share/doc/fzf/examples/key-bindings.bash
source /usr/share/doc/fzf/examples/completion.bash
Dari mana saya tahu agar menambahkan dua baris di atas? Dari output `apt-cache show fzf`, seperti disarankan di laman resminya.
Demikian, Ctrl-R sekarang sudah berganti ke `fzf` dari `history`. Selamat jalan `history`.

Thursday, January 27, 2022

Ekstraksi Fitur Akustik dengan Torchaudio

Kode di bawah ini mengekstrak tiga fitur akustik -- spectrogram, melspectrogram, dan mfcc -- dari sebuah file audio "filename" (wav, mp3, ogg, flacc, dll). Ketiga fitur akustik tersebut merupakan fitur-fitur akustik terpenting dalam pemrosesan sinyal wicara. Keterangan singkat ada di dalam badan kode. Hasil plot ada di bawah kode.

###
#import torch
import torchaudio
from matplotlib import pyplot as plt
import librosa

# show torchaudio version
# torch.__version__
print(torchaudio.__version__)


def plot_spectrogram(spec, title=None, ylabel="freq_bin", aspect="auto",
                     xmax=None):
    fig, axs = plt.subplots(1, 1)
    axs.set_title(title or "Spectrogram (db)")
    axs.set_ylabel(ylabel)
    axs.set_xlabel("frame")
    im = axs.imshow(librosa.power_to_db(spec), origin="lower", aspect=aspect)
    if xmax:
        axs.set_xlim((0, xmax))
    fig.colorbar(im, ax=axs)
    plt.show(block=False)


filename = "/home/bagus/train_001.wav"  # change with your file
waveform, sample_rate = torchaudio.load(filename)

# Konfigurasi untuk spectrogam, melspectrogram, dan MFCC
n_fft = 1024
win_length = None  # jika None maka sama dengan n_fft
hop_length = 512   # y-axis in spec plot
n_mels = 64  # y-axis in melspec plot
fmin = 50
fmax = 8000
n_mfcc = 40  # must be smaller than n_mels, will be y-axis in plot

# definisi kelas untuk ekstraksi spektrogram
spectrogram = torchaudio.transforms.Spectrogram(
    n_fft=n_fft,
    win_length=win_length,
    hop_length=hop_length,
    center=True,
    pad_mode="reflect",
    power=2.0,
)

# Show plot of spectrogram
spec = spectrogram(waveform)
print(spec.shape)  # torch.Size([1, 513, 426])
plot_spectrogram(spec[0], title=f"Spectrogram - {str(filename)}")


## kelas untuk ekstraksi melspectrogram
melspectogtram = torchaudio.transforms.MelSpectrogram(
    sample_rate=sample_rate,
    n_fft=n_fft,
    win_length=win_length,
    hop_length=hop_length,
    n_mels=n_mels,
    f_min=fmin,
    f_max=fmax,
)

# Calculate melspec
melspec = melspectogtram(waveform)
melspec.shape # torch.Size([1, 513, 426])
plot_spectrogram(melspec[0], title=f"Melspectrogam - {str(filename)}")

## kelas untuk ekstraksi MFCC
mfcc_transform = torchaudio.transforms.MFCC(
    sample_rate=sample_rate,
    n_mfcc=n_mfcc,
    melkwargs={
      'n_fft': n_fft,
      'n_mels': n_mels,
      'hop_length': hop_length,
      'mel_scale': 'htk',
    }
)

# plot mfcc
mfcc = mfcc_transform(waveform)
print(mfcc.shape) # torch.Size([1, 40, 426])
plot_spectrogram(mfcc[0], title=f"MFCC - {str(filename)}")
###

Plot 


Wednesday, January 19, 2022

Choosing Journals and Conferences for Publication: Google Top 20 (and h5-index > 30)

If you want to publish your academic paper in a conference or journal, you may be confused about to which conference or journal you should submit your papers to. This short article may help you. To be categorized as a "reputable journal", my institution required two indicators below.

  1. It appears in Google Top 20 (all categories, categories, and sub-categories)
  2. It has Google H5-index > 30
For the first reason, it makes sense. The top twenty are the top 20 journals and conferences (mixed) which have the highest h5-index. I don't know the reason for the second reason why my institution chooses 30 as the limit of h5-index for "more incentive". It still makes sense since the higher h5-index means the higher impact.

From those two indicators, I choose the first as the main criteria for selecting publication. Here are five top 20 journals and conferences from all categories, categories, and two sub-categories in my field.


Google Top-20 (all categories)


For choosing categories, click "VIEW ALL"
https://scholar.google.com > Metrics > VIEW ALL.

Google Top 20 Category Engineering and Computer Sciences



Google Top 20 Category Life Sciences and Earth Sciences



Google Top 20 Sub-category: Signal Processing



Google Top 20 Sub-category: Acoustic and Audio



This guide for selecting criteria is not mandatory in my constitution. But they will give more bonus to the researchers if their publications are ranked by one or both criteria above (more bonus for both, maybe).

Tuesday, January 04, 2022

New Paper: Effect of Different Splitting Criteria on Speech Emotion Recognition

Abstract

Traditional speech emotion recognition (SER) evaluations have been performed merely on a speaker-independent (SI) condition; some of them even did not evaluate their result on this condition (speaker-dependent, SD). This paper highlights the importance of splitting training and test data for SER by script, known as sentence-open or text-independent (TI) criteria. The results show that employing sentence-open criteria degraded the performance of SER. This finding implies the difficulties of recognizing emotion from speech in different linguistic information embedded in acoustic information. Surprisingly, text-independent criteria consistently performed worse than speaker+text-independent (STI) criteria. The full order of difficulties for splitting criteria on SER performances from the most difficult to the easiest is text- independent, speaker+text-independent, speaker-independent, and speaker+text-dependent. The gap between speaker+text- independent and text-independent was smaller than other criteria, strengthening the difficulties of recognizing emotion from speech in different sentences.


Method

Experiment #1: average of 30 trials (runs)
Experiment #2: 5-fold cross-validation
Experiment #3: Same number of training and test data


Result


Take home message

Sentence (or linguistic) information plays a crucial role in speech emotion recognition.


Full paper + code:

https://github.com/bagustris/ti

Related Posts Plugin for WordPress, Blogger...