Ham TensorFlow operatörleri

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]]