Web App dengan Python Flask, Nginx dan uwsgi.

29 September 2017 at 18:23 | Posted in Uncategorized | Leave a comment

Walapun sempat mengerjakan beberapa proyek dengan PHP, pengalaman saya membuat web app dengan PHP ternyata tidak menyenangkan. Pernah coba menggunakan Java, tapi menurut saya terlalu rumit untuk web app. Sejalan dengan eksplorasi saya belajar Python untuk keperluan datamining, maka sekalian saja menggunakan Python untuk membuat applikasi web, baik frontend maupun untuk RestFul-API.

Di posting sebelumnya saya mencoba membuat sendiri dari nol, tapi ternyata rawan kesalahan. Setelah lihat-lihat beberapa framework, menurut saya yang paling menarik adalah Flask (http://flask.pocoo.org/).  Seperti biasa, saya share di blog ini untuk catatan pribadi dan mudah-mudahan bermanfaat bagi pemula seperti saya.

Saya menggunakan instance Ubuntu AWS  dengan client Windows+Putty.  Pertama siapkan port forwarding agar kita bisa mencoba app dengan aman via SSH.  Di Putty, pilih settings->connection-SSH-tunnels. Saya forward port 5000, jangan lupa klik add (gambar bawah). Simpan session supaya tidak perlu mengeset berulangkali.

tunnel

 

Pertamakali yang perlu dilakukan adalah install pip, tools untuk menginstall lib python.

sudo apt-get update
sudo apt-get install python-pip

Kemudian install nginx sebagai webserver

sudo apt-get install nginx

Pastikan port 80 sudah dibuka (kalau digital ocean dibuka, tapi kalau AWS defaultnya ditutup),  dan buka alamat server kita di browser, harusnya pesan bahwa nginx sudah terinstall akan keluar.

Selanjutnya kita akan menginstall virtual environment (virtualenv). Ini penting dan wajib karena memungkinkan kita menginstall lib Python untuk suatu proyek  yang terisolasi dengan proyek lainnya. Tanpa virtualenv, install lib bisa membuat proyek lain jadi tidak jalan (pengalaman pahit pribadi hehe).

sudo pip install virtualenv 

Selanjutnya buat directory project dan masuk.

mkdir myproject
cd myproject

Dalam direktori ini set virtual env dengan:

 virtualenv myproject-env 

untuk mengaktivasi virtual env ini, gunakan

source myproject-env/bin/activate 

perhatikan prompt akan berubah. Sekarang kalau kita jalankan pip, maka lib tersebut akan terinstall di virt env ini saja (myproject/myproject-env).  Tapi kalau installnya lewat apt-get tetap berlaku untuk semua.

Untuk mengetest, coba jalankan

 which python 

maka yang muncul adalah lokasi Python di myproject. Untuk menonaktifkan virt env ini,  ketik  deactivate (tapi jangan lakukan dulu sekarang).

Selanjutnya install Flask dan uwsgi. Flask untuk framework, sedangkan uwsgi untuk koneksi dengan nginx.

 pip install uwsgi flask 

Selanjutnya kita akan membuat code sederhana hello world.

from flask import Flask
from werkzeug.serving import run_simple
app = Flask(__name__)

@app.route("/")
def beranda():
     return "Hello World"

if __name__ == '__main__':
     run_simple('0.0.0.0', 5000, app, use_reloader=True, use_debugger=True, use_evalex=True)

Jalankan

 python myapp.py 

dan buka browser dengan alamat  http://localhost:5000/  maka di browser akan muncul “Hello World” (jika menggunakan putty, pastikan tunneling sudah benar).  Jika code diupdate maka otomatis akan dilakukan reload. Gampang kan 🙂

Inilah kelebihan Flask, sangat mudah untuk dijalankan dan didebug.  Tapi tentu jika sudah operasional cara seperti ini tidak cocok. Sekarang kita akan menghubungkan app ini dengan web server nginx melalui uwsgi.

Pertama buat konfigurasi wsgi dulu, buat file uwsgi-myproject.ini dengan isi sebagai berikut:

Catatan: Sesuaikan path lokasi project di variabel home. Pastikan nama directory virtenv sudah cocok.

[uwsgi]
home = /home/ubuntu/myproject
wsgi-file = %(home)/myapp.py
socket = 127.0.0.1:3033
callable = app
module = app
daemonize = %(home)/app.log
pidfile = %(home)/app.pid
virtualenv= %(home)/myproject-env

Sekarang kita perlu update nginx agar mendengarkan socket uwsgi.  Buka /etc/nginx/nginx.conf   (mungkin perlu sudo) lalu pada bagian  ” http { ” tambahkan konfigurasi server berikut:

http {
  ##
  # Basic Settings
  ##
  ...
  server {
    listen 80;
    location / { include uwsgi_params; uwsgi_pass 127.0.0.1:3033; }
  }
}

Selanjutnya hapus page default nginx dan restart nginx.

sudo rm -v /etc/nginx/sites-enabled/default
sudo service nginx restart

Sekarang jalankan uwsgi project kita dengan cara

 uwsgi uwsgi-myproject.ini 

Sekarang buka di browser alamat server anda (bukan localhost:5000), yang tadinya ucapan default dari nginx harusnya akan berubah menjadi “Hello world” . Jika tidak, coba lihat catatan error di di file app.log (tail -10 app.log)

Untuk men-stop uwsgi, lakukan dengan (hati-hati, parameternya adalah app.pid bukan file uwsgi.ini):

 uwsgi --stop app.pid 

Tips: jika di-log keluar pesan seperti ini: “probably another instance of uWSGI is running on the same address”. Reset port dengan

 sudo fuser -k 3033/tcp 

 

 

 

 

 

 

 

 

 

 

 

Advertisements

App mencari makan halal di Bali

1 September 2017 at 17:24 | Posted in Uncategorized | Leave a comment

Link ke app: https://play.google.com/store/apps/details?id=yuliadi.com.blhlv2

Ide pembuatan app ini sudah cukup lama. Saat saya datang ke Bali,  salah satu hal yang menyulitkan adalah mencari makan halal. Biasanya googling dulu, lalu tandai di peta. Tetapi ada beberapa tempat yang jarang dibahas orang, tidak mencantumkan halal di restorannya dan diwebsitenya padahal sebenarnya punya sertifikat halal MUI.  Ini diperparah situs MUI yang tidak menyedikan informasi yang mudah diakses masyarakat.

Sekitar sebulan yang lalu, untungnya ada pelatihan pengembangan Android dari Google untuk para dosen. Lumayan panjang 5 hari full time. Sambil ikut pelatihan saya mulai iseng mulai buat app ini.  Berlanjut saat saya ikut menemani istri ke Bali dalam rangka konferensi.

Saya tidak menduga ternyata perlu waktu banyak untuk mengumpulkan dan memverifikasi data.  Data dari MUI (pusat dan lokal Bali) berbentuk pdf dan isinya lebih fokus terhadap perusahaan yang mendaftarkan dan tidak ada informasi alamat.  Perlu dicek satu persatu dengan Google Streetview, Zomato dan Tripadvisor.

Setelah data tempat makan yang dapat sertifikat MUI, saya lanjutkan dengan data yang self-certified, artinya mengklaim halal dengan tulisan “halal” ditempel di depan tempat restoran atau diwebsitenya. Setelah googling tempat-tempat yang katanya halal, ternyata banyak yang sebenarnya tidak mengklaim dirinya halal karena menyajikan minuman alkohol. Orang mengganggap halal karena berasumsi karena tempat itu hanya menyajikan seafood, makanan timur tengah dan sunda.  Mungkin ke depannya saya akan tambahkan kategori no-pork tanpa atau dengan alkohol.

Dari sisi teknis, banyak yang saya pelajari. Mungkin nanti detilnya akan diposting terpisah. Ini beberapa yang saya ingat:

  • Recyleview, walaupun lebih ribet ternyata lebih cepat daripada listview.
  • Penggunaan key untuk mengakses Google Map API.  Ternyata key ini kalau ganti komputer harus dibuat lagi. Lalu saat publish jangan lupa diletakkan juga di /res/release.   Jika menggunakan Google Play App Signing, jangan lupa SHA1-nya ditambahkan ke key. Sempat panik saat coba app yang di playstore peta-nya blank 😦
  • Splashscreen dengan style tanpa load view, sangat membantu dari sisi user interface daripada user melihat layar kosong.
  • Layout dengan constraint layout mantep, mulai dari HP kecil sampai tablet bisa tetap bagus.
  • Karena ukuran APK saya besar (kena error), maka saya set proguard agar mengecilkan app. Tapi ini punya efek samping fasilitas search tidak jalan. Bug yang luar biasa (hanya error saat jadi APK). Harus tambahkan perkecualian di proguard untuk searchview.
  • Ada masalah penggunaan appcompat, ini saya lupa, tapi kalau tidak salah saat saya mengakses icon. Di HP istri (LG) ini menyebabkan error.
  • Ada beberapa device lokal (Andromax) yang mengalami error. Tapi karena saya tidak punya devicenya, masih belum bisa didebug.
  • Alpha dan beta test bisa dilakukan di playstore, tapi belum jelas caranya seperti apa.

 

Produk Digital

30 June 2017 at 23:34 | Posted in Uncategorized | Leave a comment

Saat ini kita  dapat melihat bagaimana kemampuan anak sampai dengan remaja mengkonsumsi produk digital. Mulai dari film, game, berita  sampai sosial media.  Jika itu dihilangkan dapat dipastikan mereka akan gelisah. Mereka lebih memilih akses internet daripada membeli barang seperti baju dan berwisata. Apakah mereka merasa tertekan dan sedih?  Kalau ditanya, biasanya mereka merasa cukup puas dan bahagia. Produk digital sudah memenuhi semua kebutuhan mereka (diluar sandang-pangan-papan).  Bagi mereka produk digital sudah seperti candu.

Generasi tipe ini hanya mengkonsumsi tapi sangat sedikit memproduksi.  Tidak ada masalah keseimbangan karena  produk digital sekali dibuat dapat direplikasi ribuan bahkan jutaan kali nyaris tanpa biaya. Satu orang bisa memproduksi belasan film di Youtube yang kemudian ditonton ratusan ribu orang.

Pergeseran ini juga terjadi di dunia kerja, perusahaan dengan puluhan pekerja bisa mempunyai pelanggan sampai jutaan orang. Tahun 2014, Whatsapp hanya memiliki 55 pegawai saat dibeli Facebook seharga 19 Milyar USD  (250 Triliun rupiah) dan sudah memiliki pengguna sebanyak 420 juta. Perkembangan kecerdasan buatan (AI) juga mengancam akan  menggantikan pekerjaan yang tadinya dianggap aman dari otomatisasi.

Menurut saya, di masa depan, masyarakat akan terbagi jadi dua kelompok. Ada kelompok minoritas yang punya kemampuan sangat tinggi dan sangat produktif dala menghasilkan produk digital dan di sisi lain kelompok mayoritas yang pasif dan hanya mengkonsumsi.  Bisa dipastikan kelompok minoritas akan memiliki kekayaan dan pengaruh lebih besar.

Ada dua pendekatan  untuk mengatasi kesenjangan ini. Pertama, dengan mempersiapkan sebanyak mungkin orang untuk bisa menghasilkan produk digital. Misalnya dengan pengenalan tentang ilmu komputasi untuk siswa SD-SMA dan materi elearning gratis seperti MOOC.  Kedua, dengan transfer kekayaan. Golongan minoritas dengan kekayaan berlimpah mendapat pajak tinggi dan ditransfer ke golongan mayoritas.  Artinya,  berikan uang yang cukup walaupun mereka menganggur  untuk sandang-pangan-papan-internet (hanya cukup, tidak berlebihan) dan biarkan mereka tenggelam dengan mengkonsumsi media digital.  Selama mereka puas, tidak akan terjadi kejahatan dan struktur sosial akan stabil (tidak ada kerusuhan).

Blog baru

30 May 2017 at 21:42 | Posted in Uncategorized | Leave a comment

Akhirnya buat blog resmi di UPI (yudiwibisono.staf.upi.edu)   Posting tentang pemrograman, penelitian, pengajaran dan teknologi akan dilanjutkan di sana. Blog ini tetap akan diisi dengan topik lain seperti keluarga, politik(?) dan lain-lain.

Backend API dengan Python

1 May 2017 at 13:05 | Posted in Uncategorized | Leave a comment

Update: sebaiknya gunakan libray seperti Flask-Restfull. Tutorial saya tentang pengantar Flask+uwsgi+nginx

 

Saat ini saya mulai belajar Python karena Tensorflow (dan beberapa deeplearning framework) menggunakan Python. Lalu kebetulan di kuliah mobile programming saya memberikan tugas besar yang memerlukan backend untuk komunikasi antar app jadi sekalian saja untuk latihan.

Pada tugas mobile programming tersebut mahasiswa diminta membuat app yang mirip Gojek atau Uber tetapi untuk pedagang keliling.  Intinya agar pembeli bisa melihat pedagang keliling yang lewat. Jadi idenya saya akan buat REST  API dengan Python yang dapat digunakan untuk menyimpan dan berbagi  lokasi user (baik pedagang maupun pembeli). Niat utamanya untuk mencoba, niat sampingannya supaya tidak ada mahasiswa yang protes “kok kuliah mobile programming diminta buat backend” hehe.

Untuk server, saya buat droplet DigitalOcean. Bisa saja sih menggunakan server ilkom UPI, cuma gara-gara bulan lalu kena hack jadi males (tepatnya takut utak-atik). Install apache2, mysql, python dan setup Python sebagai CGI tidak susah. Cuma ternyata perlu hati-hati untuk versi python: versi 2.7 dan 3. Saya menggunakan python3, tapi saat install library,  lupa malah menggunakan pip, bukan pip3.  Sempat bingung kok librarynya tidak dikenal padahal sudah diinstall.

Dari sisi bahasa, Python yang menggunakan indentasi, bukan “{” “}” sempat membuat saya salah meletakan code, solusinya saya tambahkan comment seperti “#end for” 🙂 Yang paling susah adalah masalah protokol  HTTP-nya sendiri.  Misal setelah  Content-Type: ..” wajib ada satu baris kosong.  Lalu penanganan error (error 400, 500 dst). Anehnya jarang yang membahas ini, mungkin karena mayoritas menggunakan library seperti Flask? 

Berikut code untuk menyimpan lokasi:

#!/usr/bin/python3

# contoh cara penggunaan:  http://xxxyyy.co.id/updatelokasi.py?tag=yw&userid=123&lat=2.343434&long=1.2423424

import cgi, cgitb
cgitb.enable()

import MySQLdb

form = cgi.FieldStorage()

tag = form.getvalue('tag')
userid = form.getvalue('userid')
lat = form.getvalue('lat')
long = form.getvalue('long')

if (tag==None) or (userid==None) or (lat==None) or (long==None) :
   print ("Status: 400 Bad Request")
   print ("Content-Type: application/json\n")
   print ('{"status":"error parameter tidak lengkap, paramter yg valid adalah userid,tag,lat dan long"}')
   print("")
else:
   tag = cgi.escape(tag)
   #print (tag+":"+userid+":"+lat+":"+long)
   db = MySQLdb.connect("localhost","mobprog","mobprogpass","mobprog" )
   cursor = db.cursor()
   sql ="insert into lokasiuser (tag, userid, latitude, longitude) values (%s,%s,%s,%s)";
   try:
      cursor.execute(sql,(tag,userid,lat,long))
      db.commit()
      print ("Status: 200 OK")
      print ("Content-Type: application/json\n")
      print ('{"status":"OK"}')
      print("")
   except:
      db.rollback()
      print ("Status: 500 Internal Error")
      print ("Content-Type: application/json\n")
      print ('{"status":"Error di server, kontak yudi@upi.edu"}')
      print("")

   db.close()

Sedangkan code untuk mengambil lokasi:

#!/usr/bin/python3

# contoh cara penggunaan: http://xxxyyy.co.id/getlokasi.py?tag=yw&userid=123

import cgi, cgitb
cgitb.enable()

import MySQLdb
import json

form = cgi.FieldStorage()

tag = form.getvalue('tag')
userid = form.getvalue('userid')

if (tag==None) or (userid==None) :
   print ("Status: 400 Bad Request")
   print ("Content-Type: application/json\n")
   print ('{"error":"parameter tidak lengkap, paramter yg valid adalah userid dan tag"}')
   print("")
else:
   tag = cgi.escape(tag)
   #print (tag+":"+userid+":"+lat+":"+long)
   db = MySQLdb.connect("localhost","mobprog","mobprogpass","mobprog" )
   cursor = db.cursor()
   sql =" select timestamp, latitude, longitude  from lokasiuser where userid = %s and tag = %s ORDER BY timestamp DESC LIMIT 1"
   try:
      cursor.execute(sql,(userid,tag))
      results = cursor.fetchall()
      #harusnya cuma satu rec
      isAda = False
      for row in results:
         timestamp  = None
         timestamp  = row[0]
         latitude   = row[1]
         longitude  = row[2]
         response={"timestamp":timestamp.isoformat(),"latitude":latitude,"longitude":longitude}
         body = json.dumps(response)
         print ("Status: 200 OK")
         print ("Content-Type: application/json\n")
         print(body)
         print("")
         isAda = True
       #endfor
      if not(isAda) :
         print ("Status: 400 Bad Request")
         print ("Content-Type: application/json\n")
         print ('{"error":"userid atau tag tidak ditemukan"}')
         print("")

   except:
      print ("Status: 500 Internal Error");
      print("Content-Type: text/html\n")
      print('{"error":"server error, kontak yudi@upi.edu"}')
      print("")
   db.close()

 

 

Tutorial Weka Berbahasa Indonesia

28 March 2017 at 08:29 | Posted in Uncategorized | 1 Comment

Weka digunakan pada kuliah Datamining di ilkom UPI. Alasan utama sih karena gratis, open source, dan menggunakan Java sehingga mudah digunakan sebagai library kalau saya membuat program dengan Java (walaupun perlu hati-hati dengan lisensinya yang GPL).

Saya sudah membuat tutorial singkat Weka di:

https://docs.google.com/document/d/12aX-41KJtNqOVo_78ZUzqJGjZbKweZCJAuZgvhZY808/edit?usp=sharing

Lisensinya creative commons jadi bebas digunakan bahkan dimodifkasi, asal nama saya tidak hilang 🙂  Kalau mau format lain (pdf, doc) tinggal pilih File –> Download as.

Cakupan materinya masih terbatas: klasifikasi, clustering, freq itemset mining. Rencananya akan saya tambah pelan-pelan. JIka ada yang mau menyumbang materi  lebih bagus lagi 🙂

Mengapa memilih sekolah favorit?

24 March 2017 at 22:25 | Posted in keluarga, Uncategorized | Leave a comment

Setiap awal penerimaan siswa baru, isu ini selalu muncul. Ada usaha untuk menghilangkan label sekolah favorit, ada juga yang ingin mempertahankan. Saya bukan ahli bidang ini, jadi saya hanya membahas pengalaman saya dan anak.

Saya sendiri masuk SD dengan kualitas yang termasuk rendah, dengan separuh lulusannya tidak melanjutkan ke SMP (putus sekolah). Masuk SMP yang sekarang terbaik di kabupaten Bandung, SMA terbaik di Kota Bandung dan akhirnya masuk prodi dengan passing grade tertinggi se Indonesia.

Menurut saya, yang membedakan sekolah favorit adalah siswanya. Biasanya siswanya punya karakter rajin, pintar (atau keduanya) dan punya motivasi berprestasi tinggi. Alumninya lebih sukses karena hal ini memang penting saat dewasa nanti.

Keuntungan memilih sekolah favorit?  suasana yang lebih kompetitif. Istilah di atas langit ada langit akan terasa sekali. Lebih terpacu untuk lebih baik lagi. Sekolah favorit juga biasanya memiliki siswa bermasalah lebih sedikit.

Kelemahan memilih sekolah favorit?  suasana yang kompetitif kadang menekan, apalagi di masa remaja yang kepribadiannya belum matang.  Siswanya juga lebih individualistis, soft skill seperti kemampuan kerjasama, empati jadi kurang berkembang.  Masalah yang lain adalah semakin tingginya siswa yang masuk secara curang .  Siswa yang masuk dengan cara curang biasanya punya karakter yang berbeda, dan jika jumlahya terlalu banyak justru menghilangkan keunggulan utama sekolah favorit.

Masalah kecurangan ini terus terang membuat saya jauh lebih khawatir saat anak mengikuti penerimaan siswa baru di tingkat SMP dan SMA dibandingkan perguruan tinggi. Anak saya harus bekerja lebih keras untuk bersaing dengan anak lain yang menghalalkan berbagai cara. Di perguruan tinggi untungnya masalah ini relatif  tidak ada, kalaupun ada yang masuk dengan cara curang banyak yang kena drop out di tahun-tahun awal. Bisa jadi pelajaran bagi para ortu yang menghalalkan segala cara.

Berdasarkan pengalaman saya pribadi, beberapa hal yang saya terapkan pada anak:

  1. SD: fokus lebih pada bermain. Jadi cari SD yang tidak perlu kompetitif,  santai dan bisa dicapai dengan jalan kaki. Karena anak saya anak tunggal, kami berusaha agar sebanyak dan sesering mungkin temannya main ke rumah. Untuk memperkuat materi pelajaran, terutama matematika yang sangat penting untuk dasar, kami ikutkan dia dibeberapa les (sempoa, sakamoto, bahasa Inggris, drum). Les bisa disesuaikan waktu, tempat, guru jadi bebannya bisa diatur.
  2. SMP:  pada tahap ini anak sudah diberi kebebasan untuk memilih sekolah. Saya cuma menyampaikan bahwa target akhir yang perlu diincar adalah prodi terbaik se Indonesia (apapun prodinya), oleh karena itu perlu pertimbangan yang matang juga. Saya tidak mau anak mengincar SMP terbaik, karena menurut saya di masa SMP anak masih dalam tahap bermain (walaupun tidak sebanyak SD). Tapi belajar dari saya yang terseok-seok saat SMA, maka perlu dicari SMP yang kualitasnya bagus. Anak juga didorong untuk aktif dalam berbagai organisasi. Les hanya ikut di kelas 3, untuk mencegah kelelahan.
  3. SMA:  sudah mulai perlu serius dan cari SMA terbaik di kota Bandung. Saya tetap mendorong anak untuk berorganisasi (sayangnya kurang berhasil). Anak saya sekarang di tahap ini.
  4. Perguruan tinggi,  apapun jurusannya, sebaiknya yang  terbaik di tingkat nasional. Jurusannya sendiri saya bebaskan. Untuk alternatif kuliah di luar negeri, saya lebih suka nanti saja saat S2, walaupun  memang kalau anaknya mau ya silahkan saja. Masalahnya kepribadian anak belum matang sampai lulus S1, masih gampang dipengaruhi lingkungan.

Khusus untuk tingkat perguruan tinggi,  perguruan tinggi favorit juga punya kelebihan dari sisi jejaring alumni.

Part of Speech Tagger dan Dependency Parser Bahasa Indonesia: Syntaxnet

4 March 2017 at 14:42 | Posted in bahasa indonesia, penelitian, text processing | 6 Comments

Fungsi POS Tagger adalah memberi label jenis kata (kata benda, kata kerja dst), sedangkan dependency parser berfungsi mencari struktur tata bahasa seperti subyek, obyek dan keterkaitan antar kata (parent dan child yang bergantung pada parent).  POS tagger dan dependency parser berguna untuk banyak task NLP.

POS Tagger bahasa Indonesia masih belum banyak dan kalaupun ada lisensinya masih kurang jelas. Saya hanya menemukan dua, yang pertama dari UI http://bahasa.cs.ui.ac.id/postag/tagger  dengan lisensi creative commons (agak aneh karena setahu saya creative commons bukan untuk source code) dan lainnya INANLP dari ITB tetapi tidak tersedia bebas source code-nya (cmiiw). Lisensi ini jadi penting jika kita ingin membuat software yang komersial. Untuk dependency parser Bahasa Indonesia saya belum menemukannya.

Saat saya mempelajari Tensorflow, saya melihat library Syntaxnet yang menggunakan Tensorflow untuk POS Tagger dan dependency parser, dan ternyata sudah ada parser untuk Bahasa Indonesia. Sudah ada pretrained model  sehingga tidak perlu lagi mencari data dan melakukan training lagi. Lisensinya juga Apache 2.0 yang sangat longgar. Berikut proses instalasinya.

Pertama siapkan Linux dan install Tensorflow, terutama yang penting bagian persiapan terkait software pendukung GPU-nya (posting saya tentang menginstall tensorflow). Mungkin sebenarnya setelah persiapan  GPU, bisa saja langsung install Syntaxnet karena syntaxnet mengcompile ulang source, tapi untuk amannya, install saja keseluruhan Tensorflow.  Selanjutnya  ikuti petunjuk instalasi Syntaxnet  yang ada di: https://github.com/tensorflow/models/tree/master/syntaxnet#installation

Prosesnya cukup lama (2-3 jam)untuk menginstall Syntaxnet ini dari source code, termasuk mencompile core tensorflow lagi. Padahal saya sudah menginstall tensorflow sebelumnya. Lalu ada beberapa peringatan tentang SS3, AVX dst,  yang saya tidak tahu harus diset dimana. Waktu install Tensorflow sebelumnya, warning tersebut hilang setelah saya intsall dari source bukan binary.

Untuk mencoba  apakah instalasi berhasil, masuk ke direktori /models/syntaxnet lalu jalankan:

echo 'Rudi is eating the rice.' | sudo sh syntaxnet/demo.sh
Hasilnya:
+-- Rudi NNP nsubj
 +-- is VBZ aux
 +-- rice NN dobj
 | +-- the DT det
 +-- . . punct

Berikutnya kita akan meload pretrained untuk bahasa Indonesia, penjelasannya ada di:

https://github.com/tensorflow/models/blob/master/syntaxnet/g3doc/universal.md

Download model Bahasa Indonesia di:

http://download.tensorflow.org/models/parsey_universal/Indonesian.zip

Ekstrak  zip tersebut (kalau saya ekstrak di /models)

Untuk menjalankan parser, masuk ke direktori syntaxnet, lalu masukan perintah. Pastikan tidak ada slash setelah direktori model bahasa Indonesia ( ~/models/Indonesian bukan ~/models/Indonesian/ )

echo 'Budi makan nasi enak sekali' | sudo sh syntaxnet/models/parsey_universal/parse.sh ~/models/Indonesian

Maka hasilnya

1 Budi _ PROPN _ fPOS=PROPN++ 2 nsubj _ _
2 makan _ VERB _ fPOS=VERB++ 0 ROOT _ _
3 nasi _ NOUN _ fPOS=NOUN++ 2 dobj _ _
4 enak _ ADJ _ fPOS=ADJ++ 3 amod _ _
5 sekali _ ADV _ fPOS=ADV++ 4 advmod _

PROPN adalah proper noun, ADJ adalah adjective dst.

Sedangkan hasil dependency parser dapat dibaca: “makan” adalah ROOT dengan parent 0, “Budi” adalah subyek (nsubj) dengan parent no 2 (“makan”) dst.  Jika digambarkan dependency treenya adalah sbb.

budi_makan_nasi

Mencoba Tensorflow

26 February 2017 at 16:58 | Posted in penelitian | Leave a comment

Bagi yang pemula yang ingin menginstall tensorflow dengan gampang, ini tutorial yang saya buat: http://yudiwibisono.staf.upi.edu/2017/06/03/install-ubuntutensorflowkeras/

Update Nov 2017:
Sekarang tensorflow dengan GPU bisa diinstall dengan lebih mudah, tidak perlu compile source lagi. Setelah driver nvidia, cuda dan cudnn diinstall (cudnn-nya versi 6), maka tinggal panggil pip3 install tensorflow-gpu.

 

Update Mei 2017:

Akhirnya beli PC sendiri, niatnya akhir pekan digunakan oleh anak untuk main game, sisanya untuk saya eksperimen 🙂 GTX1060 6GB, memori 32GB, core i7 6700.  Sebenarnya lebih ideal GTX1070 yang 8GB atau 1080, tapi harganya hampir dua kali lipat dari 1060.  Sempat bermasalah saat install karena chipset tidak dikenali dan menyebabkan monitor blank (tip: edit grub.cfg, tambahkan opsi nomodeset).  Lalu setelah diinstall Ubuntu eh terus nyelonong ke Windows 10 (Grub tidak dipanggil). Bisa diperbaiki dengan boot-repair lalu grub update.  Terakhir ternyata ukuran partisi swap yang dibuat 32GB!  padahal saya cuma beri ukuran 50GB untuk Ubuntu karena ukuran HD SSD terbatas. Ini ternyata gampang diatur ulang dengan GParted. Lumayan repot untuk saya yang awam Linux.

Untuk pengingat masalah saat install Tensorflow:

  • Saat install Cuda Toolkit, gunakan versi deb jangan local file. Jika menggunakan local file efeknya harus matikan x-server dst yang lebih ribet.
  • Cara update driver GPU NVIDIA yang lebih mudah di Ubuntu adalah dengan masuk System Setting ; Software and Updates ; tab Additional Driver lalu pilih NVDIA binary driver. Tidak perlu dengan apt-get install nvidia-375 lagi.
  • Terbentur saat install CuDNN lagi 😦  kurang jelas ternyata posting blog ini.  Jadi di situs cuDNN saat pilih CuDNN versi 5.1, ada tiga file yang perlu di download: cuDNN v5.1 Library for Linux,  cuDNN v5.1 Runtime Library for Ubuntu14.04 (Deb), cuDNN v5.1 Developer Library for Ubuntu14.04 (Deb). Hati-hati jangan pilih yang Power 8, walaupun untuk Ubuntu 16.04 tapi arsitekturnya berbeda (bukan arm64).  Untuk file library for linux, formatnya .tar, ekstrak lalu berdasarkan direktorinya copy ke /usr/local/cuda-8.0/include dan /usr/local/cuda-8.0/lib64. Gunakan sudo cp -P agar symlinknya ikut tercopy(?).  Untuk runtime lib dan dev lib formatnya .deb, install dengan dpkg. Mungkin ini dapat dipilih salah satu? atau bahkan mungkin malah tidak perlu? Nanti kapan-kapan saya coba deh.

–end update–

Catatan: update ini tdk berlaku lagi, lihat update Mei di atas.

Update Mar 2017: karena di lab ada PC dengan GPU GTX980, maka saya mencoba untuk menginstall Tensorflow dengan GPU.  Perlu beberapa kali baru berhasil. Kesalahan pertama, saya belum update driver GPU dengan yang versi terakhir (375) agar bisa jalan dengan Cuda8. Cara update driver, masuk mode tty (ctrl-alt-F1)  lalu:

  1. Run sudo apt-get purge nvidia-*  
  2. Run sudo add-apt-repository ppa:graphics-drivers/ppa lalu sudo apt-get update.
  3. Run sudo apt-get install nvidia-375.

Sumber: http://askubuntu.com/questions/760934/graphics-issues-after-while-installing-ubuntu-16-04-16-10-with-nvidia-graphics 

Tadinya saya coba menggunkan installer dari web NVIDIA dan gagal total.

Kesalahan kedua: saat instal CudaDNN (lib cuda untuk neural net), tadinya saya ikuti petunjuk yang ada di situs Tensorflow, dan gagal. Ternyata yang harus dilakukan adalah mendownload versi linux (tar) dan versi ubuntu (deb). Lalu ekstrak ke lokasi cuda diinstall di dalam /header dan /lib64   (baca http://askubuntu.com/questions/767269/how-can-i-install-cudnn-on-ubuntu-16-04/767270)

— end update —

Tensorflow adalah library untuk deep learning (neural net dengan banyak layer dan bermacam topologi) yang dikembangkan Google dan dijadikan open source. Saya tertarik mencoba Tensorflow karena memerlukan library sequence to sequence untuk di NLP. Library buatan perusahaan besar seperti Google enaknya adalah dokumentasi lengkap, fitur lengkap dan kalau ada bug cepat ditangani (yang mengerjakannya pegawai yang digaji, bukan proyek sampingan sih 🙂 )

Walaupun bisa diinstall di  Windows, Tensorflow dari awal ditujukan untuk Unix. Karena pernah punya pengalaman jelek install Python di Windows, maka saya akan coba di Linux. Idealnya sih menyiapkan komputer yang punya GPU bagus dengan OS Linux,  tapi karena saya masih menggunakan Windows, maka saya menggunakan VMWare + Ubuntu saja.

Petunjuk instalasi lengkap dan mudah untuk diikuti (saya termasuk awam Linux). Saya coba berhasil tapi lalu bermunculan berbagai warning:

The TensorFlow library wasn’t compiled to use SSE3 instructions, but these are available on your machine and could speed up CPU computations.

The TensorFlow library wasn’t compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations … dst

Setelah saya baca, warning ini bisa dihilangkan dengan cara menginstall lansung dari source dan bisa mempercepat sampai tiga kali lipat. Saya kemudian coba install dari source, tidak ada masalah, hanya lumayan lama saat build. Lalu sempat kebingunan cari bazel-bin, ternyata ada di dalam direktori tensorflownya dan pada saat pip install, nama file whl-nya tidak sama persis dengan tutorial, bergantung pada konfigurasi yang kita tentukan.  Nanti tulisan ini akan saya lanjutkan sejalan dengan eksplorasi  Tensorflow ini 🙂

Untuk editor Python, saya sempat cari-cari, dan ternyata JetBrains punya editor PyCharm. Bagi saya yang sudah terbiasa dengan produk JetBrains Android Studio dan IntelliJ, tentu lebih nyaman menggunakan PyCharm ini.

  • Setelah lancar di contoh-contoh awal, akhirnya kena error saat menjalankan contoh tf.contrib.learn, beberapa warning tepatnya, tapi hasilnya tidak muncul. “WARNING:tensorflow:Rank of input Tensor (1) should be the same as output_rank (2) for column. …. WARNING:tensorflow:From ….; scalar_summary (from tensorflow.python.ops.logging_ops) is deprecated  …  Update: hasilnya muncul, harus tambahkan print ternyata. Cuma warning tetap keluar, tidak tahu kenapa.
  • Ternyata saat menggunakan GPU, maka yang digunakan memori GPU bukan CPU. GTX980 yang punya memori 4GB ternyata pas-pasan. Perlu dipikirkan upgrade ke GTX1080 atau minimal GTX1060 . Salah pesan kemarin, harusnya memori PC tidak perlu terlalu besar, yang penting GPU-nya sebaik mungkin. Update: ternyata penggunaan memori saat training (task machine translation) sampai 25GB, artinya memori 32GB berguna juga. CPU usage tidak terlalu tinggi. Load avg 1.5 untuk 6 cores artinya hanya sekitar sepertiga CPU yang digunakan.

Mengisi Database App saat Instalasi

22 February 2017 at 21:26 | Posted in android, Uncategorized | Leave a comment

— Catatan: Sebenarnya saya biasa posting tentang Android dev di blog yang lain (indonesiaberkicau.com), tapi hosting Qwords terlalu sering bermasalah (situs tidak merespon). Saya sudah upgrade ke paket yang lebih tinggi tapi tetap bermasalah, mau upgrade lagi apa ada jaminan bakal lancar? Informasi penyebab situs mati juga tidak ada (habis resources yang mana?). Oleh karena itu saya akan pindahkan ke blog ini saja — end

Pada aplikasi yang sedang saya buat, saya ingin agar database terisi saat user selesai menginstall app. Cara yang paling sederhana dengan mengisi satu persatu data di method SQLiteOpenHelper.onCreate(SQLiteDatabase) dengan query insert, tapi tidak praktis untuk data yang cukup banyak. Cara yang lain adalah membuat database di luar, diletakkan di assets lalu file database ini dicopy. Harusnya ini yang paling cepat, karena langsung copy antar file dan tidak melibatkan database. Cuma setelah saya coba, selalu gagal, dan ada resiko jika struktur database yang digunakan Android berganti.

Solusi yang saya gunakan adalah membuat file JSON lalu diletakkan di direktori assets kemudian diparsing dan diinsert.  Contoh JSON-nya seperti ini:

[
   {
     "nama": "resto A",
     "alamat": "sarijadi blok 23",
     "telp": "08162424"
   },
   {
     "nama": "resto B",
     "alamat": "buahbatu",
     "telp": "0832324"
   }
]

Simpan sebagai file teks, letakkan di direktori assets (…\app\src\main\assets).

Code berikut memparse data ini dan memindahkannya ke tabel. Transaction diatur manual agar kinerja lebih optimal (cuma belum saya test). Untuk data yang besar, sebaiknya proses load ini dilakukan di thread yang terpisah.

public static final String TABLE_INSERT = "insert into tempat_makan (nama, telepon, alamat) values(?,?,?)";
private static String DATA_FILE = "data.txt";
private void loadData(SQLiteDatabase db) {
    try {
        InputStream myInput  = myContext.getAssets().open(DATA_FILE);
        String jsonStr = getStringFromInputStream(myInput);
        SQLiteStatement insert = db.compileStatement(TABLE_INSERT);
        db.beginTransaction();
        JSONArray jArr = new JSONArray(jsonStr); //karena dimulai dgn array
        for (int i=0; i < jArr.length(); i++)
        {
            JSONObject jObj = jArr.getJSONObject(i);

            String nama      = jObj.getString("nama");
            String alamat    = jObj.getString("alamat");
            String telp      = jObj.getString("telp");

            insert.bindString(1,nama);
            insert.bindString(2,alamat);
            insert.bindString(3,telp);
            insert.execute();
        }
        db.setTransactionSuccessful();
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("yw",e.getMessage());
    } finally {
        db.endTransaction();
    }
}

// convert InputStream to String
private static String getStringFromInputStream(InputStream is) {
    BufferedReader br = null;
    StringBuilder sb = new StringBuilder();

    String line;
    try {

        br = new BufferedReader(new InputStreamReader(is));
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return sb.toString();
}

Next Page »

Blog at WordPress.com.
Entries and comments feeds.