端智能: Swift for TensorFlow, First Class Machine Learning in Swift

2021-02-15 SwiftGG翻譯組

作者:蓮叔,中年 iOS 開發者,就職於 UC,主要搞多媒體

本文發表於 2018/09/22 《SwiftOldDriver 精選》

本文是我在 atSwift Conf 2018 上的分享的文字版。內容和 keynote 高度重合,不過因為是文章,一些地方解釋得會更加到位一些。如果看過 keynote 的同學可以不用看了。

背景

首先一個問題是:為什麼要關注 Swift 在機器學習領域的應用?

從語言層面來看,Swift 兼具了腳本語言快速開發迭代的特性以及 low level 的編譯型語言的性能。而效率和性能是後端開發考慮的兩個主要方面,所以這也不能解釋為什麼 Server-Side Swift 受到越來越多的關注。概括來說,Swift 具備以下優勢:

開源並且社區非常活躍,語言本身也在高速發展與迭代;

開發效率很高,並且語言級別的靜態類型和異常處理使得代碼非常安全;

Next Big Thing on Server

既然說到 server 開發,我們不妨認真地思考一下最近幾年的 server 開發都在討論什麼,雲計算和容器化極大程度的提高運維效率之外,最重要的一大改變就是基於機器學習的應用呈現出了井噴式的發展,其中主要包括以下幾個方面:

文本分析,推薦系統的基礎能力之一,蘋果在 iOS 中也非常重視 NLP 能力的完善與建設;

音視頻理解,音視頻由於其數據的特殊性,長久以來我們只能從信號學層面做一些粗淺的分析,近年來得益於卷積神經網絡在計算機視覺領域的成功應用,越來越多的公司在使用這些技術嘗試從視頻中提取更多的結構化信息;

超解析度,簡單的說就是小圖變大圖,曾經我們普遍使用雙線性插值和雙三次插值,近年來通過試用卷積神經網絡技術能夠更好地猜出變大後圖片的細節,也有廣泛的應用。

聊天機器人,這個就不用說了,智能化客服基本是已經產業化的技術,雖然有時候會被調侃為人工智障,但不可忽視的是這項技術已經切實為很多公司節省了客服的人力成本。

目前機器學習應用主要的開發語言是 C++ 和 Python,Python 用於快速驗證想法,驗證之後用 C++實現後部署到線上系統,這兩門語言的優缺點都比較明顯,C++性能很強,但門檻高,開發效率低,Python 容易寫,但也非常容易寫出很多垃圾代碼。所謂動態類型一時爽,重構起來火葬場。

我們不禁會想,既然 Swift 是一門博眾家之長的語言,那假如它能提供很好的機器學習能力,豈不是非常完美?

本文的主角解決的就是這個問題 —— Swift for TensorFlow

Swift for TensorFlow 概覽

Swift for Tensor, 簡稱 TFiwS( 為什麼這麼叫,官方並沒有解釋,我大膽的猜測一下,應該是正讀看起來像TensorFlow for Swift, 倒過來讀就是 Swift), 文章接下來會簡稱 TFS.

TFS 是今年 Chris 在2018 TensorFlow Dev Submit 上發布的,到現在也沒滿一年,是一個非常年輕的技術,現在也不算正式發布,但已經開源了。目前正在 active developing 的階段,基本上每兩周會有一個新的版本放出來。

TFS 有如下幾個優勢:

可以融入完整的 TF 生態系統,眾所周知目前 TF 的生態是最完善的;

不僅僅只是 TensorFlow 的 API binding,而是提供了 First class machine learning 的能力;

基於2中有趣的特性(後面會講),使得 TFS 同時支持跑 CPU、GPU 以及遠程的 TPU;

最後一點,支持 Xcode Playground,使得天生具備「Notebook」一樣的感覺;

簡單的例子:

那個詭異的實心圓代表矩陣乘法,等價於 matmul

那到底什麼才是所謂的「First class machine learning」, 以及為什麼說 TFS 是兼具可用性和性能呢?我們還需要看 TF 的兩種模式。

