2017年2月12日 星期日

iOS筆記:Core Animation

Core Animation:

Core Animation 是在 iOS 上負責一般 UI 繪圖與動畫的 framework. 要注意的是, Core Animation是直接作用在CALayer上, 而非UIView. 至於一個 view 呈現出來的外觀,在 iOS 上,UIView 的外觀呈現,也都是由 Core Animation 實作。我們看到的 UIView 的樣子,其實是裡頭的 CALayer 的樣子。

每個 UIView,都是屬於自己專屬的 CALayer 物件的 delegate,當我們要重繪某個 view 的內容時,其實是叫 CALayer 重繪,重繪 CALayer 時會呼叫到 CALayer 的-drawInContext:,在這個 method 中,CALayer 可以自己決定怎麼繪製內容,或是去問 delegate 該怎麼畫,而去問了 CALayer delegate 的 -drawLayer:inContext:。

在 UIView 的 -drawLayer:inContext: 的實作中,便呼叫了 drawRect:,因此, drawRect: 繪製的內容,放到 CALayer 上。

範例可以參考reference!

Reference:
1. https://zonble.gitbooks.io/kkbox-ios-dev/content/core_animation/index.html
2. http://www.bkjia.com/IOSjc/1120723.html
3. http://www.cocoachina.com/ios/20170124/18617.html
4. http://charsdavy.github.io/2016/07/29/animation-caanimation/

2017年1月8日 星期日

iOS筆記:React Native環境建置

React Native 是 Facebook 推出的一個用 JavaScript 語言就能同時編寫 iOS,Android,以及後台的一項技術

1. 安裝Node 和 Watchman

    $ brew install node
    $ brew install watchman
Watchman 是來自 Facebook 的檔案監控工具。 React Native 利用 Watchman 來偵測程式碼的變化,以便重新建構。

2. 安裝React Native CLI

    $ npm install -g react-native-cli

enter image description here

3. iOS環境

有安裝Mac的Xcode即可.

4. Android環境

安裝Android studio. 另外還需要Java SE Development Kit 8.

enter image description here

5. Install Android SDK

開啟安裝完的Android studio, 選擇右下角的”Configure”, 選擇 “SDK Manager”, 會出現下面的畫面:

enter image description here

打勾右下角的 Show Package Details, 勾 Android 6.0 (Marshmallow) 下的這些:
- Android SDK Platform
- Google APIs
- Intel x86 Atom System Image
- Intel x86 Atom_64 System Image
- Google APIs Intel x86 Atom_64 System Image

切換到分頁 SDK Tools, 繼續安裝需要的工具.
- Android SDK Build Tools
- Android SDK Tool
- Google Play Services

6. Set up the ANDROID_HOME environment variable

如果你使用的是bash,那就在~/.bashrc文件中加入以下内容,如果是用zsh,那就是~/.zshrc.
    export ANDROID_HOME=~/Library/Android/sdk
    export PATH=${PATH}:${ANDROID_HOME}/tools
    export PATH=${PATH}:${ANDROID_HOME}/platform-tools

7.新增專案

虛擬機的部分我是使用“Genymotion”的. 要注意的是需要設定Android SDK的位址(路徑可以在 SDK Manager 上找到).

enter image description here

新增專案

    $ react-native init HelloWorld
移動到專案中執行”npm start“並先將Android虛擬機開啟.
然後就可以執行run-ios跟run-android.

enter image description here


enter image description here

Issue

  1. 會發生這問題的原因是忘記把Android的虛擬機開啟就執行run-android導致.
    Key world: :app:installDebug

enter image description here

Reference:

  1. https://facebook.github.io/react-native/
  2. https://github.com/facebook/react-native
  3. http://reactnative.cn/
  4. https://github.com/jondot/awesome-react-native
  5. http://makeitopen.com/



2017年1月4日 星期三

iOS筆記:Swift3 GCD

Grand Central Dispatch (GCD)

在iOS當中,蘋果提供兩個方法來實作多工任務:包含Grand Central Dispatch (GCD)以及NSOperationQueue的frameworks,它們都可以幫助開發者達到多個任務分配給多個執行緒或不同queues進行同步運行的需求.

