TensorFlow.org'da görüntüleyin | Kaynağı GitHub'da görüntüle |
TensorFlow'u temel alan Swift for TensorFlow, API tasarımına yeni bir yaklaşım getiriyor. API'ler köklü kütüphanelerden özenle seçilmiş ve yeni dil deyimleriyle birleştirilmiştir. Bu, tüm TensorFlow API'lerinin doğrudan Swift API'leri olarak kullanılamayacağı ve API iyileştirmemizin gelişmesi için zamana ve özel çabaya ihtiyaç duyduğu anlamına gelir. Ancak, favori TensorFlow operatörünüz Swift'de mevcut değilse endişelenmeyin; TensorFlow Swift kitaplığı, _Raw
ad alanı altında çoğu TensorFlow operatörüne şeffaf erişim sağlar.
Başlamak için TensorFlow
içe aktarın.
import TensorFlow
Ham operatörlerin çağrılması
İhtiyacınız olan işlevi kod tamamlama yoluyla _Raw
ad alanı altında bulmanız yeterlidir.
print(_Raw.mul(Tensor([2.0, 3.0]), Tensor([5.0, 6.0])))
[10.0, 18.0]
Yeni bir çarpma operatörü tanımlama
Çarpma, Tensor
*
operatörü olarak zaten mevcuttur, ancak onu .*
olarak yeni bir adla kullanılabilir hale getirmek istediğimizi varsayalım. Swift, extension
bildirimlerini kullanarak mevcut türlere geriye dönük olarak yöntemler veya hesaplanan özellikler eklemenizi sağlar.
Şimdi Tensor
bir extension bildirerek .*
ekleyelim ve tensörün Scalar
tipi Numeric
uygun olduğunda bunu kullanılabilir hale getirelim.
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]]
Sarılmış bir fonksiyonun türevini tanımlama
Ham bir TensorFlow operatörü için kolayca bir Swift API tanımlamakla kalmaz, aynı zamanda Swift'in birinci sınıf otomatik farklılaştırmasıyla çalışmasını da türevlenebilir hale getirebilirsiniz.
.*
ı türevlenebilir yapmak için, türev işlevinde @derivative
niteliğini kullanın ve orijinal işlevi of:
etiketi altında bir öznitelik argümanı olarak belirtin. .*
operatörü, Scalar
genel türü Numeric
ile uyumlu olduğunda tanımlandığından, Tensor<Scalar>
Differentiable
protokole uygun hale getirilmesi yeterli değildir. Tür güvenliğiyle doğan Swift, bize Scalar
TensorFlowFloatingPoint
protokolüne uymasını gerektirecek şekilde @differentiable
niteliğine genel bir kısıtlama eklememizi hatırlatacak, bu da Tensor<Scalar>
Differentiable
ile uyumlu olmasını sağlayacaktır.
@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)
Daha fazla örnek
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]]