下面的代码,因为最初声明的 是整数类型 ,所以如果将 赋值给 时,会出现类型不匹配的问题,Swift 将会报错:

    报错输出:

    1. Cannot assign value of type 'String' to type 'Int'

    下面是一个使用 TensorFlow 计算的基础示例:

    1. import TensorFlow
    2.  
    3. // 声明两个Tensor
    4. let x = Tensor<Float>([1])
    5. let y = Tensor<Float>([2])
    6.  
    7. // 对两个 Tensor 做加法运算
    8. let w = x + y
    9.  
    10. // 输出结果
    11. print(w)

    在基础的 Tensorflow API 上,Swift 封装了 Tensorflow 的标准 API 接口。比如看一下处理数字的代码,API 与 Tensorflow 高度保持了一致:

    1. let x = Tensor<BFloat16>(zeros: [32, 128])
    2. let h1 = sigmoid(x w1 + b1)
    3. let h2 = tanh(h1 w1 + b1)
    4. let h3 = softmax(h2 w1 + b1)

    再比如 Data API ,也是同名函数直接改写为 Swift 语法即可直接使用:

    借助 S4TF 强大的集成能力,从 Python 迁移到 Swift 非常简单。您可以逐步迁移 Python 代码(或继续使用 Python 代码库),因为 S4TF 支持直接在代码中加载 Python 原生代码库,使得开发者可以继续使用熟悉的语法在 Swift 中调用 Python 中已经完成的功能。

    下面我们以 NumPy 为例,看一下如何在 Swift 语言中,直接加载 Python 的 NumPy 代码库,并且直接进行调用:

    1. import Python
    2.  
    3. let np = Python.import("numpy")
    4. let x = np.array([[1, 2], [3, 4]])
    5. let y = np.array([11, 12])
    6. print(x.dot(y))

    输出:

    1. [35 81]

    除了能够直接调用 Python 之外,Swift 也快成直接调用系统函数库。比如下面的代码例子展示了我们可以在 Swift 中直接加载 Glibc 的动态库,然后调用系统底层的 malloc 和 memcpy 函数,对变量直接进行操作。

    1. let x = malloc(18)
    2. memcpy(x, "memcpy from Glibc", 18)
    3. free(x)

    通过 Swift 强大的集成能力,针对 C/C++ 语言库的加载和调用,处理起来也将会是非常简单高效。

    输出:

    1. -4.0

    本小节的源代码可以在 <> 找到。加载 MNIST 数据集使用了作者封装的 Swift Module swift-MNIST)。

    更方便的是在 Google Colab 上直接打开本例子的 Jupyter 直接运行,地址: (推荐)

    1. import TensorFlow
    2. import Python
    3. import Foundation
    4.  
    5. /**
    6. * The Swift Module for MNIST Dataset:
    7. * https://github.com/huan/swift-MNIST
    8. */
    9. import MNIST
    10.  
    11. struct MLP: Layer {
    12. typealias Input = Tensor<Float>
    13. typealias Output = Tensor<Float>
    14.  
    15. var flatten = Flatten<Float>()
    16. var dense = Dense<Float>(inputSize: 784, outputSize: 10)
    17.  
    18. @differentiable
    19. public func callAsFunction(_ input: Input) -> Output {
    20. return input.sequenced(through: flatten, dense)
    21. }
    22. }
    23.  
    24. let optimizer = Adam(for: model)
    25.  
    26. let mnist = MNIST()
    27. let ((trainImages, trainLabels), (testImages, testLabels)) = mnist.loadData()
    28.  
    29. let imageBatch = Dataset(elements: trainImages).batched(32)
    30. let labelBatch = Dataset(elements: trainLabels).batched(32)
    31.  
    32. for (X, y) in zip(imageBatch, labelBatch) {
    33. // Caculate the gradient
    34. let (_, grads) = valueWithGradient(at: model) { model -> Tensor<Float> in
    35. let logits = model(X)
    36. return softmaxCrossEntropy(logits: logits, labels: y)
    37. }
    38.  
    39. // Update parameters by optimizer
    40. optimizer.update(&model.self, along: grads)
    41. }
    42.  
    43. let logits = model(testImages)
    44. let acc = mnist.getAccuracy(y: testLabels, logits: logits)
    45.  
    46. print("Test Accuracy: \(acc)" )

    以上程序运行输出为:

    1. Downloading train-images-idx3-ubyte ...
    2. Downloading train-labels-idx1-ubyte ...
    3. Reading data.
    4. Constructing data tensors.