Using Email with Google App Engine

สวัสดีครับ วันนี้อยากแนะนำ cloud ของ google (ไม่ได้เงินค่าโฆษณาแต่อย่างใด) สำหรับใครที่มองหา Server ฟรีสำหรับทำโปรเจคส่งอาจารย์ เช่น โปรเจคเกี่ยวกับ IoT (Internet of Things) ถ้าเงินไม่มีแนะนำ Google App Engine ครับฟรีถึงแม้โควต้าจะไม่เยอะเท่าไหร่แต่ก็ทำให้ได้ Server ดีๆ ได้เลยทีเดียว ลองเข้าไปศึกษากันได้ที่ Google Cloud Platform

สำหรับ Google App Engine รองรับหลายภาษาไม่ว่าจะเป็น Python Java PHP และ Go (ซึ่งในที่นี้ผมถนัด Python นะบอกเลย–น่าจะเดาได้จากหลายๆ โพสที่ผ่านมา) สำหรับฐานข้อมูลนั้นไม่ได้มี MySQL หรือ MongoDB ที่หลายคนถนัดต้องใช้ App Engine Datastore ซึ่งมีโควต้านับเป็นจำนวนครั้งในการอ่านเขียน และโควต้าของ GAE นั้นนับเป็นวันครับ ถ้าวันนั้นใช้เกินโควต้าเว็บหรือเซอร์วิสที่เราพัฒนาจะไม่สามารถเข้าใช้งานได้ ก็รอไปจนครบ 24 ชม (ระหว่างนั้นก็ไปช้อปปิ้ง เล่นเกม) แล้วระบบจะรีเซ็ทให้เหลือศูนย์ใหม่ แล้วก็จะเข้าเว็บได้เหมือนเดิม เหมาะสำหรับผู้ริเริ่มอะไรใหม่ๆ

วันนี้จะแนะนำการใช้เซอร์วิส Email ของ GAE นะครับ นอกจากจะโฮสเว็บได้แล้วยังมีระบบรับส่งอีเมล์ให้เราได้ใช้อีกด้วย สำหรับโค้ดสามารถหาได้จาก SimpleEmailGAE ซึ่งผมเขียนไว้เองแหละ ผู้อ่านสามารถเอาไปต่อยอดไปศึกษา (เดา) จากโค้ดกันได้แน่นอน โค้ดไม่ได้ซับซ้อนมาก โดยการทำงานของโค้ดคือเมื่อส่งเมล์เข้าเมล์ของแอพนั้น จะทำการส่งเมล์ตอบกลับมาก็เท่านั้นเอง ที่สำคัญคือในไฟล์ app.yaml ใน section handlers ห้ามสลับลำดับมั่วนะครับ เดี๋ยวมันจะทำงานผิด แล้วก็ต้องไปเปลี่ยน sender ในไฟล์ handle_incoming_email.py ให้ตรงกับชื่อแอพที่ลงทะเบียนไว้ด้วยนะครับ

นอกจากนั้น GAE ยังอำนวยความสะดวกให้เราได้โดยที่เราสามารถรัน server แบบ localhost (page – localhost:8080 และ admin panel – localhost:8000) ใน Admin panel สามารถส่งเมล์ ดูข้อมูลที่เราเก็บไว้ใน Datastore และดู log ที่เกิดขึ้นได้ สำหรับการส่งอีเมล์ต้องตั้งค่า SMTP ก่อนถึงจะส่งจาก localhost ได้แต่บน GAE ไม่ต้องตั้งค่าก็ใช้งานได้เลย เมื่อทดสอบได้แล้วก็ลองนำไป Deploy บน GAE ได้เลย

Graphviz with Python

