Mam pytanie? Połącz się ze społecznością na Forum TensorFlow Odwiedź Forum

Przeprowadź migrację kodu TensorFlow 1 do TensorFlow 2

Zobacz na TensorFlow.org Uruchom w Google Colab Wyświetl źródło w serwisie GitHub Pobierz notatnik

Ten przewodnik jest przeznaczony dla użytkowników niskopoziomowych interfejsów API TensorFlow. Jeśli korzystasz z interfejsów API wysokiego poziomu ( tf.keras ), może być niewiele lub nie musisz nic robić, aby Twój kod był w pełni zgodny z TensorFlow 2.x:

W TensorFlow 2.x nadal można uruchamiać niezmodyfikowany kod 1.x ( z wyjątkiem contrib ):

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

Jednak nie pozwala to na skorzystanie z wielu ulepszeń wprowadzonych w TensorFlow 2.x. Ten przewodnik pomoże Ci zaktualizować kod, czyniąc go prostszym, wydajniejszym i łatwiejszym w utrzymaniu.

Automatyczny skrypt konwersji

Pierwszym krokiem, przed przystąpieniem do wprowadzenia zmian opisanych w tym przewodniku, jest próba uruchomienia skryptu aktualizacji .

Spowoduje to wykonanie początkowego przejścia podczas aktualizacji kodu do TensorFlow 2.x, ale nie może uczynić kodu idiomatycznym do v2. Twój kod może nadal korzystać z punktów końcowych tf.compat.v1 aby uzyskać dostęp do tf.compat.v1 zastępczych, sesji, kolekcji i innych funkcji w stylu 1.x.

Zmiany behawioralne na najwyższym poziomie

Jeśli Twój kod działa w TensorFlow 2.x przy użyciu tf.compat.v1.disable_v2_behavior , nadal istnieją globalne zmiany w zachowaniu, które mogą wymagać rozwiązania. Główne zmiany to:

  • Zachłanne wykonanie, v1.enable_eager_execution() : każdy kod, który niejawnie używa tf.Graph , zakończy się niepowodzeniem. Pamiętaj, aby opakować ten kod w with tf.Graph().as_default() .

  • Zmienne zasobów, v1.enable_resource_variables() : Część kodu może zależeć od niedeterministycznych zachowań włączonych przez zmienne referencyjne TensorFlow. Zmienne zasobów są blokowane podczas zapisywania, dzięki czemu zapewniają bardziej intuicyjne gwarancje spójności.

    • Może to zmienić zachowanie w skrajnych przypadkach.
    • Może to spowodować utworzenie dodatkowych kopii i większe zużycie pamięci.
    • Można to wyłączyć, przekazując use_resource=False do konstruktora tf.Variable .
  • Kształty v1.enable_v2_tensorshape() , v1.enable_v2_tensorshape() : TensorFlow 2.x upraszcza zachowanie kształtów tensorów. Zamiast t.shape[0].value możesz powiedzieć t.shape[0] . Te zmiany powinny być niewielkie i warto je naprawić od razu. Przykłady można znaleźć w sekcji TensorShape .

  • Przepływ sterowania, v1.enable_control_flow_v2() : Implementacja przepływu sterowania TensorFlow 2.x została uproszczona, dzięki czemu tworzy różne reprezentacje wykresów. Prosimy o zgłaszanie błędów w przypadku jakichkolwiek problemów.

Utwórz kod dla TensorFlow 2.x

W tym przewodniku omówiono kilka przykładów konwersji kodu TensorFlow 1.x do TensorFlow 2.x. Te zmiany pozwolą Twojemu kodowi skorzystać z optymalizacji wydajności i uproszczonych wywołań interfejsu API.

W każdym przypadku wzór to:

1. Zastąp połączenia v1.Session.run

Każde wywołanie v1.Session.run powinno zostać zastąpione funkcją Pythona.

  • feed_dict i v1.placeholder s stają się argumentami funkcji.
  • fetches stają się wartością zwracaną przez funkcję.
  • Podczas konwersji szybkie wykonanie umożliwia łatwe debugowanie za pomocą standardowych narzędzi Pythona, takich jak pdb .

Następnie dodaj dekorator tf.function aby działał wydajnie na wykresie. Sprawdź przewodnik po autografach, aby uzyskać więcej informacji o tym, jak to działa.

Zauważ, że:

  • W przeciwieństwie do v1.Session.run , tf.function ma stałą sygnaturę powrotu i zawsze zwraca wszystkie dane wyjściowe. Jeśli powoduje to problemy z wydajnością, utwórz dwie oddzielne funkcje.

  • Nie ma potrzeby wykonywania tf.control_dependencies lub podobnych operacji: tf.function zachowuje się tak, jakby została uruchomiona w zapisanej kolejności. tf.Variable przypisania tf.Variable i tf.assert s są wykonywane automatycznie.

Sekcja konwersji modeli zawiera działający przykład tego procesu konwersji.

2. Używaj obiektów Pythona do śledzenia zmiennych i strat

Wszelkie śledzenie zmiennych opartych na nazwach jest zdecydowanie odradzane w TensorFlow 2.x. Użyj obiektów Pythona do śledzenia zmiennych.

Użyj tf.Variable zamiast v1.get_variable .

Każda v1.variable_scope powinna zostać przekonwertowana na obiekt Pythona. Zwykle będzie to jeden z następujących:

Jeśli chcesz zagregować listy zmiennych (np. tf.Graph.get_collection(tf.GraphKeys.VARIABLES) ), użyj .variables i .trainable_variables obiektów Layer i Model .

Te klasy Layer i Model implementują kilka innych właściwości, które eliminują potrzebę stosowania kolekcji globalnych. Ich właściwość .losses może zastąpić używanie kolekcji tf.GraphKeys.LOSSES .

Więcej informacji znajdziesz w przewodnikach Keras .

3. Zaktualizuj swoje pętle treningowe

Użyj interfejsu API najwyższego poziomu, który działa w Twoim przypadku użycia. Preferuj tf.keras.Model.fit tworzenia własnych pętli treningowych.

Te funkcje wysokiego poziomu zarządzają wieloma szczegółami niskiego poziomu, które można łatwo przeoczyć, jeśli napiszesz własną pętlę treningową. Na przykład automatycznie zbierają straty regularyzacyjne i ustawiają argument training=True podczas wywoływania modelu.

4. Zaktualizuj potoki wprowadzania danych

Użyj zbiorów danych tf.data do wprowadzania danych. Obiekty te są wydajne, wyraziste i dobrze integrują się z tensorflow.

Można je przekazać bezpośrednio do metody tf.keras.Model.fit .

model.fit(dataset, epochs=5)

Mogą być iterowane bezpośrednio w standardowym Pythonie:

for example_batch, label_batch in dataset:
    break

5. Przenieś symbole compat.v1

Moduł tf.compat.v1 zawiera kompletne API TensorFlow 1.x z jego oryginalną semantyką.

Skrypt uaktualniający TensorFlow 2.x przekonwertuje symbole na ich odpowiedniki v2, jeśli taka konwersja jest bezpieczna, tj. Jeśli może określić, że zachowanie wersji TensorFlow 2.x jest dokładnie równoważne (na przykład zmieni nazwę v1.arg_max do tf.argmax , ponieważ są to ta sama funkcja).

