Friday, May 5, 2017

Hướng dẫn cài đặt Tensorflow GPU trên Ubuntu 17.04

Giới thiệu

Chào mọi người, sau đây mình sẽ hướng dẫn cách cài đặt Tensorflow phiên bản GPU trên Ubuntu. Phần lớn các bài hướng dẫn chi tiết cài đặt Tensorflow GPU đã lỗi thời, khi thực hiện theo sẽ gặp lỗi. Sau khi cài thành công mình quyết định ghi chú ngắn gọn các bước cài đặt.

Cài đặt


1. Cài đặt Cuda:
    Chọn nền tảng tương ứng, download và chạy các lệnh như hướng dẫn để cài đặt.


2. Tiếp tục thực hiện bước 2 và 3 như trong link sau: 
Note: Ở thời điểm hiện tại, trong bước 2 các bạn tải cuDNN v5.1

3. Từ bước 4 trở đi mình không cần phải làm theo hướng dẫn đó nữa, lúc đó ta sẽ làm như sau:
(Python 2.7;  GPU)
$ pip install tensorflow-gpu
$ sudo nano ~/.bashrc
Thêm dòng sau vào cuối file: 
LD_LIBRARY_PATH=/usr/local/cuda/lib64
Và lưu lại: Ctrl + X --> y --> Enter

(Tránh lỗi không tìm thấy thư viện)
$ sudo chmod a+r /usr/local/cuda/lib64/libcudnn*

(Test thử)
$ python
>>> import tensorflow
Note: nếu không hiện thông báo lỗi gì tức bạn đã cài thành công. Chúc mừng nhé!

Tham khảo

Friday, April 28, 2017

Install Ubuntu 17.04

  1. Download Ubuntu 17.04: http://releases.ubuntu.com/17.04/
  2. Burn Ubuntu 17.04 ISO file to USB via this software: http://isotousb.com/
  3. Boot the system with your USB.
  4. Ubuntu shows intsallation wizard.
  5. Installation type: choose "Something else" and continue.
  6. My partition configuration:
    • Mount point: /, Ext4, 400GB, Primary, Beginning of this space
    • Mount point: swap, 8GB
    • Mount point: /home, Ext4, 92GB (the remaining), Primary, Beginning of this space
  7. Continue to configure the remaining items such as timezone, ...
  8. If there are 2 OS, you need to choose the OS (Ubuntu 17.04 or Windows) to proceed.
  9. Welcome to Ubuntu!

Sunday, June 5, 2016

Android studio - NDK - include and use .so library

Compile library (.so)
Create jni and jniLibs folder. The structure of your project would be:

PROJECTNAME
|-app
   |-src
      |-main
         |-jni
         |-jniLibs

Create native code and make files:
PROJECTNAME
|-app
   |-src
      |-main
         |-jni
            |-Android.mk
            |-Application.mk
            |-setenv.c


Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := native  // module name, this name is just an example
LOCAL_SRC_FILES := setenv.c // your C code
include $(BUILD_SHARED_LIBRARY)

Application.mk
APP_ABI := all

APP_BUILD_SCRIPT := Android.mk

setenv.c
#include <jni.h>
#include <stddef.h>
#include <stdlib.h>

JNIEXPORT jint JNICALL Java_hcmut_controller_FcamController_setenv(JNIEnv* env, jclass clazz, jstring key, jstring value, jboolean overwrite)
{
    char* k = (char *) (*env)->GetStringUTFChars(env, key, NULL);
    char* v = (char *) (*env)->GetStringUTFChars(env, value, NULL);
    int err = setenv(k, v, overwrite);
    (*env)->ReleaseStringUTFChars(env, key, k);
    (*env)->ReleaseStringUTFChars(env, value, v);
    return err;

}

* Note: function name in .c code follows the naming convention:
Java_your_package_ClassName_functionname(.......)

PROJECTNAME
|-app
   |-src
      |-main
         |-hcmut
            |-controller
               |-FcamController.java

associated with Java_hcmut_controller_FcamController_setenv

Jump to the folder containing Application.mk file and execute the following command:
$ cd "~/Project/Android/CrowdCounting/app/src/main/jni"
$ ~/android-ndk/ndk-build NDK_APPLICATION_MK=./Application.mk
--> It will compile and create obj folder in the same level with jni folder.