นี่ก็สิ้นเดือนอีกแล้วนะครับ ยังไม่ได้ไปหาเนื้อหาใหม่มาเขียนเลย แต่เนื่องจากตั้งใจไว้ว่าทุกเดือนต้องเขียนอย่างน้อยหนึ่งบทความ วันนี้เลยจะมาเสนอ Tool สำหรับวาดกราฟบน Python สำหรับคนที่จะนำไปทำเขียนเปเปอร์หรืออยากให้โปรแกรมแสดงผลเป็นกราฟนะครับ

Tool ที่จะมานำเสนอชื่อ Graphviz ครับซึ่งสามารถติดตั้งได้โดยคำสั่งข้างล่างนี้ (สำหรับระบบปฎิบัติการ Debian นะครับ)

$ sudo apt-get install graphviz
$ sudo pip install graphviz

สำหรับการใช้งานนะครับ ก็ทำการ import ในโค้ด Python ของเราได้เลย นี่คือตัวอย่างโค้ด

import graphviz as gv

graph = gv.Digraph(format="jpg")
graph.attr('graph',{'rankdir':'LR','splines':'ortho'})

layer = [7,6,5,3,3]
layer_name = ['input', 'L1 AE', 'L2 AE', 'L3 AE', 'output']

# init node
layers = []
for layer_id in range(len(layer)):
        layers.append([])
        subgraph = gv.Digraph(name="cluster%d" % (layer_id))
        subgraph.attr('graph', {'label':layer_name[layer_id]})
        
        for node_id in range(layer[layer_id]):
                node_name = 'L_%d_%d' % (layer_id, node_id)
                layers[layer_id].append(node_name)
                subgraph.node(node_name, label='')
        graph.subgraph(subgraph)

# init full-connected edges
for layer_id in range(len(layer)-2):
        for node_source in layers[layer_id]:
               for node_sink in layers[layer_id+1]:
                        graph.edge(node_source, node_sink)

# final layer
for node_id in range(3):
        graph.edge('L_3_%d' % (node_id), 'L_4_%d' % (node_id))

filename = graph.render(filename='img/neural_net')
print filename

และนี่คือตัวอย่างของภาพที่ได้จากการรันโค้ดข้างบนครับ

Neural Network Structure

Neural Network Structure

การทำงานของโปรแกรมจะทำงานโดยสร้างไฟล์ชนิด dot ขึ้นมาจากนั้นแปลงไฟล์ dot ให้เป็นไฟล์ภาพ เพราะฉะนั้นถ้าอยากได้กราฟที่สวยหรูกว่านี้ต้องลองดู property ต่างๆ จาก link นี้ได้เลยครับ

Easy Panorama with OpenCV

ห่างหายจากการเขียนบล็อคไปนาน เพราะมีภารกิจที่หลายอย่างที่ต้องทำนะครับ จากตอนแรกคิดว่าจะเขียนเดือนละครั้ง เดือนที่แล้วก้ได้พลาดไปอย่างน่าเสียดาย ตอนนี้ก็ใกล้สิ้นเดือนแล้วจึงมาเขียนโพสสั้นๆ เกี่ยวกับการทำภาพพาโนราม่าด้วย OpenCV ไลบรารี่

เริ่มจากอย่างแรกต้องลง OpenCV Library (2.4.8) ก่อนละครับ ซึ่งในที่นี้จะเป็นการ install สำหรับ Ubuntu โดยใช้คำสั่งตามนี้ครับ

$ sudo apt-get install libopencv-dev build-essential

จากนั้นก้โหลดโค้ด (stitching.cpp) และภาพ dataset จาก link นี้นะครับ โดยต้องโหลด CMakeLists.txt มาด้วยเพื่อช่วยให้การ build โปรแกรมง่ายขึ้น โดยใช้คำสั่งข้างล่างนี้

$ cmake . && make

เพื่อตรวจสอบว่าโปรแกรมที่ build มานั้นทำงานได้หรือไม่ทำได้โดยการพิมพ์ ./stitching จากนั้นตัวโปรแกรมจะฟ้องให้ใส่ input images เข้าไปครับ เราก็สามารถใส่ภาพที่เตรียมไว้ให้เข้าไปได้โดยใช้คำสั่งดังนี้

