Swift For TensorFlow는 Python 상호 운용성을 지원합니다.
Swift에서 Python 모듈을 가져오고, Python 함수를 호출하고, Swift와 Python 간에 값을 변환할 수 있습니다.
import PythonKit
print(Python.version)
3.6.9 (default, Oct 8 2020, 12:12:24) [GCC 8.4.0]
Python 버전 설정
기본적으로 import Python
때 Swift는 설치된 Python의 최신 버전에 대한 시스템 라이브러리 경로를 검색합니다. 특정 Python 설치를 사용하려면 PYTHON_LIBRARY
환경 변수를 설치 시 제공되는 libpython
공유 라이브러리로 설정하세요. 예를 들어:
export PYTHON_LIBRARY="~/anaconda3/lib/libpython3.7m.so"
정확한 파일 이름은 Python 환경과 플랫폼에 따라 다릅니다.
또는 Swift가 일치하는 Python 버전에 대한 시스템 라이브러리 경로를 검색하도록 지시하는 PYTHON_VERSION
환경 변수를 설정할 수 있습니다. PYTHON_LIBRARY
는 PYTHON_VERSION
보다 우선합니다.
코드에서는 PYTHON_VERSION
설정과 동일한 PythonLibrary.useVersion
함수를 호출할 수도 있습니다.
// PythonLibrary.useVersion(2)
// PythonLibrary.useVersion(3, 7)
참고: import Python
직후, Python 코드를 호출하기 전에 PythonLibrary.useVersion
실행해야 합니다. Python 버전을 동적으로 전환하는 데 사용할 수 없습니다.
Python 라이브러리 로딩에 대한 디버그 출력을 보려면 PYTHON_LOADER_LOGGING=1
설정합니다.
기초
Swift에서 PythonObject
Python의 객체를 나타냅니다. 모든 Python API는 PythonObject
인스턴스를 사용하고 반환합니다.
Swift의 기본 유형(숫자 및 배열 등)은 PythonObject
로 변환 가능합니다. 어떤 경우에는( PythonConvertible
인수를 사용하는 리터럴 및 함수의 경우) 변환이 암시적으로 발생합니다. Swift 값을 PythonObject
로 명시적으로 캐스팅하려면 PythonObject
이니셜라이저를 사용하세요.
PythonObject
숫자 연산, 인덱싱 및 반복을 포함한 많은 표준 연산을 정의합니다.
// 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
많은 표준 Swift 프로토콜에 대한 적합성을 정의합니다.
-
Equatable
-
Comparable
-
Hashable
-
SignedNumeric
-
Strideable
-
MutableCollection
- 모든
ExpressibleBy_Literal
프로토콜
이러한 적합성은 유형에 안전하지 않습니다. 호환되지 않는 PythonObject
인스턴스에서 프로토콜 기능을 사용하려고 하면 충돌이 발생합니다.
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
튜플을 Python에서 Swift로 변환하려면 튜플의 개수를 정적으로 알아야 합니다.
다음 인스턴스 메서드 중 하나를 호출합니다.
-
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)
Python 내장
전역 Python
인터페이스를 통해 Python 내장 기능에 액세스하세요.
// `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
Python 모듈 가져오기
Python.import
사용하여 Python 모듈을 가져옵니다. 이는 Python
의 import
키워드처럼 작동합니다.
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.]]
안전한 가져오기를 수행하려면 던지기 함수 Python.attemptImport
를 사용하세요.
let maybeModule = try? Python.attemptImport("nonexistent_module")
print(maybeModule)
nil
numpy.ndarray
사용한 변환
다음 Swift 유형을 numpy.ndarray
로 변환하거나 그 반대로 변환할 수 있습니다.
-
Array<Element>
-
ShapedArray<Scalar>
-
Tensor<Scalar>
numpy.ndarray
의 dtype
Element
또는 Scalar
일반 매개변수 유형과 호환되는 경우에만 변환이 성공합니다.
Array
의 경우 numpy.ndarray
1D인 경우에만 numpy
에서의 변환이 성공합니다.
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.]
이미지 표시
Python 노트북에서와 마찬가지로 matplotlib
사용하여 이미지를 인라인으로 표시할 수 있습니다.
// 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()
Use `print()` to show values.