הצג באתר 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]]