$ ./stitching 1.jpg 2.jpg 3.jpg

จากนั้นเราก้จะได้ภาพพาโนราม่าสวยๆ ในไฟล์ result.jpg ตามข้างล่างนี้ครับ

Panorama 1

Panorama 1

Panorama 2

Panorama 2

Kasetsart University

Kasetsart University

ขอขอบคุณภาพจาก P. MONGKOLPITTAYATHORN, NOPPON UMNAJWANNAPHAN

Create Bash-script service for Debian

ในบางครั้ง เราต้องการให้โปรแกรมที่เราเขียนขึ้นรันเมื่อเปิดเครื่องคอมพิวเตอร์ขึ้นมา และใน Debian นั้นสามารถทำได้หลายวิธี ไม่ว่าจะเป็นการสั่งให้เรียกโปรแกรมจากไฟล์ crontab หรือ rc.local ซึ่งในวันนี้จะเสนอวิธีที่นำโปรแกรมมาสร้างเป็น Bash-script แล้วนำไปผูกกับ service ของระบบปฎิบัติการ Debian

การสร้าง Bash-script แล้วจึงนำไปถูกกับ Service มีข้อดีคือ เราสามารถสั่งเปิดปิดโปรแกรมของเรา รวมถึง restart ได้ผ่านทางระบบ service ของ Debian ได้นั่นเอง ซึ่งนี่คือตัวอย่างของวิธีการดังกล่าว PiCam-Setup เป็นการสร้าง Service ในการเปิดกล้องให้กับ Raspberry Pi โดยใช้ไลบรารี่ mpeg-streamer

มาเริ่มกันเลยดีกว่า อย่างแรกที่ต้องมีคือโปรแกรมที่อยากให้ทำงานก่อนในที่ใช้โปรแกรม my_program.py จากนั้นเขียนไฟล์ Bash-script ดังนี้

#!/bin/bash
# /etc/init.d/MyService.sh

function startService()
{
    ./my_program.py &
}

case "$1" in
    start)
        echo "Starting my_program.py"
        startService
        ;;
    stop)
        echo "Stopping my_program.py"
        killall my_program.py
        ;;
    status)
        echo "Not supported yet"
        ;;
    restart)
        echo "Restarting my_program.py"
        killall my_program.py
        start
        sleep 2
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac
exit 0

จากนั้น เราต้องก็อปปี้สคริปข้างบนไปไว้ /etc/init.d/ จากนั้นก้ update-rc.d ตามคำสั่งดังนี้

# cp MyService.sh /etc/init.d/
# chmod +x /etc/init.d/MyService.sh
# update-rc.d MyService.sh defaults

เพียงเท่านี้เราก้จะได้เซอร์วิสที่เป็นของเราเองแล้วครับ

Deep learning with Autoencoder

In past 10 years, machine learning is the most attractive subject, especially deep learning. Deep learning is the novel method to understand what ours brain think and percept. It begins in 1959, researchers found that cat’s brain can recognize picture by extract edges first, then lines, then surfaces, and objects. From this hypothesis, machine learning researchers adapt this idea to theirs algorithm and made its similar to real brain. At this time, there are several hardware that provide for deep learning algorithm, such as, Nervana Systems and Drive Px.

I am one of students that interested in this area, so I search for material to learn and practice about deep learning. And I found Machine Learning course from Coursera for beginner and deep learning website for expert. From a lot of articles about deep learning, I selected UFLDL tutorial to begin studying. First, I am not being expert in MATLAB that suggests in this tutorial. So I decide to use Theano python library which is my frequent programming language.

