Swift For TensorFlow prend en charge l'interopérabilité Python.
Vous pouvez importer des modules Python depuis Swift, appeler des fonctions Python et convertir des valeurs entre Swift et Python.
import PythonKit
print(Python.version)
3.6.9 (default, Oct 8 2020, 12:12:24) [GCC 8.4.0]
Définition de la version Python
Par défaut, lorsque vous import Python
, Swift recherche dans les chemins de bibliothèque système la dernière version de Python installée. Pour utiliser une installation Python spécifique, définissez la variable d'environnement PYTHON_LIBRARY
sur la bibliothèque partagée libpython
fournie par l'installation. Par exemple:
export PYTHON_LIBRARY="~/anaconda3/lib/libpython3.7m.so"
Le nom exact du fichier diffère selon les environnements et les plates-formes Python.
Vous pouvez également définir la variable d'environnement PYTHON_VERSION
, qui demande à Swift de rechercher dans les chemins de la bibliothèque système une version Python correspondante. Notez que PYTHON_LIBRARY
est prioritaire sur PYTHON_VERSION
.
Dans le code, vous pouvez également appeler la fonction PythonLibrary.useVersion
, ce qui équivaut à définir PYTHON_VERSION
.
// PythonLibrary.useVersion(2)
// PythonLibrary.useVersion(3, 7)
Remarque : vous devez exécuter PythonLibrary.useVersion
juste après import Python
, avant d'appeler du code Python. Il ne peut pas être utilisé pour changer dynamiquement de version de Python.
Définissez PYTHON_LOADER_LOGGING=1
pour voir la sortie de débogage pour le chargement de la bibliothèque Python .
Les bases
Dans Swift, PythonObject
représente un objet de Python. Toutes les API Python utilisent et renvoient des instances PythonObject
.
Les types de base dans Swift (comme les nombres et les tableaux) sont convertibles en PythonObject
. Dans certains cas (pour les littéraux et les fonctions prenant des arguments PythonConvertible
), la conversion se produit implicitement. Pour convertir explicitement une valeur Swift en PythonObject
, utilisez l'initialiseur PythonObject
.
PythonObject
définit de nombreuses opérations standard, notamment les opérations numériques, l'indexation et l'itération.
// 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
définit les conformités à de nombreux protocoles Swift standard :
-
Equatable
-
Comparable
-
Hashable
-
SignedNumeric
-
Strideable
-
MutableCollection
- Tous les protocoles
ExpressibleBy_Literal
Notez que ces conformités ne sont pas de type sécurisé : des plantages se produiront si vous tentez d'utiliser la fonctionnalité de protocole à partir d'une instance PythonObject
incompatible.
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
Pour convertir des tuples de Python en Swift, vous devez connaître statiquement l'arité du tuple.
Appelez l'une des méthodes d'instance suivantes :
-
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)
Intégrations Python
Accédez aux fonctions intégrées de Python via l'interface Python
globale.
// `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
Importation de modules Python
Utilisez Python.import
pour importer un module Python. Cela fonctionne comme le mot-clé import
en 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.]]
Utilisez la fonction de lancement Python.attemptImport
pour effectuer une importation sécurisée.
let maybeModule = try? Python.attemptImport("nonexistent_module")
print(maybeModule)
nil
Conversion avec numpy.ndarray
Les types Swift suivants peuvent être convertis vers et depuis numpy.ndarray
:
-
Array<Element>
-
ShapedArray<Scalar>
-
Tensor<Scalar>
La conversion ne réussit que si le dtype
de numpy.ndarray
est compatible avec le type de paramètre générique Element
ou Scalar
.
Pour Array
, la conversion depuis numpy
ne réussit que si numpy.ndarray
est 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.]
Afficher des images
Vous pouvez afficher des images en ligne à l'aide matplotlib
, tout comme dans les notebooks 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()
Use `print()` to show values.