RSVP para seu evento TensorFlow Everywhere hoje mesmo!
Esta página foi traduzida pela API Cloud Translation.
Switch to English

Interoperabilidade Python

Ver no TensorFlow.org Executar no Google Colab Ver fonte no GitHub

Swift para TensorFlow é compatível com interoperabilidade Python.

Você pode importar módulos Python do Swift, chamar funções Python e converter valores entre Swift e Python.

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

Definir a versão Python

Por padrão, quando você import Python , o Swift procura os caminhos da biblioteca do sistema para a versão mais recente do Python instalada. Para usar uma instalação específica do Python, defina a variável de ambiente PYTHON_LIBRARY para a biblioteca compartilhada libpython fornecida pela instalação. Por exemplo:

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

O nome de arquivo exato será diferente nos ambientes e plataformas Python.

Como alternativa, você pode definir a variável de ambiente PYTHON_VERSION , que instrui o Swift a pesquisar os caminhos da biblioteca do sistema para uma versão correspondente do Python. Observe que PYTHON_LIBRARY tem precedência sobre PYTHON_VERSION .

No código, você também pode chamar a função PythonLibrary.useVersion , que é equivalente a definir PYTHON_VERSION .

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

Observação: você deve executar PythonLibrary.useVersion logo após import Python , antes de chamar qualquer código Python. Não pode ser usado para alternar dinamicamente as versões do Python.

Defina PYTHON_LOADER_LOGGING=1 para ver a saída de depuração para o carregamento da biblioteca Python .

Fundamentos

Em Swift, PythonObject representa um objeto de Python. Todas as APIs Python usam e retornam instâncias PythonObject .

Tipos básicos em Swift (como números e matrizes) são conversíveis em PythonObject . Em alguns casos (para literais e funções que PythonConvertible argumentos PythonConvertible ), a conversão ocorre implicitamente. Para converter explicitamente um valor Swift para PythonObject , use o inicializador PythonObject .

PythonObject define muitas operações padrão, incluindo operações numéricas, indexação e iteração.

// 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 define conformidade para muitos protocolos Swift padrão:

  • Equatable
  • Comparable
  • Hashable
  • SignedNumeric
  • Strideable
  • MutableCollection
  • Todos os protocolos ExpressibleBy_Literal

Observe que essas conformações não são seguras para o tipo: travamentos ocorrerão se você tentar usar a funcionalidade do protocolo de uma instância PythonObject incompatível.

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

Para converter tuplas de Python em Swift, você deve saber estaticamente a aridade da tupla.

Chame um dos seguintes métodos de instância:

  • 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 integrado

Acesse os recursos internos do Python por meio da interface global do 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

Importando módulos Python

Use Python.import para importar um módulo Python. Funciona como a palavra-chave import em 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.]]

Use a função de lançamento Python.attemptImport para realizar uma importação segura.

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

Conversão com numpy.ndarray

Os seguintes tipos de Swift podem ser convertidos de e para numpy.ndarray :

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

A conversão é bem-sucedida apenas se o dtype de numpy.ndarray for compatível com o tipo de parâmetro genérico Element ou Scalar .

Para Array , a conversão de numpy é bem-sucedida apenas se numpy.ndarray for 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.]

Exibindo imagens

Você pode exibir imagens in-line usando matplotlib , assim como em 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()

png

Use `print()` to show values.