Po zakończeniu aktualizacji skryptu z fragmentem kodu prawdopodobnie pojawiło się wiele wzmianek o compat.v1 . Warto przejrzeć kod i przekonwertować je ręcznie na odpowiednik v2 (należy o tym wspomnieć w logu, jeśli taki istnieje).

Konwertowanie modeli

Zmienne niskiego poziomu i wykonanie operatora

Przykłady niskopoziomowego interfejsu API obejmują:

  • Używanie zmiennych zakresów do kontrolowania ponownego użycia.
  • Tworzenie zmiennych z v1.get_variable .
  • Dostęp do kolekcji w sposób jawny.
  • Dostęp do kolekcji niejawnie za pomocą metod takich jak:

  • Używanie v1.placeholder do konfigurowania danych wejściowych wykresu.

  • Wykonywanie wykresów za pomocą Session.run .

  • Ręczne inicjowanie zmiennych.

Przed konwersją

Oto, jak te wzorce mogą wyglądać w kodzie używającym TensorFlow 1.x.

import tensorflow as tf
import tensorflow.compat.v1 as v1

import tensorflow_datasets as tfds
g = v1.Graph()

with g.as_default():
  in_a = v1.placeholder(dtype=v1.float32, shape=(2))
  in_b = v1.placeholder(dtype=v1.float32, shape=(2))

  def forward(x):
    with v1.variable_scope("matmul", reuse=v1.AUTO_REUSE):
      W = v1.get_variable("W", initializer=v1.ones(shape=(2,2)),
                          regularizer=lambda x:tf.reduce_mean(x**2))
      b = v1.get_variable("b", initializer=v1.zeros(shape=(2)))
      return W * x + b

  out_a = forward(in_a)
  out_b = forward(in_b)
  reg_loss=v1.losses.get_regularization_loss(scope="matmul")

with v1.Session(graph=g) as sess:
  sess.run(v1.global_variables_initializer())
  outs = sess.run([out_a, out_b, reg_loss],
                feed_dict={in_a: [1, 0], in_b: [0, 1]})

print(outs[0])
print()
print(outs[1])
print()
print(outs[2])
[[1. 0.]
 [1. 0.]]

[[0. 1.]
 [0. 1.]]

1.0

Po konwersji

W przekonwertowanym kodzie:

  • Zmienne są lokalnymi obiektami Pythona.
  • Funkcja forward nadal definiuje obliczenia.
  • Połączenie Session.run zostaje zastąpione połączeniem do forward .
  • W tf.function zwiększenia wydajności można dodać opcjonalny dekorator funkcji tf.function .
  • Regularyzacje są obliczane ręcznie, bez odwoływania się do żadnego zbioru globalnego.
  • Nie ma użycia sesji ani symboli zastępczych .
W = tf.Variable(tf.ones(shape=(2,2)), name="W")
b = tf.Variable(tf.zeros(shape=(2)), name="b")

@tf.function
def forward(x):
  return W * x + b

out_a = forward([1,0])
print(out_a)
tf.Tensor(
[[1. 0.]
 [1. 0.]], shape=(2, 2), dtype=float32)
out_b = forward([0,1])

regularizer = tf.keras.regularizers.l2(0.04)
reg_loss=regularizer(W)

Modele oparte na tf.layers

Moduł v1.layers jest używany do przechowywania funkcji warstwy, które opierały się na v1.variable_scope celu definiowania i ponownego wykorzystywania zmiennych.

Przed konwersją

def model(x, training, scope='model'):
  with v1.variable_scope(scope, reuse=v1.AUTO_REUSE):
    x = v1.layers.conv2d(x, 32, 3, activation=v1.nn.relu,
          kernel_regularizer=lambda x:0.004*tf.reduce_mean(x**2))
    x = v1.layers.max_pooling2d(x, (2, 2), 1)
    x = v1.layers.flatten(x)
    x = v1.layers.dropout(x, 0.1, training=training)
    x = v1.layers.dense(x, 64, activation=v1.nn.relu)
    x = v1.layers.batch_normalization(x, training=training)
    x = v1.layers.dense(x, 10)
    return x
train_data = tf.ones(shape=(1, 28, 28, 1))
test_data = tf.ones(shape=(1, 28, 28, 1))

train_out = model(train_data, training=True)
test_out = model(test_data, training=False)