Use library
Copy the folders in obj/local/* to jniLibs
|-app
   |-src
      |-main
         |-jni
         |-jniLibs
            |-arm64-v8a
            |-armeabi
            |-armeabi-v7a
            |-mips
            |-mips64
            |-x86
            |-x86_64

To use the native library, we load the library and declare the library's method
PROJECTNAME
|-app
   |-src
      |-main
         |-hcmut
            |-controller
               |-FcamController.java

FcamController.java
static {
        System.loadLibrary("native");
}
private static native int setenv(String key, String value, boolean overwrite);

* You can check the library whether it is included by opening .apk file with Archive Manager (Linux)


Other way to add library (.so)
Create a .zip file with the structure:
mylib.zip
|-lib
   |-armeabi
      |-libnative.so
   |-armeabi-v7a
      |-libnative.so
   |-x86
      |-libnative.so
    ...

Then change the file type from mylib.zip to mylib.jar

Put mylib.jar in libs folder
PROJECTNAME
|-app
   |-libs
      |-mylib.jar

Modify dependencies in build.gradle
PROJECTNAME
|-app
   |-libs
   |-build.gradle

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.1'
}

References:
https://software.intel.com/en-us/articles/building-an-android-command-line-application-using-the-ndk-build-tools
http://stackoverflow.com/questions/16683775/include-so-library-in-apk-in-android-studio
https://groups.google.com/forum/?fromgroups#!topic/adt-dev/nQobKd2Gl_8

Wednesday, July 22, 2015

[Linux] Phục hồi file, hình ảnh đã xóa trong thẻ nhớ, USB và ổ cứng

Đôi lúc bạn lỡ tay hoặc vô ý xóa mất file, hình ảnh đáng giá lưu trên thẻ nhớ của điện thoại? Không sao! Mình sẽ hướng dẫn bạn cách phục hồi lại chúng trên hệ điều hành Linux. Mình đã thử và thành công.
Bước 0 (quan trọng nhất): khi bạn xóa file, thực chất dữ liệu vẫn còn, chẳng qua những vùng lưu trữ file đã xóa được hệ thống cho phép sử dụng để lưu những file mới, vì vậy những mảnh dữ liệu đã xóa sẽ mất dần => ngưng chép thêm file mới vào thiết bị lưu trữ đó (USB, SD, micro SD, HDD, ...), cố gắng giữ nguyên "hiện trường".
Bước 1: kết nối thiết bị lưu trữ đó với máy tính chạy HĐH Linux (máy tính mình Ubuntu 14.04 LTS)
-- Lưu ý: nếu bạn phục hồi file vừa mới xóa thì dùng TestDisk là đủ (Bước 2->7). Nếu file đã bị xóa cách đây khá lâu thì nên dùng Foremost (bước 8->10). Hoặc bạn có thể thử cả 2 nếu muốn :)
[-TestDisk-]
Bước 2: Cài đặt chương trình TestDisk dùng Terminal (Ctrl + Alt + T)
$ sudo apt-get install testdisk
Bước 3: Chạy photorec
$ photorec
Bước 4: Nhấn enter để tiếp tục. Như trong hình ổ cứng được mount ở đường dẫn /dev/sda (bạn cần nhớ chỗ này để tiện khi dùng chương trình foremost)

Bước 5: Chọn lựa chọn đầu tiên [Whole Disk]
Bước 6: Chọn kiểu của ổ cứng bạn cần phục hồi:
ext2/ext3/ext4 cho ổ cứng trong HĐH Linux
Other (FAT/NTFS/...) cho ổ cứng trong Windows, USB, thẻ nhớ (micro) SD
Bước 7: Chọn thư mục để chứa file sẽ được phục hồi. Thư mục này không nằm trong thiết bị lưu trữ bạn đang muốn phục hồi dữ liệu và còn trống nhiều dung lượng. Dùng phím mũi tên (lên xuống, trái phải) để định vị thư mục mong muốn. Sau đó nhấn phím "C". Đợi ít phút cho tới khi chạy xong!
[-TestDisk-]
[-Foremost-]
Bước 8: Cài đặt Foremost
$ sudo apt-get install foremost
Bước 9: Tạo thư mục chứa file sẽ được phục hồi. Ví dụ thư mục "recovery" nằm trong "Home". Thư mục này phải nằm ngoài thiết bị lưu trữ bạn đang cần phục hồi dữ liệu và còn trống nhiều dung lượng.
$ mkdir ~/recovery
Bước 10: Phục hồi dữ liệu bằng lệnh. Sau đó ngồi chờ, có thể sẽ mất kha khá lâu thời gian.
$ sudo foremost -i /dev/sda -o ~/recovery
-- Lưu ý: lúc mình phục hồi ảnh trong thẻ nhớ ngoài điện thoại (Android), đường dẫn sau "-i" của mình là /dev/sdc , lệnh ở trên là ví dụ mình họa.
[-Foremost-]

* Các file, thư mục sau khi phục hồi sẽ có quyền sở hữu bởi root. Vì vậy ta nên đổi về quyền sở hữu user hiện tại.
1. Terminal gõ
$ whoami
minh (ta sẽ nhận được hồi đáp, ví dụ là "minh")
2. Đổi quyền sở hữu đối với file, thư mục
$ sudo chown minh ~/recovery -R

* Script sắp xếp tất cả các file ảnh trong cùng thư mục theo ngày được chụp ảnh đó (dựa vào thuộc tính "Date Taken")

#!/bin/sh
# Goes through all jpeg files in current directory, grabs date from each
# and sorts them into subdirectories according to the date
# Creates subdirectories corresponding to the dates as necessary.
for fil in *.jpg  # Also try *.JPG
do
    datepath="$(identify -verbose $fil | grep DateTimeOri | awk '{print $2 }' | sed s%:%/%g)"
    if ! test -e "$datepath"; then
        mkdir -pv "$datepath"
    fi
    mv -v $fil $datepath
done

-- Lưu vào file "sort_date_taken.sh" chẳng hạn, bỏ vào thư mục chứa ảnh cần sắp xếp. Dùng terminal chạy script vừa tạo:
$ cd path/to/your/folder
$ sudo sh sort_date_taken.sh

* Nguồn tham khảo:
http://askubuntu.com/questions/31450/tool-for-recovering-deleted-data-from-a-flash-drive
https://help.ubuntu.com/community/DataRecovery
http://www.linuxjournal.com/content/tech-tip-automaticaly-organize-your-photos-date

* Thắc mắc hoặc gặp vấn đề các bạn cứ comment nhé :)

Saturday, December 27, 2014

[Android] Chức năng Leader Board sử dụng Google Play API

* Thêm BaseGameUtils vào project
1. Tải BaseGameUtils về từ link. Hoặc từ link này (khi đó bỏ qua bước 2 và 3)
2. (Eclipse) nhảy đến thư mục android-basic-samples-master trong cmd
3. (Ubuntu) chạy lệnh: bash Scripts/make_eclipse_compat
4. (Eclipse) File > Import... > Existing Android Code Into Workspace > chọn đường dẫn đến eclipse_compat/libraries/BaseGameUtils
5. BaseGameUtils > Properties > Android > Library > tick chọn is Library và thêm reference đến google-play-services_lib

6. Project cần sử dụng BaseGameUtils > Properties > Android > Library > thêm reference đến BaseGameUtils
7. Nếu báo lỗi có 2 android-support-v4 trong project của bạn. Giải quyết như sau:
BaseGameUtils > Properties > Java Build Path > Order and Export > Bỏ chọn Android Private Libraries

* Sử dụng GameHelper của BaseGameUtils
Code bên dưới minh họa ứng xử như sau:
- Tự động đăng nhập 1 lần, nếu người dùng bấm Cancel, các lần sau không tự động đăng nhập nữa (vì GameHelper đã tự động lưu trong Preference)
- Người dùng nhấp Button để xem Leader Board -> displayLeaderBoard -> nếu chưa đăng nhập, yêu cầu người dùng đăng nhập -> đăng nhập thành công tự động hiển thị Leader Board (trong code minh họa còn submit điểm của người dùng, nhằm tránh việc điểm cao không được submit lúc người dùng chưa đăng nhập)

Activity
public GameHelper gameHelper;

@Override
protected void onCreate(Bundle savedInstanceState) {
//...
gameHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
gameHelper.setMaxAutoSignInAttempts(1);
gLeaderBoard = new GoogleAPILeaderBoard(this, GoogleAPILeaderBoard.FLAG_NOTHING);

gameHelper.setup(gLeaderBoard);
//...
}

@Override

protected void onStart() {
//...
gameHelper.onStart(this);
//...
}

@Override

protected void onStop() {
//...
gameHelper.onStop();
//...
}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_LEADERBOARD:
// ...
break;
default:
gameHelper.onActivityResult(requestCode, resultCode, data);
break;
}
}

private static final int REQUEST_LEADERBOARD = 555;
public void displayLeaderBoard(View v) {
// gamestate.isGoogleAPIConnected() is equal to gameHelper.isSignedIn()
if(gamestate.isGoogleAPIConnected()) {
        // do something before starting default Leader Board
if(!state.FEATURE_RATE_SHARE_LEADERBOARD_ENABLE) return;
feature_menu_rate_share_leaderboard_click();
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(gameHelper.getApiClient(),
this.getString(R.string.leaderboard_top_players)), REQUEST_LEADERBOARD);
} else {
gLeaderBoard.setFlag(GoogleAPILeaderBoard.FLAG_LEADER_BOARD);
gameHelper.beginUserInitiatedSignIn();
}

}

// optional
// use Google API to submit score to Leader Board (developer did set up Leader Board)
public void submitBestScore2LeaderBoard() {
int bestScore = AppLib.getConfiguration(this, ConstantStorage.PREF_GAME_STATE, ConstantStorage.PREF_BEST_SCORE_KEY);
if(gamestate.isGoogleAPIConnected() && bestScore>ConstantStorage.GAME_MINIMUM_SCORE_SUBMIT_LEADER_BOARD) {
Games.Leaderboards.submitScore(gameHelper.getApiClient(), this.getString(R.string.leaderboard_top_players), bestScore);
}

}

GoogleAPILeaderBoard
public class GoogleAPILeaderBoard implements GameHelperListener {
//private Context context;
private SkymonsterMain sm;
private int flag;
public static final int FLAG_NOTHING = 0;
public static final int FLAG_LEADER_BOARD = 1;
public GoogleAPILeaderBoard(Context context, int flag) {
//this.context = context;
this.sm = (SkymonsterMain) context;
this.setFlag(flag);
}
@Override
public void onSignInFailed() {
this.sm.gamestate.setGoogleAPIConnected(false);
}

@Override
public void onSignInSucceeded() {
this.sm.gamestate.setGoogleAPIConnected(true);
this.sm.submitBestScore2LeaderBoard();
switch (this.getFlag()) {
case FLAG_LEADER_BOARD:
this.sm.displayLeaderBoard(null);
break;
default:
break;
}
}

public int getFlag() {
return flag;
}

public void setFlag(int flag) {
this.flag = flag;
}

}

Sunday, November 23, 2014

Android - Navigation Drawer example

1. Add DrawerLayout to xml file




















2. Add some codes to open/close drawer

















3. Implement menu content
In my case, I need to add views dynamically to uim.menu

4. Change main content when user selects a choice in menu
+ Change views in main content view respectively (in my case, it is a ViewFlipper)
+ Close showing menu (by calling closeDrawer(...))

-------------------------------------------------------------

I do not use ActionBar in the above example. You can reference this link for more detail:

Friday, November 14, 2014

Android NDK Example

1. Download NDK - https://developer.android.com/tools/sdk/ndk/index.html










2. Extract to folder android-ndk
Linux
chmod +x android-ndk-r10c-linux-x86_64.bin
./android-ndk-r10c-linux-x86_64.bin
mv android-ndk-r10c android-ndk

3. Install CDT
Eclipse > Help > Install New Software... > Add...
http://download.eclipse.org/releases/galileo







Tick Eclipse C/C++ Development Tools (in Programming Languages) > Next, accept licences and finish

4. Create jni folder, Android.mk and your_native_code.c
jni - right click on your project > New > Folder > Folder name: jni > Finish
Android.mk - right click on jni folder > New > File > File name: Android.mk > Finish
your_native_code.c - right click on jni folder > New > File > File name: your_native_code.c > Finish

5. Android.mk

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS)
LOCAL_MODULE    := native
LOCAL_SRC_FILES := clean.c
include $(BUILD_SHARED_LIBRARY)

6. your_native_code.c

#include <jni.h>

JNIEXPORT void JNICALL Java_cleanmemory_activity_MainActivity_cleanNow(JNIEnv* env, jobject javaThis) {

}

7. Convert to a C/C++ Project
File > New > Other... > C/C++ > Convert to a C/C++ Project (Adds C/C++ Nature) > Next > Candidates for conversion: tick YOUR PROJECT > Project type: Makefile project > Toolchains: -- Other Toolchain -- > Finish

8. Set up C/C++ Build
Right click on your project (or Alt + Enter) > Properties > C/C++ Build > uncheck Use default build command > Build command: /home/your_user_name/android-ndk/ndk-build (do not have any redundant SPACE character after "ndk-build" | having a redundant space causes Error)> Apply
Change to Behavior tab > uncheck Clean > clear the text field on the right of Build (Incremental build) > Apply > OK

9. Set up Path and Symbols
Right click on your project (or Alt + Enter) > Properties > C/C++ General > Paths and Symbols > GNU C > Add... > File system... > choose path to android-ndk/platforms/android-21/arch-arm/usr/include > OK > OK > OK

10. Load (native) library in Java Activity class for using native functions

static {
System.loadLibrary("native");
}
private native void cleanNow();

11. Calling native functions is similar to calling functions in Java

* Note: GenyMotion may not simulate the app using NDK, it causes Fatal signal 7 error. To test app, we can use Android Virtual Device (default simulator) or real device.

Reference
http://mindtherobot.com/blog/452/android-beginners-ndk-setup-step-by-step/
http://mhandroid.wordpress.com/2011/01/23/using-eclipse-for-android-cc-development/