主佇列都是用來處理UI接收到的指令,所以跑在主執行緒的任務是最優先執行的
有時候都會在completion handler block執行以下的方式來更新UI, 主要的原因是因為原本的狀況並不是在main queue刷新UI介面, 所以可能你的圖片已經下載好了 但礙於不是在main queue所以會沒辦法及時被更新而產生很多error log.

    DispatchQueue.main.async {
        self.imageView.image = UIImage(data: data)
    }

GCD在swift上一直都是基於C建立的, 之前也有聽人說過如果把swift上跟dispatch相關的程式碼貼到linux上可以直接運作. 但這件事情在Swift 3上應該是不會再發生了. 因為這方面進行了大改版. 詳細的部分請參考Reference.

Dispatch framework

  1. DispatchQueue
    取代原本Dispatch async的工能, 建立一個queue最基本的語法:

        let queue = DispatchQueue(label: "dispatchQueue")

    queue一旦被建立後,我們就可以透過程式碼使用它,同步則使用sync函式,若非同步則呼叫async函式,當我們開始時,先提供一段code當做一個block(closure).

            queue.async {
            for _ in 1...10 {
                print("111111111")
            }
        }
  2. DispatchQoS (Quality of Service)
    可以去決定執行緒的權重(優先順序), 右邊為Swift 3現在的語法, 左邊則是對應到之前的權限是多大. 根據想要的優先順序,提供一個適當的QoS值在佇列初始化作業,如果沒有特別定義,佇列則預設為 default priority.

    enter image description here

    測試的話可以先定義兩條queue然後再用forloop看執行結果就可以明顯看出優先權高跟低的差異.

    let queue1 = DispatchQueue(label: "com.appcoda.queue1", qos: DispatchQoS.userInitiated)
let queue2 = DispatchQueue(label: "com.appcoda.queue2", qos: DispatchQoS.utility)
  1. DispatchWorkItem
    DispatchWorkItem是一個代碼塊(可以想成是把closure封裝成一個item),可以在任何的佇列上面被調用,因此,裡面的程式碼可以在背景執行,或是在主執行緒運行.

        //workItem的目的是將value變量的值增加5
        func useWorkItem() {
            var value = 10
    
            let workItem = DispatchWorkItem {
                value += 5
            }
        }
    
        //調用方式
        let queue = DispatchQueue.global()
        queue.async {
            workItem.perform()
        }

另外也有比較快的方式可以調用work item,DispatchQueue類別為此目的提供了一種方便的方法:

    queue.async(execute: workItem)
  1. DispatchTime 延遲時間
    now()方法會回傳目前時間,另外再把想要延遲的時間添加進來.
    func dispatchTime() {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) { 
            //兩秒後才會被執行
            print("兩秒了")
        }
    }

Reference:
1. http://www.appcoda.com.tw/grand-central-dispatch/

2016年12月20日 星期二

iOS筆記:Firebase Guide with Swift 3

  1. 建立新專案[建立專案名稱]
    enter image description here
  2. 點選將Firebase加入iOS專案
enter image description here
         3. 將專案的ID加進Firebase中, 在專案的”General“的Bundle Identifier.

enter image description here

4.  Firebase會直接下載GoogleService-info.plist, 將此檔案加進Xcode專案中

enter image description here

      5.透過Cocoapods將Firebase加到專案裡.

enter image description here

enter image description here

      6. 在AppDelegate.swift中加入 import FirebaseFIRApp.configure()

enter image description here

其他功能:

大部分的功能可以參考Firebase線上的文件即可完成


Reference:

  1. https://codelabs.developers.google.com/codelabs/firebase-ios-swift/#12
  2. https://firebase.google.com/docs/cloud-messaging/ios/certs

2016年12月18日 星期日

iOS筆記:在Swift中使用Objective-C的專案

在使用Swift開發的時候, 一定會遇到只用3rd party專案的情形發生. 但也不是每個open source的專案都會轉到Swift中進行開發. 所以這邊紀錄一下. 怎麼在Swift中使用3rd party的Objc-C專案.

Objective-C Bridging Header File

不管是[在Swift專案中使用Objective-C檔案]或是[在Objective-C專案中使用Swift檔案]都需要使用Objective-C bridging header檔案。加入Objective-C bridging header檔案的方法有兩種:
  1. 由Xcode 自己產生
    首先在File -> new file中, 點選Objective-C file (在objc-c 中就是新增.swift的檔案), 名稱可以隨便亂取, 我們主要只是為了再新增檔案的時候會跳出下面的視窗.
enter image description here.