print(train_out)
print()
print(test_out)
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/convolutional.py:414: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  warnings.warn('`tf.layers.conv2d` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py:2273: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  warnings.warn('`layer.apply` is deprecated and '
tf.Tensor([[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]], shape=(1, 10), dtype=float32)

tf.Tensor(
[[ 0.379358   -0.55901194  0.48704922  0.11619566  0.23902717  0.01691487
   0.07227738  0.14556988  0.2459927   0.2501198 ]], shape=(1, 10), dtype=float32)
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/pooling.py:310: UserWarning: `tf.layers.max_pooling2d` is deprecated and will be removed in a future version. Please use `tf.keras.layers.MaxPooling2D` instead.
  warnings.warn('`tf.layers.max_pooling2d` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/core.py:329: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  warnings.warn('`tf.layers.flatten` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/core.py:268: UserWarning: `tf.layers.dropout` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dropout` instead.
  warnings.warn('`tf.layers.dropout` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/core.py:171: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
  warnings.warn('`tf.layers.dense` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/normalization.py:308: UserWarning: `tf.layers.batch_normalization` is deprecated and will be removed in a future version. Please use `tf.keras.layers.BatchNormalization` instead. In particular, `tf.control_dependencies(tf.GraphKeys.UPDATE_OPS)` should not be used (consult the `tf.keras.layers.BatchNormalization` documentation).
  '`tf.layers.batch_normalization` is deprecated and '

Po konwersji

Większość argumentów pozostała taka sama. Ale zwróć uwagę na różnice:

  • Argument training jest przekazywany do każdej warstwy przez model podczas jego działania.
  • Pierwszy argument oryginalnej funkcji model (wejście x ) zniknął. Dzieje się tak, ponieważ warstwy obiektów oddzielają budowanie modelu od wywoływania modelu.

Pamiętaj również, że:

  • Jeśli używasz regulatorów lub inicjatorów z tf.contrib , mają one więcej zmian argumentów niż inne.
  • Kod nie zapisuje już w kolekcjach, więc funkcje takie jak v1.losses.get_regularization_loss nie będą już zwracać tych wartości, potencjalnie przerywając pętle szkoleniowe.
model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.04),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

train_data = tf.ones(shape=(1, 28, 28, 1))
test_data = tf.ones(shape=(1, 28, 28, 1))
train_out = model(train_data, training=True)
print(train_out)
tf.Tensor([[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]], shape=(1, 10), dtype=float32)
test_out = model(test_data, training=False)
print(test_out)
tf.Tensor(
[[-0.2145557  -0.22979769 -0.14968733  0.01208701 -0.07569927  0.3475932
   0.10718458  0.03482988 -0.04309493 -0.10469118]], shape=(1, 10), dtype=float32)
# Here are all the trainable variables
len(model.trainable_variables)
8
# Here is the regularization loss
model.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.08174552>]

Zmienne mieszane i v1.layers

Istniejący kod często miesza zmienne niższego poziomu TensorFlow 1.x i operacje z v1.layers wyższego poziomu v1.layers .

Przed konwersją

def model(x, training, scope='model'):
  with v1.variable_scope(scope, reuse=v1.AUTO_REUSE):
    W = v1.get_variable(
      "W", dtype=v1.float32,
      initializer=v1.ones(shape=x.shape),
      regularizer=lambda x:0.004*tf.reduce_mean(x**2),
      trainable=True)
    if training:
      x = x + W
    else:
      x = x + W * 0.5
    x = v1.layers.conv2d(x, 32, 3, activation=tf.nn.relu)
    x = v1.layers.max_pooling2d(x, (2, 2), 1)
    x = v1.layers.flatten(x)
    return x

train_out = model(train_data, training=True)
test_out = model(test_data, training=False)

Po konwersji

Aby przekonwertować ten kod, postępuj zgodnie ze schematem mapowania warstw na warstwy, jak w poprzednim przykładzie.

Ogólny wzorzec to:

  • Zbierz parametry warstwy w __init__ .
  • Zbuduj zmienne w build .
  • Wykonaj obliczenia w call i zwróć wynik.

v1.variable_scope jest w zasadzie v1.variable_scope warstwą. Więc przepisz go jako tf.keras.layers.Layer . Aby uzyskać szczegółowe informacje, zapoznaj się z przewodnikiem Tworzenie nowych warstw i modeli za pomocą podklas .

# Create a custom layer for part of the model
class CustomLayer(tf.keras.layers.Layer):
  def __init__(self, *args, **kwargs):
    super(CustomLayer, self).__init__(*args, **kwargs)

  def build(self, input_shape):
    self.w = self.add_weight(
        shape=input_shape[1:],
        dtype=tf.float32,
        initializer=tf.keras.initializers.ones(),
        regularizer=tf.keras.regularizers.l2(0.02),
        trainable=True)

  # Call method will sometimes get used in graph mode,
  # training will get turned into a tensor
  @tf.function
  def call(self, inputs, training=None):
    if training:
      return inputs + self.w
    else:
      return inputs + self.w * 0.5
custom_layer = CustomLayer()
print(custom_layer([1]).numpy())
print(custom_layer([1], training=True).numpy())
[1.5]
[2.]
train_data = tf.ones(shape=(1, 28, 28, 1))
test_data = tf.ones(shape=(1, 28, 28, 1))

# Build the model including the custom layer
model = tf.keras.Sequential([
    CustomLayer(input_shape=(28, 28, 1)),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
])

train_out = model(train_data, training=True)
test_out = model(test_data, training=False)

Kilka uwag:

  • Modele i warstwy podklasowe Keras muszą działać zarówno na wykresach w wersji 1 (bez zależności automatycznego sterowania), jak iw trybie przyspieszonym:

    • Zawiń call tf.function aby uzyskać autograf i zależności automatycznego sterowania.
  • Nie zapomnij przyjąć argumentu training aby call :

    • Czasami jest to tf.Tensor
    • Czasami jest to wartość logiczna Pythona
  • Utwórz zmienne modelu w konstruktorze lub Model.build przy użyciu `self.add_weight:

  • Nie trzymaj tf.Tensors w swoich obiektach:

    • Mogą zostać utworzone w tf.function lub w tf.function kontekście, a te tensory zachowują się inaczej
    • Użyj tf.Variable jako stanu, są one zawsze używane w obu kontekstach
    • tf.Tensors są tylko dla wartości pośrednich

Uwaga na temat Slim i contrib .layers

Duża część starszego kodu TensorFlow 1.x korzysta z biblioteki Slim , która została dołączona do TensorFlow 1.x jako tf.contrib.layers . Jako contrib modułu, to nie jest już dostępna w TensorFlow 2.x, nawet w tf.compat.v1 . Konwersja kodu za pomocą Slim do TensorFlow 2.x jest bardziej skomplikowana niż konwersja repozytoriów korzystających z v1.layers . W rzeczywistości sensowne może v1.layers najpierw przekonwertowanie kodu Slim do v1.layers , a następnie przekonwertowanie go na Keras.

  • Usuń arg_scopes , wszystkie argumenty muszą być jawne.
  • Jeśli ich używasz, podziel normalizer_fn i activation_fn na ich własne warstwy.
  • Oddzielne warstwy konw. Mapują się na jedną lub więcej różnych warstw Keras (głębokie, punktowe i oddzielne warstwy Keras).
  • v1.layers Slim i v1.layers mają różne nazwy argumentów i wartości domyślne.
  • Niektóre argumenty mają różne skale.
  • Jeśli używasz wstępnie wytrenowanych modeli Slim, wypróbuj wstępnie trenowane modele Keras z tf.keras.applications lub TensorFlow 2.x SavedModels TF Hub wyeksportowane z oryginalnego kodu Slim.

Niektóre warstwy tf.contrib mogły nie zostać przeniesione do rdzenia TensorFlow, ale zamiast tego zostały przeniesione do pakietu TensorFlow Addons .

Trening

Istnieje wiele sposobów dostarczania danych do modelu tf.keras . Będą akceptować generatory Pythona i tablice Numpy jako dane wejściowe.

Zalecanym sposobem dostarczania danych do modelu jest użycie pakietu tf.data , który zawiera kolekcję klas o wysokiej wydajności do manipulowania danymi.

Jeśli nadal używasz tf.queue , są one teraz obsługiwane tylko jako struktury danych, a nie jako potoki wejściowe.

Korzystanie z zestawów danych TensorFlow

TensorFlow zestawów danych pakiet ( tfds ) zawiera narzędzia do wczytywania predefiniowanych zestawów danych jakotf.data.Dataset obiektów.

W tym przykładzie możesz załadować zestaw danych tfds za pomocą tfds :

datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets['train'], datasets['test']
Downloading and preparing dataset mnist/3.0.1 (download: 11.06 MiB, generated: 21.00 MiB, total: 32.06 MiB) to /home/kbuilder/tensorflow_datasets/mnist/3.0.1...
WARNING:absl:Dataset mnist is hosted on GCS. It will automatically be downloaded to your
local data directory. If you'd instead prefer to read directly from our public
GCS bucket (recommended if you're running on GCP), you can instead pass
`try_gcs=True` to `tfds.load` or set `data_dir=gs://tfds-data/datasets`.
Dataset mnist downloaded and prepared to /home/kbuilder/tensorflow_datasets/mnist/3.0.1. Subsequent calls will reuse this data.

Następnie przygotuj dane do treningu:

  • Ponownie przeskaluj każdy obraz.
  • Potasuj kolejność przykładów.
  • Zbieraj partie obrazów i etykiet.
BUFFER_SIZE = 10 # Use a much larger value for real code
BATCH_SIZE = 64
NUM_EPOCHS = 5


def scale(image, label):
  image = tf.cast(image, tf.float32)
  image /= 255

  return image, label

Aby przykład był krótki, przytnij zbiór danych, aby zwracał tylko 5 partii:

train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
test_data = mnist_test.map(scale).batch(BATCH_SIZE)

STEPS_PER_EPOCH = 5

train_data = train_data.take(STEPS_PER_EPOCH)
test_data = test_data.take(STEPS_PER_EPOCH)
image_batch, label_batch = next(iter(train_data))

Użyj pętli treningowych Keras

Jeśli nie potrzebujesz niskopoziomowej kontroli procesu treningowego, zalecane jest użycie wbudowanych metod fit , evaluate i predict Keras. Metody te zapewniają jednolity interfejs do uczenia modelu niezależnie od implementacji (sekwencyjnej, funkcjonalnej lub podklasowej).

Zalety tych metod obejmują:

  • Akceptują tablice Numpy, generatory Pythona i tf.data.Datasets .
  • Automatycznie stosują regularyzację i straty aktywacji.
  • Obsługują tf.distribute do tf.distribute na wielu urządzeniach .
  • Obsługują arbitralne wywołania jako straty i metryki.
  • Obsługują wywołania zwrotne, takie jak tf.keras.callbacks.TensorBoard i niestandardowe wywołania zwrotne.
  • Są wydajne, automatycznie przy użyciu wykresów TensorFlow.

Oto przykład uczenia modelu przy użyciu Dataset . (Aby uzyskać szczegółowe informacje na temat tego, jak to działa, zapoznaj się z sekcją samouczków ).

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

# Model is the full model w/o custom layers
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_data, epochs=NUM_EPOCHS)
loss, acc = model.evaluate(test_data)

print("Loss {}, Accuracy {}".format(loss, acc))
Epoch 1/5
5/5 [==============================] - 1s 9ms/step - loss: 2.0191 - accuracy: 0.3608
Epoch 2/5
5/5 [==============================] - 0s 9ms/step - loss: 0.4736 - accuracy: 0.9059
Epoch 3/5
5/5 [==============================] - 0s 8ms/step - loss: 0.2973 - accuracy: 0.9626
Epoch 4/5
5/5 [==============================] - 0s 9ms/step - loss: 0.2108 - accuracy: 0.9911
Epoch 5/5
5/5 [==============================] - 0s 8ms/step - loss: 0.1791 - accuracy: 0.9874
5/5 [==============================] - 0s 6ms/step - loss: 1.5504 - accuracy: 0.7500
Loss 1.5504140853881836, Accuracy 0.75

Napisz własną pętlę

Jeśli krok treningowy modelu Keras działa dla Ciebie, ale potrzebujesz większej kontroli poza tym krokiem, rozważ użycie metody tf.keras.Model.train_on_batch we własnej pętli iteracji danych.

Pamiętaj: wiele rzeczy można zaimplementować jako tf.keras.callbacks.Callback .

Ta metoda ma wiele zalet metod wymienionych w poprzedniej sekcji, ale daje użytkownikowi kontrolę nad zewnętrzną pętlą.

Możesz również użyć tf.keras.Model.test_on_batch lub tf.keras.Model.evaluate aby sprawdzić wydajność podczas treningu.

Aby kontynuować szkolenie powyższego modelu:

# Model is the full model w/o custom layers
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

for epoch in range(NUM_EPOCHS):
  # Reset the metric accumulators
  model.reset_metrics()

  for image_batch, label_batch in train_data:
    result = model.train_on_batch(image_batch, label_batch)
    metrics_names = model.metrics_names
    print("train: ",
          "{}: {:.3f}".format(metrics_names[0], result[0]),
          "{}: {:.3f}".format(metrics_names[1], result[1]))
  for image_batch, label_batch in test_data:
    result = model.test_on_batch(image_batch, label_batch,
                                 # Return accumulated metrics
                                 reset_metrics=False)
  metrics_names = model.metrics_names
  print("\neval: ",
        "{}: {:.3f}".format(metrics_names[0], result[0]),
        "{}: {:.3f}".format(metrics_names[1], result[1]))
train:  loss: 0.138 accuracy: 1.000
train:  loss: 0.161 accuracy: 1.000
train:  loss: 0.159 accuracy: 0.969
train:  loss: 0.241 accuracy: 0.953
train:  loss: 0.172 accuracy: 0.969

eval:  loss: 1.550 accuracy: 0.800
train:  loss: 0.086 accuracy: 1.000
train:  loss: 0.094 accuracy: 1.000
train:  loss: 0.090 accuracy: 1.000
train:  loss: 0.119 accuracy: 0.984
train:  loss: 0.099 accuracy: 1.000

eval:  loss: 1.558 accuracy: 0.841
train:  loss: 0.076 accuracy: 1.000
train:  loss: 0.068 accuracy: 1.000
train:  loss: 0.061 accuracy: 1.000
train:  loss: 0.076 accuracy: 1.000
train:  loss: 0.076 accuracy: 1.000

eval:  loss: 1.536 accuracy: 0.841
train:  loss: 0.059 accuracy: 1.000
train:  loss: 0.056 accuracy: 1.000
train:  loss: 0.058 accuracy: 1.000
train:  loss: 0.054 accuracy: 1.000
train:  loss: 0.055 accuracy: 1.000

eval:  loss: 1.497 accuracy: 0.863
train:  loss: 0.053 accuracy: 1.000
train:  loss: 0.049 accuracy: 1.000
train:  loss: 0.044 accuracy: 1.000
train:  loss: 0.049 accuracy: 1.000
train:  loss: 0.045 accuracy: 1.000

eval:  loss: 1.463 accuracy: 0.878

Dostosuj etap szkolenia

Jeśli potrzebujesz większej elastyczności i kontroli, możesz to osiągnąć, wdrażając własną pętlę treningową. Istnieją trzy kroki:

  1. tf.data.Dataset po generatorze Pythona lubtf.data.Dataset aby uzyskać partie przykładów.
  2. Użyjtf.GradientTape do zbierania gradientów.
  3. Użyj jednego z tf.keras.optimizers aby zastosować aktualizacje wagi do zmiennych modelu.

Zapamiętaj:

  • Zawsze dołączaj argument training w metodzie call warstw i modeli z podklasami.
  • Upewnij się, aby zadzwonić do modelu ze training zestaw argumentów poprawnie.
  • W zależności od zastosowania zmienne modelu mogą nie istnieć, dopóki model nie zostanie uruchomiony na partii danych.
  • Musisz ręcznie obsługiwać takie rzeczy, jak straty regularyzacyjne dla modelu.

Zwróć uwagę na uproszczenia w stosunku do wersji 1:

  • Nie ma potrzeby uruchamiania inicjalizatorów zmiennych. Zmienne są inicjalizowane podczas tworzenia.
  • Nie ma potrzeby dodawania zależności sterowania ręcznego. Nawet w tf.function operacje działają jak w trybie tf.function .
model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

optimizer = tf.keras.optimizers.Adam(0.001)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

@tf.function
def train_step(inputs, labels):
  with tf.GradientTape() as tape:
    predictions = model(inputs, training=True)
    regularization_loss=tf.math.add_n(model.losses)
    pred_loss=loss_fn(labels, predictions)
    total_loss=pred_loss + regularization_loss

  gradients = tape.gradient(total_loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))

for epoch in range(NUM_EPOCHS):
  for inputs, labels in train_data:
    train_step(inputs, labels)
  print("Finished epoch", epoch)
Finished epoch 0
Finished epoch 1
Finished epoch 2
Finished epoch 3
Finished epoch 4

Metryki i straty w nowym stylu

W TensorFlow 2.x metryki i straty są obiektami. Działają one zarówno chętnie, jak iw tf.function s.

Obiekt straty jest wywoływalny i oczekuje (y_true, y_pred) jako argumentów:

cce = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
cce([[1, 0]], [[-1.0,3.0]]).numpy()
4.01815

Obiekt metryczny ma następujące metody:

  • Metric.update_state() : dodaj nowe obserwacje.
  • Metric.result() : pobiera bieżący wynik metryki, biorąc pod uwagę zaobserwowane wartości.
  • Metric.reset_states() : wyczyść wszystkie obserwacje.

Sam obiekt jest wywoływalny. Wywołanie aktualizuje stan nowymi obserwacjami, tak jak w przypadku update_state , i zwraca nowy wynik metryki.

Nie musisz ręcznie inicjować zmiennych metryki, a ponieważ TensorFlow 2.x ma zależności od automatycznej kontroli, nie musisz się o nie martwić.

Poniższy kod wykorzystuje metrykę do śledzenia średniej straty obserwowanej w ramach niestandardowej pętli treningowej.

# Create the metrics
loss_metric = tf.keras.metrics.Mean(name='train_loss')
accuracy_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')

@tf.function
def train_step(inputs, labels):
  with tf.GradientTape() as tape:
    predictions = model(inputs, training=True)
    regularization_loss=tf.math.add_n(model.losses)
    pred_loss=loss_fn(labels, predictions)
    total_loss=pred_loss + regularization_loss

  gradients = tape.gradient(total_loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  # Update the metrics
  loss_metric.update_state(total_loss)
  accuracy_metric.update_state(labels, predictions)


for epoch in range(NUM_EPOCHS):
  # Reset the metrics
  loss_metric.reset_states()
  accuracy_metric.reset_states()

  for inputs, labels in train_data:
    train_step(inputs, labels)
  # Get the metric results
  mean_loss=loss_metric.result()
  mean_accuracy = accuracy_metric.result()

  print('Epoch: ', epoch)
  print('  loss:     {:.3f}'.format(mean_loss))
  print('  accuracy: {:.3f}'.format(mean_accuracy))
Epoch:  0
  loss:     0.139
  accuracy: 0.997
Epoch:  1
  loss:     0.116
  accuracy: 1.000
Epoch:  2
  loss:     0.105
  accuracy: 0.997
Epoch:  3
  loss:     0.089
  accuracy: 1.000
Epoch:  4
  loss:     0.078
  accuracy: 1.000

Nazwy metryk Keras

W TensorFlow 2.x modele Keras są bardziej spójne w obsłudze nazw metryk.

Teraz, gdy przekazujesz ciąg na liście metryk, ten dokładny ciąg jest używany jako name metryki. Nazwy te są widoczne w obiekcie historii zwróconym przez model.fit oraz w dziennikach przekazanych do keras.callbacks . jest ustawiony na ciąg przekazany na liście metryk.

model.compile(
    optimizer = tf.keras.optimizers.Adam(0.001),
    loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics = ['acc', 'accuracy', tf.keras.metrics.SparseCategoricalAccuracy(name="my_accuracy")])
history = model.fit(train_data)
5/5 [==============================] - 1s 8ms/step - loss: 0.0901 - acc: 0.9923 - accuracy: 0.9923 - my_accuracy: 0.9923
history.history.keys()
dict_keys(['loss', 'acc', 'accuracy', 'my_accuracy'])

Różni się to od poprzednich wersji, w których przekazywanie metrics=["accuracy"] skutkowałoby dict_keys(['loss', 'acc'])

Optymalizatory Keras

Optymalizatory w wersji v1.train , takie jak v1.train.AdamOptimizer i v1.train.GradientDescentOptimizer , mają odpowiedniki w tf.keras.optimizers .

Przekonwertuj v1.train na keras.optimizers

Oto rzeczy, o których należy pamiętać podczas konwersji optymalizatorów:

Nowe ustawienia domyślne dla niektórych tf.keras.optimizers

Nie ma żadnych zmian dla optimizers.SGD , optimizers.Adam lub optimizers.RMSprop .

Zmieniły się następujące domyślne współczynniki uczenia się:

TensorBoard

TensorFlow 2.x zawiera istotne zmiany w interfejsie API tf.summary używanym do zapisywania danych podsumowujących do wizualizacji w TensorBoard. Aby uzyskać ogólne wprowadzenie do nowego tf.summary , dostępnych jest kilka samouczków korzystających z interfejsu API TensorFlow 2.x. Obejmuje to przewodnik migracji TensorBoard do TensorFlow 2.x.

Zapisywanie i ładowanie

Zgodność z punktem kontrolnym

TensorFlow 2.x używa punktów kontrolnych opartych na obiektach .

Jeśli zachowasz ostrożność, nadal można załadować punkty kontrolne oparte na nazwach w starym stylu. Proces konwersji kodu może spowodować zmianę nazwy zmiennej, ale istnieją obejścia.

Najprostszym podejściem jest zestawienie nazw nowego modelu z nazwami w punkcie kontrolnym:

  • Wszystkie zmienne nadal mają argument name który można ustawić.
  • Modele Keras również przyjmują argument name który ustawiają jako przedrostek dla swoich zmiennych.
  • Funkcja v1.name_scope może służyć do ustawiania przedrostków nazw zmiennych. To bardzo różni się od tf.variable_scope . Wpływa tylko na nazwy, nie śledzi zmiennych i nie wykorzystuje ich ponownie.

Jeśli to nie zadziała w Twoim przypadku użycia, wypróbuj funkcję v1.train.init_from_checkpoint . Pobiera argument assignment_map , który określa mapowanie starych nazw na nowe.

Repozytorium TensorFlow Estimator zawiera narzędzie do konwersji umożliwiające aktualizację punktów kontrolnych wstępnie przygotowanych estymatorów z TensorFlow 1.x do 2.0. Może służyć jako przykład, jak zbudować narzędzie dla podobnego przypadku użycia.

Zgodność zapisanych modeli

Nie ma istotnych problemów ze zgodnością zapisanych modeli.

  • TensorFlow 1.x zapisane_modele działają w TensorFlow 2.x.
  • TensorFlow 2.xzapisane_modele działają w TensorFlow 1.x, jeśli wszystkie operacje są obsługiwane.

Graph.pb lub Graph.pbtxt

Nie ma prosty sposób uaktualnić surowego Graph.pb plik TensorFlow 2.x. Najlepszym rozwiązaniem jest uaktualnienie kodu, który wygenerował plik.

Ale jeśli masz "zamrożony wykres" (wykres tf.Graph którym zmienne zostały zamienione na stałe), to jest możliwe przekonwertowanie go na funkcję concrete_function funkcji przy użyciu v1.wrap_function :

def wrap_frozen_graph(graph_def, inputs, outputs):
  def _imports_graph_def():
    tf.compat.v1.import_graph_def(graph_def, name="")
  wrapped_import = tf.compat.v1.wrap_function(_imports_graph_def, [])
  import_graph = wrapped_import.graph
  return wrapped_import.prune(
      tf.nest.map_structure(import_graph.as_graph_element, inputs),
      tf.nest.map_structure(import_graph.as_graph_element, outputs))

Na przykład, oto zatrzymany wykres dla Inception v1, z 2016 roku:

path = tf.keras.utils.get_file(
    'inception_v1_2016_08_28_frozen.pb',
    'http://storage.googleapis.com/download.tensorflow.org/models/inception_v1_2016_08_28_frozen.pb.tar.gz',
    untar=True)
Downloading data from http://storage.googleapis.com/download.tensorflow.org/models/inception_v1_2016_08_28_frozen.pb.tar.gz
24698880/24695710 [==============================] - 1s 0us/step

Załaduj tf.GraphDef :

graph_def = tf.compat.v1.GraphDef()
loaded = graph_def.ParseFromString(open(path,'rb').read())

Owiń to w concrete_function funkcję:

inception_func = wrap_frozen_graph(
    graph_def, inputs='input:0',
    outputs='InceptionV1/InceptionV1/Mixed_3b/Branch_1/Conv2d_0a_1x1/Relu:0')

Podaj tensor jako dane wejściowe:

input_img = tf.ones([1,224,224,3], dtype=tf.float32)
inception_func(input_img).shape
TensorShape([1, 28, 28, 96])

Estymatory

Szkolenie z estymatorami

Estymatory są obsługiwane w TensorFlow 2.x.

Korzystając z estymatorów, można użyć input_fn , tf.estimator.TrainSpec i tf.estimator.EvalSpec z TensorFlow 1.x.

Oto przykład użycia input_fn z pociągiem i ocenianiem specyfikacji.

Tworzenie specyfikacji input_fn i train / eval

# Define the estimator's input_fn
def input_fn():
  datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
  mnist_train, mnist_test = datasets['train'], datasets['test']

  BUFFER_SIZE = 10000
  BATCH_SIZE = 64

  def scale(image, label):
    image = tf.cast(image, tf.float32)
    image /= 255

    return image, label[..., tf.newaxis]

  train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
  return train_data.repeat()

# Define train and eval specs
train_spec = tf.estimator.TrainSpec(input_fn=input_fn,
                                    max_steps=STEPS_PER_EPOCH * NUM_EPOCHS)
eval_spec = tf.estimator.EvalSpec(input_fn=input_fn,
                                  steps=STEPS_PER_EPOCH)

Korzystanie z definicji modelu Keras

Istnieją pewne różnice w sposobie tworzenia estymatorów w TensorFlow 2.x.

Zaleca się zdefiniowanie modelu za pomocą Keras, a następnie użycie narzędzia tf.keras.estimator.model_to_estimator celu przekształcenia modelu w estymator. Poniższy kod pokazuje, jak używać tego narzędzia podczas tworzenia i szkolenia estymatora.

def make_model():
  return tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
  ])