TensorFlow 的兩種經典模式
#!/usr/bin/python
#coding=utf8
"""
# Author: aaron
# Created Time : 2018-09-01 16:50:36

# File Name: graph.py
# Description:

"""

import tensorflow as tf

x = tf.constant([[1,2,3], [4,5,6]])
xt = tf.transpose(x)
y = tf.matmul(x, xt)

with tf.Session() as sess:
    print sess.run(y)

圖模式的一個重要特點就是:Lazy Evaluation。比如在執行 xt = tf.transpose(x) 的時候,實際上並沒有觸發矩陣轉正的運算,而是只是生成了一個名為」轉置」的運算節點,添加到了計算圖中。最後,當執行 sess.run(y)的時候,所有計算才開始運行。

由於這個獨特的模式,圖模式的優點很明顯,那就是性能很強,因為計算時已經知道了所有的計算節點,可以做很多優化,同理,缺點也明顯,可用性很差,先建圖後計算的模式並不符合直覺,而且只能使用節點支持的運算來構建計算圖。Debug 起來很痛苦,因為你並不能通過 print x 這樣的形式來 debug 一些中間變量(執行到 print 的時候 x 還沒有 value) 。

Eager Execution 模式。示例代碼如下:
#!/usr/bin/python
#coding=utf8
"""
# Author: aaron
# Created Time : 2018-09-01 16:59:01

# File Name: eager.py
# Description:

"""

import tensorflow as tf
tf.enable_eager_execution()

x = tf.constant([[1,2,3],[4,5,6]])
y = tf.matmul(x, tf.transpose(x))
print(y)

顧名思義,Eager 模式與圖相反,計算是立即發生的,整個過程並不會構建圖。所以可以使用自然的流程控制,比如 if 語句來書寫模型,也可以在執行的過程中插入 print x 來獲取中間值,幫助我們 debug。

Eager 模式更符合直覺,易於理解,易於 debug。但因為沒有 lazy,所以很難做優化,性能並不好。

第三種模式 — TFS 模式

以下是一段 Swift 代碼:

    let x : Tensor<Float> = [[1,2,3], 
                             [4,5,6]]
    var y = Tensor<Float>(zeros: 
                            x.shape)
    print(y)
    if x.sum() > 100{
        y = x
    }else{
        y = x • x
    }
    print(y)

上面的代碼看起來是 eager 的,但其實跑起來是以 graph 的形式跑的,所以具備圖模式的所有優化。TFS 實現了一個改進版的 Swift 編譯器,在編譯階段會自動分析代碼中的 tensor 運算,並翻譯成計算圖,最終執行的時候就以圖的模式運營。而且這個過程對程式設計師透明,也就是說:

程式設計師只需要當它是 eager 的模式來寫代碼,最終跑起來就和圖模式一樣快了

聽起來是不是不太現實?這是什麼做到的呢?我們進入下一個章節。

TFS 模式的原理:Program Slicing

上文提到,TFS 會在編譯期間分析出所有的 tensor 運算,並生成計算圖,我們先來看看具體是怎麼做的,計算圖由 TensorFlow Runtime 運行的。

簡單的例子

先從一段簡單的代碼開始:

typealias FloatTensor = Tensor<Float>

func linear(x : FloatTensor, w : FloatTensor, b : FloatTensor) -> FloatTensor
{
    let tmp = w • x
    let tmp2 = tmp + b
    return tmp2
}

代碼很直觀,計算 wx + b ,只是以矩陣的形式。為了簡單期間,我們沒有使用變量,而是都用的常量。

如果是針對上面的代碼,要怎麼生成計算圖的?既然 Swift 沒有 runtime,我們不妨來看看其對應的 AST。

可以看到,所有 Tensor 類型的值和變量都可以從 AST 中找出來,也就是說,我們只需要遍歷這個 AST,就可以得到所有 Tensor 相關的常量和對應的操作,自然就可以構建計算圖。如下圖所示

<<< 左右滑動見更多 >>>