按下 Create Bridging Header後, 就可以把新增的專案刪除了.
  1. 自己手動新增
    如果沒跳出上面的視窗或者是點錯的話就可以在File -> New File。然後選[iOS](或是watchOS或是tvOS或是OSX)下的[Source]裡面的[Header File]自己產生一個標頭檔。
    名稱的話我會跟著下面的方式照打上!
    [Your project name]-Bridging-Header
如果都沒有跳出新增的畫面的話. 可以去專案的 [Build Settings] 下, Swift Compiler – Code Generation一欄中,新增Objective-C bridging header檔案的位置。

enter image description here

新增完之後…

好了之後就是要進行import的動作了.

enter image description here



2016年11月26日 星期六

ML初學筆記:Keywords 筆記

這裡主要是針對流程做一個紀錄, 也可以說是一個筆記, 所以會收錄一些從別人那轉載過來一些文字敘述或是圖等. 來源皆在最下面的網址中. 謝謝!

這次主要針對Google的TensorFlow作為機器學習的入門對象, 在學的時候有出現很多單字, 因此在這邊就紀錄下他們在TensorFlow中代表的意義是什麼.

TensorFlow

TensorFlow為Google開發的一個開源的機器學習工具, 官網有很多解釋以及相關的範例帶你上手這一個強大的工具.
架構如下圖所示, 支援Python跟C++. 在 Python 语言中, 返回的 tensor 是 numpy ndarray 对象; 在 C 和 C++ 语言中, 返回的 tensor 是 tensorflow::Tensor 實例.
主要是跑在Linux&Mac系統上. Windows在執行的時候必須先用虛擬機再安裝Linux才行.
enter image description here
執行的流程, 最大主題可以分成兩塊:
一:模型定義(modeling):抽象化,此階段完全是紙上談兵
1. 輸入項、輸出項的定義(tensorflow的術語叫:placehold)
2. 模型建構(隱藏層)
a. 定義 Variable (例:權重、誤差項)
b. 定義網路 (例:y = W*X+b)
3. 初始化 Variable
4. 定義Loss函數
5. 最佳化:讓Loss函數最小化(Tensorflow 內建 Gradient Desecnt 等,可直接叫用)
二:執行(session階段):計算資源投入(CPU/GPU)、實際資料投入
1. 開啟 Session 來run Graph
2. 要跑幾次去達成最佳化(Iterative Update)
3. 訓練資料讀入( feed)

Tensor

Tensor可以看作是一个 n 维的数组或列表. 計算Graph中, 操作間傳遞的數據都是 Tensor.

Operation

Graph 中的節點,也就是對資料的操作/計算

Variable

A variable maintains state in the graph across calls to run(). You add a variable to the graph by constructing an instance of the class Variable.
(Variable is something that can updated as your training. )

Placeholder

A input into neural network.

Data Flow Graphs

Data Flow Graphs使用節點(Nodes)與邊(Edges)所繪出的有向圖(Directed Graph)來描述數學運算[如下圖所示]。Nodes一般是用來實作數學運算,也可以儲存資料、運算結果或持久性變數,Edges描述Nodes之間的I/O關係。
這些數據的Edges進行動態調整多維數據陣列(或Tensors)的大小。TensorFlow的命名由來是Graph**[表示一整個計算任務]**上,Tensors的Flow在Nodes間藉著Edges穿梭傳遞。當系統中Nodes的所有Tensors從輸入端Edges取得,Nodes就被分配到的運算裝備中,Nodes可非同步且平行的方式作業。
enter image description here

Session

在 Session 階段中才會執行 graph.

Loss function

比較預估以及真實結果之間的差異, 在一開始的範例常使用下列的”Cross Entropy”.

Optimizer

根據Loss function的值 導入學習率去修正誤差.

Cross-Entropy

Entropy: 熵的概念最早起源於物理學,用於度量一個熱力學系統的無序程度。在資訊理論裡面,熵是對不確定性的測量。但是在資訊世界,熵越高,則能傳輸越多的資訊,熵越低,則意味著傳輸的資訊越少。
大多數人都會對犯錯感到不愉快。當發生錯誤的時候,可能當下會覺得非常的悲劇,但是如果可以記得這次的教訓下一次再遇到不犯錯其實就可以了. 且當犯的錯越大的時候,一般人對這錯誤的印象會記很久以避免再次的犯錯,相反,如果錯誤很不明顯的話,我們的學習改進的速度可能將會很慢。
對於電腦來說我們也是希望它在學習時,當發生錯誤的時候所做的修正就應該要越大. 而這就是使用Cross Entropy的一個優點,可以參考名稱的超連結有更近一步的介紹.