model = make_model()

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

estimator = tf.keras.estimator.model_to_estimator(
  keras_model = model
)

tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
INFO:tensorflow:Using default config.
INFO:tensorflow:Using default config.
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp0erq3im2
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp0erq3im2
INFO:tensorflow:Using the Keras model provided.
INFO:tensorflow:Using the Keras model provided.
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/backend.py:434: UserWarning: `tf.keras.backend.set_learning_phase` is deprecated and will be removed after 2020-10-11. To update it, simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.
  warnings.warn('`tf.keras.backend.set_learning_phase` is deprecated and '
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp0erq3im2', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp0erq3im2', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
INFO:tensorflow:Not using Distribute Coordinator.
INFO:tensorflow:Not using Distribute Coordinator.
INFO:tensorflow:Running training and evaluation locally (non-distributed).
INFO:tensorflow:Running training and evaluation locally (non-distributed).
INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.
INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/training_util.py:236: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/training_util.py:236: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Warm-starting with WarmStartSettings: WarmStartSettings(ckpt_to_initialize_from='/tmp/tmp0erq3im2/keras/keras_model.ckpt', vars_to_warm_start='.*', var_name_to_vocab_info={}, var_name_to_prev_var_name={})
INFO:tensorflow:Warm-starting with WarmStartSettings: WarmStartSettings(ckpt_to_initialize_from='/tmp/tmp0erq3im2/keras/keras_model.ckpt', vars_to_warm_start='.*', var_name_to_vocab_info={}, var_name_to_prev_var_name={})
INFO:tensorflow:Warm-starting from: /tmp/tmp0erq3im2/keras/keras_model.ckpt
INFO:tensorflow:Warm-starting from: /tmp/tmp0erq3im2/keras/keras_model.ckpt
INFO:tensorflow:Warm-starting variables only in TRAINABLE_VARIABLES.
INFO:tensorflow:Warm-starting variables only in TRAINABLE_VARIABLES.
INFO:tensorflow:Warm-started 8 variables.
INFO:tensorflow:Warm-started 8 variables.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp0erq3im2/model.ckpt.
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp0erq3im2/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 2.4717796, step = 0
INFO:tensorflow:loss = 2.4717796, step = 0
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...
INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmp0erq3im2/model.ckpt.
INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmp0erq3im2/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py:2325: UserWarning: `Model.state_updates` will be removed in a future version. This property should not be used in TensorFlow 2.0, as `updates` are applied automatically.
  warnings.warn('`Model.state_updates` will be removed in a future version. '
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:17Z
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:17Z
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmp0erq3im2/model.ckpt-25
INFO:tensorflow:Restoring parameters from /tmp/tmp0erq3im2/model.ckpt-25
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [1/5]
INFO:tensorflow:Evaluation [1/5]
INFO:tensorflow:Evaluation [2/5]
INFO:tensorflow:Evaluation [2/5]
INFO:tensorflow:Evaluation [3/5]
INFO:tensorflow:Evaluation [3/5]
INFO:tensorflow:Evaluation [4/5]
INFO:tensorflow:Evaluation [4/5]
INFO:tensorflow:Evaluation [5/5]
INFO:tensorflow:Evaluation [5/5]
INFO:tensorflow:Inference Time : 0.86556s
INFO:tensorflow:Inference Time : 0.86556s
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:18
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:18
INFO:tensorflow:Saving dict for global step 25: accuracy = 0.6, global_step = 25, loss = 1.6160676
INFO:tensorflow:Saving dict for global step 25: accuracy = 0.6, global_step = 25, loss = 1.6160676
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp0erq3im2/model.ckpt-25
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp0erq3im2/model.ckpt-25
INFO:tensorflow:Loss for final step: 0.37597787.
INFO:tensorflow:Loss for final step: 0.37597787.
({'accuracy': 0.6, 'loss': 1.6160676, 'global_step': 25}, [])

Korzystanie z niestandardowego model_fn

Jeśli masz istniejący niestandardowy estymator model_fn , który musisz utrzymywać, możesz przekonwertować swój model_fn aby używał modelu Keras.

Jednak ze względu na zgodność niestandardowy model_fn będzie nadal działał w trybie wykresu w stylu 1.x. Oznacza to, że nie ma zachłannego wykonywania ani automatycznych zależności sterujących.

Niestandardowy model_fn z minimalnymi zmianami

Aby Twój niestandardowy model_fn działał w TensorFlow 2.x, jeśli wolisz minimalne zmiany w istniejącym kodzie, tf.compat.v1 symboli tf.compat.v1 takich jak optimizers i metrics .

Używanie modelu Keras w niestandardowym model_fn jest podobne do używania go w niestandardowej pętli treningowej:

  • Ustaw odpowiednio fazę training na podstawie argumentu mode .
  • Wyraźnie zdać modelki trainable_variables do optymalizatora.

Istnieją jednak ważne różnice w stosunku do niestandardowej pętli :

  • Zamiast używać Model.losses , wyodrębnij straty za pomocą Model.get_losses_for .
  • Wyodrębnij aktualizacje modelu za pomocą Model.get_updates_for .

Poniższy kod tworzy estymator na podstawie niestandardowego model_fn , ilustrując wszystkie te obawy.

def my_model_fn(features, labels, mode):
  model = make_model()

  optimizer = tf.compat.v1.train.AdamOptimizer()
  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

  training = (mode == tf.estimator.ModeKeys.TRAIN)
  predictions = model(features, training=training)

  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

  reg_losses = model.get_losses_for(None) + model.get_losses_for(features)
  total_loss=loss_fn(labels, predictions) + tf.math.add_n(reg_losses)

  accuracy = tf.compat.v1.metrics.accuracy(labels=labels,
                                           predictions=tf.math.argmax(predictions, axis=1),
                                           name='acc_op')

  update_ops = model.get_updates_for(None) + model.get_updates_for(features)
  minimize_op = optimizer.minimize(
      total_loss,
      var_list=model.trainable_variables,
      global_step=tf.compat.v1.train.get_or_create_global_step())
  train_op = tf.group(minimize_op, update_ops)

  return tf.estimator.EstimatorSpec(
    mode=mode,
    predictions=predictions,
    loss=total_loss,
    train_op=train_op, eval_metric_ops={'accuracy': accuracy})

# Create the Estimator & Train
estimator = tf.estimator.Estimator(model_fn=my_model_fn)
tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
INFO:tensorflow:Using default config.
INFO:tensorflow:Using default config.
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpifj8mysl
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpifj8mysl
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpifj8mysl', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpifj8mysl', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
INFO:tensorflow:Not using Distribute Coordinator.
INFO:tensorflow:Not using Distribute Coordinator.
INFO:tensorflow:Running training and evaluation locally (non-distributed).
INFO:tensorflow:Running training and evaluation locally (non-distributed).
INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.
INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpifj8mysl/model.ckpt.
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpifj8mysl/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 3.0136237, step = 0
INFO:tensorflow:loss = 3.0136237, step = 0
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...
INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpifj8mysl/model.ckpt.
INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpifj8mysl/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:20Z
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:20Z
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpifj8mysl/model.ckpt-25
INFO:tensorflow:Restoring parameters from /tmp/tmpifj8mysl/model.ckpt-25
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [1/5]
INFO:tensorflow:Evaluation [1/5]
INFO:tensorflow:Evaluation [2/5]
INFO:tensorflow:Evaluation [2/5]
INFO:tensorflow:Evaluation [3/5]
INFO:tensorflow:Evaluation [3/5]
INFO:tensorflow:Evaluation [4/5]
INFO:tensorflow:Evaluation [4/5]
INFO:tensorflow:Evaluation [5/5]
INFO:tensorflow:Evaluation [5/5]
INFO:tensorflow:Inference Time : 0.97406s
INFO:tensorflow:Inference Time : 0.97406s
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:21
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:21
INFO:tensorflow:Saving dict for global step 25: accuracy = 0.59375, global_step = 25, loss = 1.6248872
INFO:tensorflow:Saving dict for global step 25: accuracy = 0.59375, global_step = 25, loss = 1.6248872
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpifj8mysl/model.ckpt-25
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpifj8mysl/model.ckpt-25
INFO:tensorflow:Loss for final step: 0.35726172.
INFO:tensorflow:Loss for final step: 0.35726172.
({'accuracy': 0.59375, 'loss': 1.6248872, 'global_step': 25}, [])

Niestandardowy model_fn z symbolami TensorFlow 2.x.

Jeśli chcesz pozbyć się wszystkich symboli TensorFlow 1.x i zaktualizować swój niestandardowy model_fn do TensorFlow 2.x, musisz zaktualizować optymalizator i metryki do tf.keras.optimizers i tf.keras.metrics .

W niestandardowym model_fn , poza powyższymi zmianami , należy wykonać więcej ulepszeń:

W powyższym przykładzie my_model_fn zmigrowany kod z symbolami TensorFlow 2.x jest przedstawiony jako:

def my_model_fn(features, labels, mode):
  model = make_model()

  training = (mode == tf.estimator.ModeKeys.TRAIN)
  loss_obj = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
  predictions = model(features, training=training)

  # Get both the unconditional losses (the None part)
  # and the input-conditional losses (the features part).
  reg_losses = model.get_losses_for(None) + model.get_losses_for(features)
  total_loss=loss_obj(labels, predictions) + tf.math.add_n(reg_losses)

  # Upgrade to tf.keras.metrics.
  accuracy_obj = tf.keras.metrics.Accuracy(name='acc_obj')
  accuracy = accuracy_obj.update_state(
      y_true=labels, y_pred=tf.math.argmax(predictions, axis=1))

  train_op = None
  if training:
    # Upgrade to tf.keras.optimizers.
    optimizer = tf.keras.optimizers.Adam()
    # Manually assign tf.compat.v1.global_step variable to optimizer.iterations
    # to make tf.compat.v1.train.global_step increased correctly.
    # This assignment is a must for any `tf.train.SessionRunHook` specified in
    # estimator, as SessionRunHooks rely on global step.
    optimizer.iterations = tf.compat.v1.train.get_or_create_global_step()
    # Get both the unconditional updates (the None part)
    # and the input-conditional updates (the features part).
    update_ops = model.get_updates_for(None) + model.get_updates_for(features)
    # Compute the minimize_op.
    minimize_op = optimizer.get_updates(
        total_loss,
        model.trainable_variables)[0]
    train_op = tf.group(minimize_op, *update_ops)

  return tf.estimator.EstimatorSpec(
    mode=mode,
    predictions=predictions,
    loss=total_loss,
    train_op=train_op,
    eval_metric_ops={'Accuracy': accuracy_obj})

# Create the Estimator and train.
estimator = tf.estimator.Estimator(model_fn=my_model_fn)
tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
INFO:tensorflow:Using default config.
INFO:tensorflow:Using default config.
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpc93qfnv6
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpc93qfnv6
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpc93qfnv6', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpc93qfnv6', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
INFO:tensorflow:Not using Distribute Coordinator.
INFO:tensorflow:Not using Distribute Coordinator.
INFO:tensorflow:Running training and evaluation locally (non-distributed).
INFO:tensorflow:Running training and evaluation locally (non-distributed).
INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.
INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpc93qfnv6/model.ckpt.
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpc93qfnv6/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 2.5293791, step = 0
INFO:tensorflow:loss = 2.5293791, step = 0
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...
INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpc93qfnv6/model.ckpt.
INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpc93qfnv6/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:24Z
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:24Z
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpc93qfnv6/model.ckpt-25
INFO:tensorflow:Restoring parameters from /tmp/tmpc93qfnv6/model.ckpt-25
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [1/5]
INFO:tensorflow:Evaluation [1/5]
INFO:tensorflow:Evaluation [2/5]
INFO:tensorflow:Evaluation [2/5]
INFO:tensorflow:Evaluation [3/5]
INFO:tensorflow:Evaluation [3/5]
INFO:tensorflow:Evaluation [4/5]
INFO:tensorflow:Evaluation [4/5]
INFO:tensorflow:Evaluation [5/5]
INFO:tensorflow:Evaluation [5/5]
INFO:tensorflow:Inference Time : 0.86534s
INFO:tensorflow:Inference Time : 0.86534s
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:25
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:25
INFO:tensorflow:Saving dict for global step 25: Accuracy = 0.59375, global_step = 25, loss = 1.7570661
INFO:tensorflow:Saving dict for global step 25: Accuracy = 0.59375, global_step = 25, loss = 1.7570661
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpc93qfnv6/model.ckpt-25
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpc93qfnv6/model.ckpt-25
INFO:tensorflow:Loss for final step: 0.47094986.
INFO:tensorflow:Loss for final step: 0.47094986.
({'Accuracy': 0.59375, 'loss': 1.7570661, 'global_step': 25}, [])

Gotowe estymatory

Gotowe estymatory z rodziny tf.estimator.DNN* , tf.estimator.Linear* i tf.estimator.DNNLinearCombined* są nadal obsługiwane w interfejsie API TensorFlow 2.x. Jednak niektóre argumenty uległy zmianie:

  1. input_layer_partitioner : Usunięty w v2.
  2. loss_reduction : Zaktualizowano do tf.keras.losses.Reduction zamiast tf.compat.v1.losses.Reduction . Jego domyślna wartość jest również zmieniana na tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE z tf.compat.v1.losses.Reduction.SUM .
  3. optimizer , dnn_optimizer i linear_optimizer : ten argument został zaktualizowany do tf.keras.optimizers zamiast tf.compat.v1.train.Optimizer .

Aby przeprowadzić migrację powyższych zmian:

  1. Migracja nie jest potrzebna dla input_layer_partitioner ponieważ Distribution Strategy zajmie się nią automatycznie w TensorFlow 2.x.
  2. W przypadku loss_reduction sprawdź tf.keras.losses.Reduction dla obsługiwanych opcji.
  3. Dla argumentów optimizer :

Konwerter punktów kontrolnych

Migracja do keras.optimizers spowoduje przerwanie punktów kontrolnych zapisanych przy użyciu TensorFlow 1.x, ponieważ tf.keras.optimizers generuje inny zestaw zmiennych do zapisania w punktach kontrolnych. Aby umożliwić ponowne użycie starego punktu kontrolnego po migracji do TensorFlow 2.x, wypróbuj narzędzie do konwertera punktów kontrolnych .

 curl -O https://raw.githubusercontent.com/tensorflow/estimator/master/tensorflow_estimator/python/estimator/tools/checkpoint_converter.py
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 15165  100 15165    0     0  40656      0 --:--:-- --:--:-- --:--:-- 40656

Narzędzie ma wbudowaną pomoc:

 python checkpoint_converter.py -h
2021-01-06 02:31:26.297951: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
usage: checkpoint_converter.py [-h]
                               {dnn,linear,combined} source_checkpoint
                               source_graph target_checkpoint

positional arguments:
  {dnn,linear,combined}
                        The type of estimator to be converted. So far, the
                        checkpoint converter only supports Canned Estimator.
                        So the allowed types include linear, dnn and combined.
  source_checkpoint     Path to source checkpoint file to be read in.
  source_graph          Path to source graph file to be read in.
  target_checkpoint     Path to checkpoint file to be written out.

optional arguments:
  -h, --help            show this help message and exit

TensorShape

Ta klasa została uproszczona do przechowywania int s, zamiast obiektów tf.compat.v1.Dimension . Więc nie ma potrzeby wywoływania .value aby uzyskać int .

Poszczególne obiekty tf.compat.v1.Dimension są nadal dostępne z tf.TensorShape.dims .

Poniżej przedstawiono różnice między TensorFlow 1.x i TensorFlow 2.x.

# Create a shape and choose an index
i = 0
shape = tf.TensorShape([16, None, 256])
shape
TensorShape([16, None, 256])

Gdybyś miał to w TensorFlow 1.x:

value = shape[i].value

Następnie zrób to w TensorFlow 2.x:

value = shape[i]
value
16

Gdybyś miał to w TensorFlow 1.x:

for dim in shape:
    value = dim.value
    print(value)

Następnie zrób to w TensorFlow 2.x:

for value in shape:
  print(value)
16
None
256

Jeśli masz to w TensorFlow 1.x (lub używasz innej metody wymiarowania):

dim = shape[i]
dim.assert_is_compatible_with(other_dim)

Następnie zrób to w TensorFlow 2.x:

other_dim = 16
Dimension = tf.compat.v1.Dimension

if shape.rank is None:
  dim = Dimension(None)
else:
  dim = shape.dims[i]
dim.is_compatible_with(other_dim) # or any other dimension method
True
shape = tf.TensorShape(None)

if shape:
  dim = shape.dims[i]
  dim.is_compatible_with(other_dim) # or any other dimension method

Wartość logiczna tf.TensorShape to True jeśli pozycja jest znana, a False przeciwnym razie.

print(bool(tf.TensorShape([])))      # Scalar
print(bool(tf.TensorShape([0])))     # 0-length vector
print(bool(tf.TensorShape([1])))     # 1-length vector
print(bool(tf.TensorShape([None])))  # Unknown-length vector
print(bool(tf.TensorShape([1, 10, 100])))       # 3D tensor
print(bool(tf.TensorShape([None, None, None]))) # 3D tensor with no known dimensions
print()
print(bool(tf.TensorShape(None)))  # A tensor with unknown rank.
True
True
True
True
True
True

False

Inne zmiany

  • Usuń tf.colocate_with : Algorytmy rozmieszczania urządzeń TensorFlow znacznie się poprawiły. Nie powinno to już być konieczne. Jeśli usunięcie powoduje spadek wydajności, zgłoś błąd .

  • Zastąp użycie v1.ConfigProto równoważnymi funkcjami z tf.config .

Wnioski

Ogólny proces to:

  1. Uruchom skrypt aktualizacji.
  2. Usuń symbole wkładu.
  3. Przełącz swoje modele na styl obiektowy (Keras).
  4. tf.keras gdzie to możliwe, korzystaj tf.keras szkoleń i pętli ocen tf.keras lub tf.estimator .
  5. W przeciwnym razie użyj niestandardowych pętli, ale pamiętaj, aby unikać sesji i kolekcji.

Konwersja kodu do idiomatycznego TensorFlow 2.x wymaga trochę pracy, ale każda zmiana skutkuje:

  • Mniej wierszy kodu.
  • Zwiększona przejrzystość i prostota.
  • Łatwiejsze debugowanie.