מפעילי TensorFlow גולמיים

הצג באתר TensorFlow.org צפה במקור ב-GitHub

בהתבסס על TensorFlow, Swift for TensorFlow נוקטת בגישה חדשה לעיצוב API. ממשקי API אוצרים בקפידה מספריות מבוססות ומשולבים עם ניבים בשפה חדשה. המשמעות היא שלא כל ממשקי ה-API של TensorFlow יהיו זמינים ישירות כממשקי API של Swift, ואצירת ה-API שלנו זקוקה לזמן ולמאמץ מסור כדי להתפתח. עם זאת, אל תדאג אם אופרטור TensorFlow המועדף עליך אינו זמין ב-Swift -- ספריית TensorFlow Swift מעניקה לך גישה שקופה לרוב אופרטורי TensorFlow, תחת מרחב השמות _Raw .

יבא את TensorFlow כדי להתחיל.

import TensorFlow

מתקשר למפעילים גולמיים

כל שעליך לעשות הוא למצוא את הפונקציה שאתה צריך תחת מרחב השמות _Raw באמצעות השלמת קוד.

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

הגדרת אופרטור כפל חדש

Multiply כבר זמין בתור אופרטור * ב- Tensor , אבל הבה נעמיד פנים שרצינו להפוך אותו זמין תחת שם חדש בשם .* . Swift מאפשר לך להוסיף רטרואקטיבית שיטות או מאפיינים מחושבים לסוגים קיימים באמצעות הצהרות extension .

כעת, הבה נוסיף .* ל- Tensor על-ידי הכרזה על הרחבה ונהפוך אותה לזמינה כאשר הסוג Scalar של הטנסור תואם ל- 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]]

הגדרת נגזרת של פונקציה עטופה

לא רק שאתה יכול להגדיר בקלות ממשק API של Swift עבור מפעיל TensorFlow גולמי, אתה יכול גם להפוך אותו לניתן להבדיל לעבוד עם הבידול האוטומטי מהמעלה הראשונה של Swift.

כדי להפוך את .* לניתנת להבדלה, השתמש בתכונה @derivative בפונקציה הנגזרת וציין את הפונקציה המקורית כארגומנט תכונה תחת התווית of: מכיוון שהאופרטור .* מוגדר כאשר הסוג הגנרי Scalar תואם ל- Numeric , זה לא מספיק כדי לגרום Tensor<Scalar> להתאים לפרוטוקול Differentiable . סוויפט, שנולד עם בטיחות סוג, תזכיר לנו להוסיף אילוץ גנרי על התכונה @differentiable כדי לחייב Scalar להתאים לפרוטוקול TensorFlowFloatingPoint , מה שיגרום Tensor<Scalar> להתאים ל- 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)

דוגמאות נוספות

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