Autoencoder is the simple technique which I chose. Because it is easy to understand and can solve by simple neural network algorithm. Code of autoencoder that follows tutorial, neural network with regularization and sparsity penalty, is given.(https://github.com/chaiso-krit/autoencoder) Dataset that used in this code are 8×8 patch images and come from whiten images, provided by tutorial.

After running code for ~20 minutes, it will show what feature that autoencoder recognize, similar to following picture.

Autoencoder recognized feature

Compile kernel 3.x for mini2440

จากคราวที่แล้วที่ได้นำเสนอการ compile U-Boot ไป ซึ่งเป็นแค่ boot loader เท่านั้น ยังไม่สามารถใช้งาน linux บน mini2440 ได้ เราจำเป็นจะต้องมี kernel ซึ่งเป็นระบบปฎิบัติการในการใช้งานต่อไป ซึ่งเราสามารถทำการ compile kernel ได้ตาม link นี้ และต่อจากนั้นเราจำเป็นจะต้องมี root file system ซึ่งจะมี configuration สำหรับการ boot อยู่ โดยเราสามารถสร้างโดยใช้ Debootstrap ซึ่งสามารถทำได้ตาม link นี้ แต่ release เป็น version เก่า (lenny) ซึ่งผมแนะนำให้เปลี่ยนเป็น wheezy เพื่อความทันสมัย

เมื่อเราเปลี่ยน root file system ให้ทันสมัยแล้ว การ compile kernel ที่นำเสนอไปก่อนหน้า จะไม่สามารถใช้ได้ โดยเมื่อนำไปใช้จะเกิดปัญหาดังนี้

udevd[xxx]: unable to receive ctrl connection: Function not implemented

และเมื่อค้นลึกลงไป ปรากฎว่า version ของ kernel เก่าไปนิดเดียวเอง ของตามที่นำเสนอเป็น 2.6.32 แต่ฟังก์ชันที่ kernel ใหม่เรียกหาอยู่ใน version 2.6.36 ช่างน่าเสียดาย ตอนแรกก้คิดว่าจริงๆ ขยับไป 2.6.36 ก้ได้ แต่เพื่อไม่ให้เกิดปัญหาคล้ายเดิมอีกในอนาคต เราควรจะย้ายไป kernel ใหม่เลย ในที่นี้เลือก 3.10.6 เพราะมีคนบอกว่าใช้ได้

การ compile จำเป็นต้องลง cross-compile ก่อน จากนั้นดาวน์โหลด kernel 3.10.6 จากนั้นแตกไฟล์ และใช้คำสั่งดังนี้

$ mkdir ../kernel-bin
$ CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm make O=../kernel-bin/ mini2440_defconfig

จากนั้น ให้ดาวน์โหลด file นี้ ไปเขียนทับไฟล์ .config ในโฟล์เดอร์ kernel-bin จากนั้นทำการ make ตามคำสั่งด้านล่าง ซึ่ง -j8 คืออนุญาตให้ make แบบขนานได้พร้อมกัน 8 thread

$ CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm make O=../kernel-bin/ -j8

จากนั้นนำไปสร้าง uImage ตามวิธีการ compile kernel ที่นำเสนอไปตอนต้นของโพส ซึ่งสำหรับคนที่ต้องการประหยัดเวลาในส่วนนี้สามารถ นำ image file ซึ่งประกอบด้วย kernel และ root file system โดยขอเพียงมี SDcard ที่ขนาดตั้งแต่ 4Gb ขึ้นไป จากนั้นใช้คำสั่งดังนี้ ซึ่งเปลี่ยน mmcblk0 ตามชื่อพาร์ติชั่นของ SDcard ของคุณเอง

$ tar -zxvf mini2440_sdcard.img.tar.gz
$ sudo dd bs=4M if=mini2440_sdcard.img of=/dev/mmcblk0

ซึ่งสามารถ ขยายพาร์ติชั่นตามที่อยากได้โดยการใช้โปรแกรม gparted เพียงเท่านี้เราก้จะได้ SDcard สำหรับรัน linux บน FriendlyARM mini2440 ได้แล้ว เห็นมั้ยครับมันลำบากนะครับกว่าจะมาเป็นคอมพิวเตอร์ที่ใช้ง่ายๆในมือคุณ

mini2440 partition

Mini2440 SDcard Partition

Compile U-Boot for mini2440

เดี๋ยวนี้ถ้าพูดถึง Embedded board คงไม่มีใครไม่รู้จัก Raspberry Pi ทั้งใช้ง่ายและสะดวกสบายมาก แต่บางทีชีวิต Programmer ก้อยากมีช่วงลำบากบ้าง วันนี้จึงนำเสนอ Board ที่เก่าหน่อย แล้วก้ทุกอย่างต้อง compile เองเกือบทั้งหมด นั่นคือ FriendlyARM mini2440 ซึ่งหลายๆคนบอกว่า ไม่ Friendly เลย เพื่อไม่ให้เป็นการเสียเวลาเรามาเริ่มกันเลย สำหรับการ compile ครั้งนี้จะทำบน ubuntu นะครับ

Cross-Compile

อย่างแรกที่ต้องมีในการ compile U-Boot คือ cross-compile แค่เริ่มก้เห็นความยากแล้วใช่มั้ยครับ cross-compile คือ การ compile code สำหรับอุปกรณ์อื่นบนเครื่องเราเอง เช่น ใช้เครื่องคอมพิวเตอร์เรา compile code สำหรับ arm แล้วทำไมไม่ compile บน arm เลยหล่ะ ก้อาจจะเพราะว่า arm ช้าจนเกินไป ซึ่งใช้คำสั่งในการติดตั้งดังนี้

$ sudo apt-get install gcc-arm-linux-gnueabi

ลองทดลองได้โดยใช้คำสั่งดังนี้

$ arm-linux-gnueabi-gcc
arm-linux-gnueabi-gcc: fatal error: no input files
compilation terminated.

ซึ่งขึ้นแบบนี้ไม่ต้องกังวลนะครับ หมายถึงใช้ได้

Compile U-Boot

ต่อมาเราจะทำการ compile U-Boot โดยเริ่มต้นจากการ clone repository ของ U-Boot มาก่อน (ซึ่งก้คือ code นั่นเอง) จากนั้นต้องทำการเซ็ค CROSS_COMPILE สุดท้ายก้ทำการ compile ได้โดยใช้คำสั่งดังนี้

$ mkdir ~/uboot && cd ~/uboot
$ git clone git://repo.or.cz/u-boot-openmoko/mini2440.git
$ export CROSS_COMPILE=arm-linux-gnueabi-
$ cd mini2440 && make mini2440_config
$ make

ถ้าสำเร็จ ก้สามารถนำไฟล์ u-boot.bin ไปลงบอร์ด mini2440 ได้ตามวิธีใน link นี้ แต่ของที่ผมทำมันไม่สำเร็จนะครับ โดยขึ้น error ดังนี้

{standard input}: Assembler messages:
{standard input}:22: Error: lo register required -- `ldr ip,[r8,#32]'
{standard input}:23: Error: lo register required -- `ldr pc,[ip,#0]'
...

ซึ่งจากการค้นหาที่มาของภัยพิบัติดังกล่าว พบว่าเราใช้ optimize มากเกินไป จึงต้องแก้ cpu/arm920t/config.mk โดยเพิ่ม -marm ไปดังนี้

PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
        -msoft-float

PLATFORM_CPPFLAGS += -march=armv4t -marm
# ===========================================================

จากนั้นทำการ make ใหม่ครับ เห็นมั้ยครับว่าจุดเริ่มต้นของความสบายมักจะเกิดจากความลำบากนะครับ ถ้าไม่อยากลำบาก compile เองผมมีอันที่ compile ไว้ให้แล้วครับ ตาม link นี้เลย