Khả năng tương tác Python

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub

Swift For TensorFlow hỗ trợ khả năng tương tác Python.

Bạn có thể nhập các mô-đun Python từ Swift, gọi các hàm Python và chuyển đổi các giá trị giữa Swift và Python.

import PythonKit
print(Python.version)
3.6.9 (default, Oct  8 2020, 12:12:24) 
[GCC 8.4.0]

Đặt phiên bản Python

Theo mặc định, khi bạn import Python , Swift sẽ tìm kiếm đường dẫn thư viện hệ thống để tìm phiên bản Python mới nhất được cài đặt. Để sử dụng bản cài đặt Python cụ thể, hãy đặt biến môi trường PYTHON_LIBRARY thành thư viện chia sẻ libpython do bản cài đặt cung cấp. Ví dụ:

export PYTHON_LIBRARY="~/anaconda3/lib/libpython3.7m.so"

Tên tệp chính xác sẽ khác nhau giữa các môi trường và nền tảng Python.

Ngoài ra, bạn có thể đặt biến môi trường PYTHON_VERSION , biến này hướng dẫn Swift tìm kiếm đường dẫn thư viện hệ thống để tìm phiên bản Python phù hợp. Lưu ý rằng PYTHON_LIBRARY được ưu tiên hơn PYTHON_VERSION .

Trong mã, bạn cũng có thể gọi hàm PythonLibrary.useVersion , tương đương với việc đặt PYTHON_VERSION .

// PythonLibrary.useVersion(2)
// PythonLibrary.useVersion(3, 7)

Lưu ý: bạn nên chạy PythonLibrary.useVersion ngay sau import Python , trước khi gọi bất kỳ mã Python nào. Nó không thể được sử dụng để tự động chuyển đổi các phiên bản Python.

Đặt PYTHON_LOADER_LOGGING=1 để xem kết quả gỡ lỗi khi tải thư viện Python .

Khái niệm cơ bản

Trong Swift, PythonObject đại diện cho một đối tượng từ Python. Tất cả các API Python đều sử dụng và trả về các phiên bản PythonObject .

Các kiểu cơ bản trong Swift (như số và mảng) có thể chuyển đổi thành PythonObject . Trong một số trường hợp (đối với các chữ và hàm lấy đối số PythonConvertible ), việc chuyển đổi diễn ra ngầm. Để chuyển một giá trị Swift thành PythonObject một cách rõ ràng, hãy sử dụng trình khởi tạo PythonObject .

PythonObject định nghĩa nhiều phép toán tiêu chuẩn, bao gồm các phép toán số, lập chỉ mục và lặp.

// Convert standard Swift types to Python.
let pythonInt: PythonObject = 1
let pythonFloat: PythonObject = 3.0
let pythonString: PythonObject = "Hello Python!"
let pythonRange: PythonObject = PythonObject(5..<10)
let pythonArray: PythonObject = [1, 2, 3, 4]
let pythonDict: PythonObject = ["foo": [0], "bar": [1, 2, 3]]

// Perform standard operations on Python objects.
print(pythonInt + pythonFloat)
print(pythonString[0..<6])
print(pythonRange)
print(pythonArray[2])
print(pythonDict["bar"])
4.0
Hello 
slice(5, 10, None)
3
[1, 2, 3]

// Convert Python objects back to Swift.
let int = Int(pythonInt)!
let float = Float(pythonFloat)!
let string = String(pythonString)!
let range = Range<Int>(pythonRange)!
let array: [Int] = Array(pythonArray)!
let dict: [String: [Int]] = Dictionary(pythonDict)!

// Perform standard operations.
// Outputs are the same as Python!
print(Float(int) + float)
print(string.prefix(6))
print(range)
print(array[2])
print(dict["bar"]!)
4.0
Hello 
5..<10
3
[1, 2, 3]

PythonObject xác định sự phù hợp với nhiều giao thức Swift tiêu chuẩn:

  • Equatable
  • Comparable
  • Hashable
  • SignedNumeric
  • Strideable
  • MutableCollection
  • Tất cả các giao thức ExpressibleBy_Literal

Lưu ý rằng những tuân thủ này không an toàn về mặt loại: sự cố sẽ xảy ra nếu bạn cố gắng sử dụng chức năng giao thức từ một phiên bản PythonObject không tương thích.

