Lihat di TensorFlow.org | Jalankan di Google Colab | 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]]