以看到,這種在編譯期間生成計算圖的計算幾乎強依賴於 Swift 的靜態類型系統,所以這活兒 Python 還真不一定適合,Chris 在 TFiwS 的白皮書也介紹了為什麼使用 Swift,感興趣的可以點這裡:https://github.com/tensorflow/swift/blob/master/docs/WhySwiftForTensorFlow.md

生成計算圖後,代碼該怎麼執行呢?我們只需要將圖代碼移除後,替換為啟動圖計算的代碼即可,上述代碼變換後如下所示:

typealias FloatTensor = Tensor<Float>
func linear(x : FloatTensor, w : FloatTensor, b : FloatTensor) -> FloatTensor
{
    let result = execTensorFlowGraph("graph_generate_before")
    return result
}

上述代碼運行時,直接調用 TensorFlow Runtime 執行剛才生成的計算圖,取得執行結果後返回

複雜的例子

現在我們來看一個複雜一點的例子:

func linear(x : FloatTensor, w : FloatTensor, b : FloatTensor) -> FloatTensor
{
    let tmp = matmul(x, w)
    let tmp2 = tmp + b
    print(tmp2)
    let tmp3 = tmp2 * magicNumberGenerateFromTensor(x: tmp2)
    return tmp3
}

func magicNumberGenerateFromTensor(x : FloatTensor) -> Float
{
    return 3.0
}

和上一個例子不同的是,這裡我們添加了一個真 eager 模式的代碼,print(tmp2) , 不僅如此,在 tmp3的計算中,我們還耦合了 tensor 的邏輯和普通的本地運算:magicNumberGenerateFromTensor,在這樣的前提下,我們生成的圖是什麼樣的呢?

tensor邏輯,代表最終要生成 graph,由 TensorFlow Runtime 運行的邏輯,或者簡單的理解為 Tensor 類的相關操作都是 tensor 邏輯。而本地運算,則是由 Swift Runtime 執行的非 tensor 邏輯的代碼。

之前的思路,我們可以得到上述的圖,但存在兩個問題:

我們需要列印出 tmp2 ,也就是 wx+b的值,但是這個圖是以一個整體由 TensorFlow 執行的,如何自動拿到某個中間的值?

magic 是由本地邏輯計算得到,TensorFlow 在執行這張圖的時候,怎麼知道 magic 的值到底是多少呢?

Program Slicing

接下來就是我們的 Program Slicing 技術登場了,這並不是一項新技術,但這應該是它第一次被用來幹這事兒,詳細介紹大家可以自行 wikipedia。

大家看完上面的問題,會發現一個終極問題是,本地代碼和 graph 似乎有雙向通信的需求。TFS 實現這樣的雙向通信,主要是通過 Program Slicing 技術,將原始代碼轉換為兩份不同的代碼,一份用來生成圖,一份用來在本地跑。兩份代碼互相通信,完成計算。

我們再 review 一下原始代碼,然後開始 slicing!

原始代碼:

func linear(x : FloatTensor, w : FloatTensor, b : FloatTensor) -> FloatTensor
{
    let tmp = matmul(x, w)
    let tmp2 = tmp + b
    print(tmp2)
    let tmp3 = tmp2 * magicNumberGenerateFromTensor(x: tmp2)
    return tmp3
}

1.Graph 部分

移除所有本地代碼,然後針對兩種情況做處理:

a. 如果本地代碼依賴圖代碼的結果,則插入 tfop(「send」, 用於指明這一步需要將結果發送給本地代碼;

b. 如果圖代碼依賴本地代碼,則插入 tfop("receive"), 用於接受本地代碼發過來的結果

改造完畢的圖代碼如下所示:

func linear(x : FloatTensor, w : FloatTensor, b : FloatTensor) -> FloatTensor
{
    let tmp = matmul(x, w)
    let tmp2 = tmp + b
    //REMOVED: print(tmp2)
    tfop("send", tmp2)
    let result = tfop("receive")
    // REMOVED: magicNumberGenerateFromTensor(x: tmp2)
    let tmp3 = tmp2 * result
    return tmp3
}

2.本地部分

邏輯同上,刪除圖相關代碼,針對依賴/被依賴的部分插入 send/receive 操作,區別只是需要在開頭插入啟動圖代碼,以及最終從圖的部分拿到結果返回。

本地版本的代碼

func linear(x : FloatTensor, w : FloatTensor, b : FloatTensor) -> FloatTensor
{
    let tensorProgram = startTensorGraph(graphName: "GeneratedGraphName")
    //REMOVED: let tmp = matmul(x, w)
    //REMOVED: let tmp2 = tmp + b
    let tmp2 = receivedFromTensorFlow(tensorProgram)
    print(tmp2)
    let result = magicNumberGenerateFromTensor(x: tmp2)
    sendToTensorFlow(tensorProgram, result)
    let tmp3 = finishTensorGraph(handle: tensorProgram)
    //REMOVED: let tmp3 = tmp2 * magicNumberGenerateFromTensor(x: tmp2)
    return tmp3
}

從一份代碼,slice 出兩份之後,將graph 部分編譯成圖,最終結構如下圖所示:

整個執行過程:

執行本地 startTensorGraph,觸發圖開始計算;

TensorFlow Runtime 開始計算圖;

計算完畢 wx + b 後,發現有SEND 節點,於是將結果發給本地;

本地代碼收到結果,如代碼所寫, 執行 print;

本地代碼調用函數,計算 magicNumber,並將結果發送給 TF Runtime;

TF Runtime 收到 magic 後,開始結算最終的結果 tmp3 ,並發回到本地;

以上,就實現了:寫 eager 的代碼,但跑起來具備圖的性能,並且像 eager 模式一樣支持本地的控制流程和用 print 進行 debug。當然,背後還有很多黑魔法,這裡只是講了最簡單的一個 use case……具體的大家可以去看 TFS 的白皮書。

看到這裡大家會想 SEND 節點和 RECV 節點是啥,為什麼 TensorFlow 有這麼騷的操作?其實這兩個東西本來是讓 TensorFlow 做分布式計算的,在不同的機器上同步結果。所以這個模式能 work,關鍵還是 TensorFlow 本身具備一個比較牛逼的架構。

通用的流程如下圖所示:

實戰 — 線性分類問題

在了解了 TFS 大致的原理之後,這裡講一個機器學習中非常基礎的例子,來體驗一下 TFS 開發機器學習類應用的便利性。

問題描述

海洋的某片區域受到了汙染,經過了五十三次勘探,我們得到了如下的分布圖:

其中,綠色的圓代表該位置是乾淨的,紅色的方塊代表該位置受到了汙染。

問題就是,當給一個新的坐標 (x1』, x2』) ,我們能否基於之前的勘探數據推測出該位置是否被汙染?

問題分析

首先,通過觀察圖,很明顯汙染和被汙染是線性可分的,那我們可以假設,我們要尋找的是一條直線,假設為 L.  我們可以得到如下的模型:

之所以可以寫為左右的矩陣形式,我們只需要假設存在x0並且x0恆為1,這樣就可以把w0也帶一個x0的係數,進而整體寫成矩陣的形式。

上述模型有三個權重,w0,w1,w2,這就是我們要通過訓練數據來計算的。不過現在我們先思考一個終極問題:假設我們已經有了w0~w2,我們怎麼用這個線性模型來判斷一個新的坐標的分類呢?

首先我們的模型 Line 的值域很明顯是負無窮到正無窮,那我們要針對這樣的一個連續值做分類,有兩種方法:

使用其他函數將 Line 的值 map 到0到1之間;

很明顯方法1是不合理的,因為不同的問題尺度不同,可以腦補一條夾角為45°的直線,不管你設多大的閾值,仍然可能會出現大於該閾值的點會同時包含兩種分類。

機器學習一般使用方法2,通過一個叫做 sigmoid 的函數來進行映射,該函數的特徵如下圖所示:

從圖中可以看出,這個函數的形狀很完美,定義域負無窮到正無窮,值域從0到1,並且整體很平滑。

我們用 sigmoid 來處理 Line 的結果,得出新的模型:

既然已經知道如何用模型來計算分類了,現在是時候來計算模型本身了,如剛才所說,計算模型也就是計算 W 向量(包含三個分量)。那如何計算 W 呢?或者說什麼樣的 W 才是好的 W 呢?基於我們已經有了 53 次觀測,於是有如下事實:

如果我們能找到一個 W,用這個 W 去計算觀測點的分類,如果能儘可能的貼合我們之前實際觀測到的 W,則就代表找到了一個好的 W

Classifier(X') 的值在0-1之間,我們可以當做是 X' 是類別1的概率

於是我們可以發現這很適合用「極大似然估計」來建模該問題,可以得到一個關於W 的方程:

根據極大似然估計的定義,我們只需要找到一個 W,使得上述函數取得最大值,則 W 就是一個最優解。至此,我們成功的將一個分類問題,轉換為一個數學上的優化問題。

找極值最常規的做法是梯度下降/上升,結合梯度上升以及對上式求導可得梯度的迭代公式:

為了簡化表示,通過觀察上式,不難發現可以進一步寫成矩陣的形式:

這個解決線性分類問題的方法也稱作 logistics regression,對數機率回歸。

代碼實現

首先,先對我們的分類問題做一些基本的定義:

typealias FloatTensor = Tensor<Float>
let matplot = Python.import("matplotlib.pyplot")

enum Label : Int{
    case Green = 0
    case Red
}

struct ClassifierParameters : ParameterAggregate {
    var w = Tensor<Float>(randomNormal: [3,1])
}

struct Model
{
    var parameters : ClassifierParameters = ClassifierParameters()
}

這裡,我們使用 TFS 中的 ParameterAggregate 結構來聲明我們的模型,簡單的來說就是一個 shape 為(3,1)的 tensor,代表三個 w。接下來,我們把測試數據 load 到 TFS 的 Tensor 結構中。

func loadTrainingSet() -> (trainingVec : FloatTensor , labelVec : FloatTensor)
{
    let lines = try! String(contentsOf: URL(fileURLWithPath: "test.txt")).split(separator: "\r\n")
    let data = lines.map{$0.split(separator: "\t")}
    let rowCount = data.count
    let trainingScalars:[[Float]] = data.map{[1.0, Float($0[0])!, Float($0[1])!]}
    let labelScalarts:[Float] = data.map{Float($0[2])!}
    
    let trainingVec = Tensor<Float>(shape: [Int32(rowCount), 3], scalars: trainingScalars.flatMap{$0})
    let labelVec = Tensor<Float>(shape: [Int32(rowCount) , 1], scalars: labelScalarts)
    return (trainingVec, labelVec)
}

下一步,就是最關鍵的訓練了,我們先 review 一下我們梯度上升的核心公式:

func train(trainingVec : FloatTensor, labelVec : FloatTensor, model : inout Model){
    let learningRate:Float = 0.0005
   
    for epoch in 0...3000{
        let y = trainingVec • model.parameters.w
        let h = sigmoid(y)
        let e = labelVec - h
        let dw = trainingVec.transposed() • e
        
        let grad = ClassifierParameters(w: dw)
        model.parameters.update(withGradients: grad) { (p, g) in
            p += g * learningRate
        }

        let p1 = -1 * labelVec * log(h)
        let p2 = (1 - labelVec)*log(1 - h)
        let traditionalLogLoss = ((p1 - p2).sum() / batchSize)

        print("epoch: \(epoch), LogLoss v2: \(traditionalLogLoss)")
    }
}

大家可以很容易看到,for 開頭的四個 let,其實就是用非常簡單的方式實現了核心的迭代公司。雖然我們分析得很複雜,但最終整個過程實現卻非常簡單,必須感謝矩陣這種東西,避免了無數的 for 循環。

最後,在得到 w 之後,我們可以把我們通過模型找到的直線畫出來

func plot(trainVec : FloatTensor, labelVec : FloatTensor, parameters : ClassifierParameters)
{
    //Calculate points based parameters (w0, w1, w2)
    //…

    let matplot = Python.import("matplotlib.pyplot")

    let fig = matplot.figure()
    let ax = fig.add_subplot(111)
    ax.scatter(coord1x, coord1y, 50, "red", "s")
    ax.scatter(coord2x,coord2y,50, "green")
    ax.plot(xpts, ypts)
    matplot.show()
}

最終的效果如圖所示:

線性分類的完整代碼在這裡:https://github.com/aaaron7/tfiws_snippet  有興趣的童鞋可以下來跑一跑。

總結

Swift for TensorFlow 通過一系列有趣的技術,給 Swift 帶來了內置的機器學習能力,實現了高可用性以及高性能,即便現在非常早期,支持的 TF Api 還不夠全,但已經能夠做出很多非常有趣的事情了。

TFS 的原理,更是 Programming language 和 machine learning 一次有趣的碰撞,有興趣可以去看看白皮書,是很有想像空間的一個方向。

推薦閱讀

✨ 端智能:用 Create ML 打造智能運動 App

關注我們

我們是「老司機技術周報」,每周會發布一份關於 iOS 的周報,也會定期分享一些和 iOS 相關的技術。歡迎關注。

這篇文章的內容來自於《SwiftOldDriver 精選》。關注【老司機技術周報】,回復「2020」, 即可領取。

相關焦點

  • 宣布Swift for TensorFlow已在GitHub上開源
    這些文檔都可以在 README 文件中找到:https://github.com/tensorflow/swift/blob/master/README.md第一個必讀文檔是「Swift for TensorFlow 設計總覽」,這裡介紹了項目的主要組成部分以及結合方式。另外,我們還會詳細介紹項目的幾個重要領域。
  • 零基礎學習Swift中的數據科學
    你可以按照下面的步驟打開一個Colab筆記本,這是快速激活的:打開一個空白的Swift筆記本(https://colab.research.google.com/github/tensorflow/swift/blob
  • TensorFlow 中文資源全集,學習路徑推薦
    /GitHub:https://github.com/tensorflow安裝教程中文安裝教程Mac安裝:http://www.cnblogs.com/tensorflownews/p/7298646.htmlubuntu 16.04 安裝 tensorflow-gpu:http://www.tensorflownews.com/2017/09/02/tensorflow-gpu-install-ubuntu
  • Hands-on Machine Learning with Scikit-Learn and TensorFlow 學習筆記
    簡述型的課後習題都以章節為單位翻譯成中文放在我的簡書上了歡迎查閱Hands-on machine learning with scikit-learn and tensorflow
  • tensorflow機器學習模型的跨平臺上線
    tensorflow模型的跨平臺上線的備選方案tensorflow模型的跨平臺上線的備選方案一般有三種:即PMML方式,tensorflow serving方式,以及跨語言API方式。PMML方式的主要思路在上一篇以及講過。
  • 【TensorFlow超級指南】你能想到的TF教程和資源都在這裡了
    >Dino Causevic—《TensorFlow入門:機器學習教程》:https://www.toptal.com/machine-learning/tensorflow-machine-learning-tutorial《Python TensorFlow教程:構建一個神經網絡
  • 從Java到Swift
    Swift程序的默認入口是main.swift文件,在iOS應用中,則通常標記了@UIApplicationMain的AppDelegate.swift文件。可以類比到Android中,在AndroidManifest.xml中定義的Application。2.Swift不需要定義行結束符,這個是像腳本語言一樣。
  • Tensorflow 2.0 到底好在哪裡?
    TensorFlow Extended(TFX)則支持端到端生產流水線。在以前的文章中,我曾評測過 :TensorFlow r0.10(2016):https://www.infoworld.com/article/3127397/review-tensorflow-shines-a-light-on-deep-learning.html  TensorFlow 1.5(2018):https://www.infoworld.com
  • 【TensorFlow】優化器AdamOptimizer的源碼分析
    源碼位置: /tensorflow/python/training/adam.py_epsilon_t = None從上邊_init_函數可以看到,除了初始化時傳進去的參數,優化器自身還存儲了這些參數的 Tensor 版本,而這個轉換是在_prepare函數中通過convert_to_tensor方法來實現的。 這個函數在/tensorflow/python/framework/ops.py#L1021處。
  • Windows配置tensorflow開發環境
    TensorFlow是一個基於數據流編程(dataflow programming)的符號數學系統,被廣泛應用於各類機器學習(machine learning
  • TensorFlow 資源大全中文版
    TensorFlow 是一個採用數據流圖(data flow graphs),用於數值計算的開源軟體庫。節點(Nodes)在圖中表示數學操作,圖中的線(edges)則表示在節點間相互聯繫的多維數據數組,即張量(tensor)。它靈活的架構讓你可以在多種平臺上展開計算,例如臺式計算機中的一個或多個CPU(或GPU)、伺服器、行動裝置等等。
  • iOS面試題-Swift篇
    class 有以下功能,struct 是沒有的:*class可以繼承,子類可以使用父類的特性和方法類型轉換可以在運行時檢查和解釋一個實例對象class可以用 deinit來釋放資源一個類可以被多次引用結構較小,適用於複製操作,相比較一個class 實例被多次引用,struct 更安全無需擔心內存洩露問題Swift 中
  • 簡單介紹 Swift on Fedora ——在 Fedora 中使用 Swift
    支持方法,擴展和協議的結構函數式編程模式,例如映射和過濾(map and filter)內置強大的錯誤處理功能使用 do,guard,defer 和 repeat 關鍵字編寫高級控制流程在 Fedora 中試用 Swift現已支持在 Fedora 28 中使用 Swift,不過需要安裝名為 swift-lang
  • 從TensorFlow.js入手了解機器學習
    沒有激活函數的話神經網絡不可能很智能。原因是儘管在網絡中你可能有很多神經,神經網絡的輸出總會是一個線性回歸。我們需要一些機制來改變這個獨立的線性回歸為非線性的以解決非線性的問題。感謝這些激活函數,我們可以將這些線性函數轉換到非線性函數:
  • 玩轉TensorFlow?你需要知道這30功能
    網址:https://js.tensorflow.org/11)KerasKeras 如今直接集成在 TF 中,也就是 tf.keras。網址:https://github.com/tensorflow/tensor2tensor
  • 可能是史上最全的Tensorflow學習資源匯總
    2)從Tensorflow基礎知識到有趣的項目應用:https://github.com/pkmital/tensorflow_tutorials同樣是適合新手的教程,從安裝到項目實戰,教你搭建一個屬於自己的神經網絡。
  • Swift中編寫單例的正確方式
    這些連結中已經有很詳盡的描述,比如https://github.com/hpique/SwiftSingleton,http://stackoverflow.com/questions/24024549/dispatch-once-singleton-model-in-swift和https://developer.apple.com/swift/blog/?id=7。
  • 吳恩達deeplearning.ai新課上線:TensorFlow移動和web端機器學習
    近日,他創始的 deeplearning.ai 在 Coursera 上另外開設了一門課程,主要介紹使用 Tensorflow.js、TensorFlow Lite、TensorFlow Hub 等工具進行數據分析的方法。該專項課程已於今日開放註冊。吳恩達對課程進行了轉推。
  • 從Fashion-Mnist開始,入門Tensorflow與深度學習
    「記憶是智能的基石」。而基於多層級神經網絡的深度學習算法也正是如此。所以,從這個方面來說,深度學習的發展和興起很大程度上是源於人類對自身發展出的智能進行逆向開發的過程。既然人類擁有的我們所謂的智能,很自然的我們就會探索我們這種智能是如何產生的。
  • Apple 在 iOS 13.1 中使用 Swift 開發的應用程式
    PlugIns/ContinuitySignature.appex/ContinuitySignature/Applications/Sidecar.app/PlugIns/ContinuitySketch.appex/ContinuitySketch/Applications/Sidecar.app/Sidecar/System/Library/Accounts/DataclassOwners