Cette page a été traduite par l'API Cloud Translation.
Switch to English

Interopérabilité Python

Voir sur TensorFlow.org Exécuter dans Google Colab Afficher la source sur GitHub

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, Jul 17 2020, 12:50:27) 
[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 de fichier exact diffère selon les environnements et plates-formes Python.

Vous pouvez également définir la variable d'environnement PYTHON_VERSION , qui indique à Swift de rechercher dans les chemins de 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 l' import Python , avant d'appeler un code Python. Il ne peut pas être utilisé pour changer dynamiquement les versions de Python.

Définissez PYTHON_LOADER_LOGGING=1 pour voir la sortie de débogage pour le chargement de la bibliothèque Python .

Basiques

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 PythonObject explicitement une valeur Swift en PythonObject , utilisez l'initialiseur PythonObject .

PythonObject définit de nombreuses opérations standard, y compris 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 essayez d'utiliser la fonctionnalité de protocole à partir d'une instance de 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égrés Python

Accédez aux fonctions intégrées de Python via l'interface globale 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

Importer des 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 réussit uniquement si le dtype de numpy.ndarray est compatible avec le type de paramètre générique Element ou Scalar .

Pour Array , la conversion à partir de 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.]

Affichage des images

Vous pouvez afficher des images en ligne à l'aide de matplotlib , comme dans les blocs-notes Python.

// This cell is here to display plots inside a Jupyter Notebook.
// Do not copy it into another environment.
%include "EnableIPythonDisplay.swift"
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

None