let one: PythonObject = 1
print(one == one)
print(one < one)
print(one + one)

let array: PythonObject = [1, 2, 3]
for (i, x) in array.enumerated() {
  print(i, x)
}
True
False
2
0 1
1 2
2 3

Để chuyển đổi các bộ dữ liệu từ Python sang Swift, bạn phải biết tĩnh về mức độ của bộ dữ liệu.

Gọi một trong các phương thức ví dụ sau:

  • PythonObject.tuple2
  • PythonObject.tuple3
  • PythonObject.tuple4
let pythonTuple = Python.tuple([1, 2, 3])
print(pythonTuple, Python.len(pythonTuple))

// Convert to Swift.
let tuple = pythonTuple.tuple3
print(tuple)
(1, 2, 3) 3
(1, 2, 3)

Nội dung Python

Truy cập nội dung Python thông qua giao diện Python toàn cầu.

// `Python.builtins` is a dictionary of all Python builtins.
_ = Python.builtins

// Try some Python builtins.
print(Python.type(1))
print(Python.len([1, 2, 3]))
print(Python.sum([1, 2, 3]))
<class 'int'>
3
6

Nhập mô-đun Python

Sử dụng Python.import để nhập mô-đun Python. Nó hoạt động giống như từ khóa import trong Python .

let np = Python.import("numpy")
print(np)
let zeros = np.ones([2, 3])
print(zeros)
<module 'numpy' from '/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/numpy/__init__.py'>
[[1. 1. 1.]
 [1. 1. 1.]]

Sử dụng hàm ném Python.attemptImport để thực hiện nhập an toàn.

let maybeModule = try? Python.attemptImport("nonexistent_module")
print(maybeModule)
nil

Chuyển đổi với numpy.ndarray

Các loại Swift sau có thể được chuyển đổi sang và từ numpy.ndarray :

  • Array<Element>
  • ShapedArray<Scalar>
  • Tensor<Scalar>

Chuyển đổi chỉ thành công nếu dtype của numpy.ndarray tương thích với loại tham số chung Element hoặc Scalar .

Đối với Array , việc chuyển đổi từ numpy chỉ thành công nếu numpy.ndarray là 1-D.

import TensorFlow

let numpyArray = np.ones([4], dtype: np.float32)
print("Swift type:", type(of: numpyArray))
print("Python type:", Python.type(numpyArray))
print(numpyArray.shape)
Swift type: PythonObject
Python type: <class 'numpy.ndarray'>
(4,)

// Examples of converting `numpy.ndarray` to Swift types.
let array: [Float] = Array(numpy: numpyArray)!
let shapedArray = ShapedArray<Float>(numpy: numpyArray)!
let tensor = Tensor<Float>(numpy: numpyArray)!

// Examples of converting Swift types to `numpy.ndarray`.
print(array.makeNumpyArray())
print(shapedArray.makeNumpyArray())
print(tensor.makeNumpyArray())

// Examples with different dtypes.
let doubleArray: [Double] = Array(numpy: np.ones([3], dtype: np.float))!
let intTensor = Tensor<Int32>(numpy: np.ones([2, 3], dtype: np.int32))!
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]

Hiển thị hình ảnh

Bạn có thể hiển thị hình ảnh nội tuyến bằng matplotlib , giống như trong sổ ghi chép Python.

// This cell is here to display plots inside a Jupyter Notebook.
// Do not copy it into another environment.
%include "EnableIPythonDisplay.swift"
print(IPythonDisplay.shell.enable_matplotlib("inline"))
('inline', 'module://ipykernel.pylab.backend_inline')

let np = Python.import("numpy")
let plt = Python.import("matplotlib.pyplot")

let time = np.arange(0, 10, 0.01)
let amplitude = np.exp(-0.1 * time)
let position = amplitude * np.sin(3 * time)

plt.figure(figsize: [15, 10])

plt.plot(time, position)
plt.plot(time, amplitude)
plt.plot(time, -amplitude)

plt.xlabel("Time (s)")
plt.ylabel("Position (m)")
plt.title("Oscillations")

plt.show()

png

Use `print()` to show values.