Operator TensorFlow mentah

Lihat di TensorFlow.org Lihat sumber di GitHub

Berdasarkan TensorFlow, Swift untuk TensorFlow mengambil pendekatan baru pada desain API. API dikurasi dengan cermat dari perpustakaan yang sudah ada dan dikombinasikan dengan idiom bahasa baru. Artinya, tidak semua API TensorFlow akan tersedia langsung sebagai API Swift, dan kurasi API kami memerlukan waktu dan upaya khusus untuk berkembang. Namun, jangan khawatir jika operator TensorFlow favorit Anda tidak tersedia di Swift -- pustaka TensorFlow Swift memberi Anda akses transparan ke sebagian besar operator TensorFlow, di bawah namespace _Raw .

Impor TensorFlow untuk memulai.

import TensorFlow

Memanggil operator mentah

Cukup temukan fungsi yang Anda perlukan di bawah namespace _Raw melalui penyelesaian kode.

print(_Raw.mul(Tensor([2.0, 3.0]), Tensor([5.0, 6.0])))
[10.0, 18.0]

Mendefinisikan operator perkalian baru

Multiply sudah tersedia sebagai operator * di Tensor , tapi mari kita berpura-pura ingin membuatnya tersedia dengan nama baru sebagai .* . Swift memungkinkan Anda menambahkan metode atau properti komputasi secara retroaktif ke tipe yang ada menggunakan deklarasi extension .

Sekarang, mari kita tambahkan .* ke Tensor dengan mendeklarasikan ekstensi dan membuatnya tersedia ketika tipe Scalar tensor sesuai dengan Numeric .

infix operator .* : MultiplicationPrecedence

extension Tensor where Scalar: Numeric {
    static func .* (_ lhs: Tensor, _ rhs: Tensor) -> Tensor {
        return _Raw.mul(lhs, rhs)
    }
}

let x: Tensor<Double> = [[1.0, 2.0], [3.0, 4.0]]
let y: Tensor<Double> = [[8.0, 7.0], [6.0, 5.0]]
print(x .* y)
[[ 8.0, 14.0],
 [18.0, 20.0]]

Mendefinisikan turunan dari fungsi yang dibungkus

Anda tidak hanya dapat dengan mudah mendefinisikan Swift API untuk operator TensorFlow mentah, Anda juga dapat membuatnya dapat dibedakan agar berfungsi dengan diferensiasi otomatis kelas satu Swift.

Untuk membuat .* terdiferensiasi, gunakan atribut @derivative pada fungsi turunan dan tentukan fungsi asli sebagai argumen atribut di bawah label of: Karena operator .* didefinisikan ketika tipe generik Scalar sesuai dengan Numeric , hal ini tidak cukup untuk membuat Tensor<Scalar> sesuai dengan protokol Differentiable . Terlahir dengan keamanan tipe, Swift akan mengingatkan kita untuk menambahkan batasan umum pada atribut @differentiable untuk mengharuskan Scalar mematuhi protokol TensorFlowFloatingPoint , yang akan membuat Tensor<Scalar> mematuhi Differentiable .

@differentiable(where Scalar: TensorFlowFloatingPoint)
infix operator .* : MultiplicationPrecedence

extension Tensor where Scalar: Numeric {
    @differentiable(where Scalar: TensorFlowFloatingPoint)
    static func .* (_ lhs: Tensor,  _ rhs: Tensor) -> Tensor {
        return _Raw.mul(lhs, rhs)
    }
}

extension Tensor where Scalar : TensorFlowFloatingPoint { 
    @derivative(of: .*)
    static func multiplyDerivative(
        _ lhs: Tensor, _ rhs: Tensor
    ) -> (value: Tensor, pullback: (Tensor) -> (Tensor, Tensor)) {
        return (lhs * rhs, { v in
            ((rhs * v).unbroadcasted(to: lhs.shape),
            (lhs * v).unbroadcasted(to: rhs.shape))
        })
    }
}

// Now, we can take the derivative of a function that calls `.*` that we just defined.
print(gradient(at: x, y) { x, y in
    (x .* y).sum()
})
(0.0, 0.0)

Lebih banyak contoh

let matrix = Tensor<Float>([[1, 2], [3, 4]])

print(_Raw.matMul(matrix, matrix, transposeA: true, transposeB: true))
print(_Raw.matMul(matrix, matrix, transposeA: true, transposeB: false))
print(_Raw.matMul(matrix, matrix, transposeA: false, transposeB: true))
print(_Raw.matMul(matrix, matrix, transposeA: false, transposeB: false))
[[ 7.0, 15.0],
 [10.0, 22.0]]
[[10.0, 14.0],
 [14.0, 20.0]]
[[ 5.0, 11.0],
 [11.0, 25.0]]
[[ 7.0, 10.0],
 [15.0, 22.0]]