ดูบน TensorFlow.org | ดูแหล่งที่มาบน GitHub |
Swift สำหรับ TensorFlow สร้างขึ้นบน TensorFlow ใช้แนวทางใหม่ในการออกแบบ API API ได้รับการดูแลจัดการอย่างระมัดระวังจากไลบรารีที่จัดตั้งขึ้นและรวมกับสำนวนภาษาใหม่ ซึ่งหมายความว่า TensorFlow API บางรายการจะพร้อมใช้งานโดยตรงในรูปแบบ Swift API และการดูแลจัดการ 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]]
การกำหนดอนุพันธ์ของฟังก์ชันที่ห่อไว้
ไม่เพียงแต่คุณสามารถกำหนด Swift API สำหรับตัวดำเนินการ TensorFlow แบบดิบได้เท่านั้น คุณยังสามารถสร้างความแตกต่างในการทำงานกับการสร้างความแตกต่างอัตโนมัติระดับเฟิร์สคลาสของ Swift ได้อีกด้วย
หากต้องการทำให้ .*
สามารถหาอนุพันธ์ได้ ให้ใช้แอตทริบิวต์ @derivative
บนฟังก์ชันอนุพันธ์ และระบุฟังก์ชันดั้งเดิมเป็นอาร์กิวเมนต์แอตทริบิวต์ภายใต้ป้ายกำกับ of:
เนื่องจากตัวดำเนินการ .*
ถูกกำหนดไว้เมื่อ Scalar
ประเภททั่วไปสอดคล้องกับ Numeric
จึงไม่เพียงพอสำหรับการทำให้ Tensor<Scalar>
สอดคล้องกับโปรโตคอล Differentiable
Swift จะเตือนให้เราเพิ่มข้อจำกัดทั่วไปในแอตทริบิวต์ @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]]