Gradient Descent

迴歸方程式是一次方程式, 所以是一條線, 而Loss Function是計算最小平方和,是自變項的二次方程式(下圖右),所以是個曲線(如果是多元迴歸就是一個高維度的山谷)
enter image description here
那做法就是將問題從線性方程式轉換成求最小平方和的最佳解.要求最佳解用的方法是,先隨便站在山谷上的任何一點,發現哪邊比較低,就往哪邊走. 透過多次的迭代來找到最低點,化成公式就長得像下面這樣:
enter image description here
當θ落在最小值的右邊,斜率是正的,帶到公式中,就會減少θ值;反之,如果θ比最小值還小,那斜率是負的,帶到迭代公式中就會增加θ值.由於曲線越接近谷底越為平緩,所以當θ靠近最低點時,每次移動的距離也會越來越小,最終將收斂在最低點.
enter image description here
講完微分的部分,接下來是α值(learning rate).α值的用途主要在控制每次θ移動的距離,下圖顯示移動距離太大或太小的狀況:
enter image description here
如果一次移動太短的距離(左圖),那收斂速度會相當的慢.但是如果移動的距離太大(右圖),反而可能造成無法收斂的情形.所以會需要根據不同的狀況來調整這個α的大小.
References:
1. http://mropengate.blogspot.tw/2016/10/ai-ch165-tensorflow.html
2. http://www.slideshare.net/ckmarkohchang/tensorflow-60645128
3. http://tensorflow-tw.blogspot.tw/2015/12/tensorflow.html
4. http://blog.moebigdata.com/2016/01/tensorflow.html
5. https://hit-scir.gitbooks.io/neural-networks-and-deep-learning-zh_cn/content/chap3/c3s1.html

2016年11月18日 星期五

ML初學筆記:安裝Tensorflow

這裡主要是針對流程做一個紀錄, 也可以說是一個筆記, 所以會收錄一些從別人那轉載過來一些文字敘述或是圖等. 來源皆在最下面的網址中. 謝謝!

安裝步驟

參考Tensorflow官網的安裝流程, 按照以下步驟就可以在Mac上安裝當下最新的版本.

$ virtualenv --system-site-packages ~/tensorflow
$ source ~/tensorflow/bin/activate
(tensorflow)$  # Your prompt should change

(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.11.0-py2-none-any.whl

(tensorflow)$ pip install --upgrade $TF_BINARY_URL

在這邊我是參考在Youtube上看的Tutorial .

(tensorflow)$ pip install --upgrade jupyter
(tensorflow)$ pip install --upgrade Pillow

接著去下載在Github上的課程文件. 執行完下面的指令後, 存取課程文件即可.

(tensorflow)$ jupyter notebook

enter image description here

Virtualenv

Virtualenv 可以隔離函數庫需求不同的專案,讓它們不會互相影響。在建立並啟動虛擬環境後,透過 pip 安裝的套件會被放在虛擬環境中,專案就可以擁有一個獨立的環境,也降低了不同版本套件間衝突的可能。

簡而言之,Virtualenv 可以幫你做到:
1. 在沒有權限的情況下安裝新套件
2. 不同專案可以使用不同版本的相同套件
3. 套件版本升級時不會影響其他專案

使用方法
I. 建立虛擬環境
請於命令列模式下輸入下列指令:

$ virtualenv [指定虛擬環境的名稱]

例如下列指令會建立名為 “ENV” 的虛擬環境:

$ virtualenv ENV

預設在建立虛擬環境時,會依賴系統環境中的 site packages,如果想完全不依賴系統的 packages,可以加上參數 –no-site-packages 來建立虛擬環境:

$ virtualenv --no-site-packages [指定虛擬環境的名稱]

II. 啟動虛擬環境
請先切換當前目錄至建立的虛擬環境中。前例中,建立名稱為 “ENV”,則:

$ cd ENV

接著,啟動虛擬環境:

$ source bin/activate

III. 退出虛擬環境

$ deactivate

Reference:
1. https://www.tensorflow.org/
2. https://github.com/sherrym/tf-tutorial/blob/master/install-mac-native.md