Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Przeprowadź migrację kodu TensorFlow 1 do TensorFlow 2

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

Ten dokument 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.0:

W TensorFlow 2.0 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.0. Ten przewodnik pomoże Ci zaktualizować kod, czyniąc go prostszym, wydajniejszym i łatwiejszym w utrzymaniu.

Automatyczny skrypt konwersji

Pierwszym krokiem przed próbą wprowadzenia zmian opisanych w tym dokumencie jest uruchomienie skryptu aktualizacji .

Spowoduje to wstępną aktualizację kodu do wersji TensorFlow 2.0. Ale nie może uczynić twojego kodu idiomatycznym do 2.0. 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.0 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 odniesienia TF. 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 uż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() : TF 2.0 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 TensorShape .

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

Zmień kod na natywny w wersji 2.0

W tym przewodniku przedstawiono kilka przykładów konwersji kodu TensorFlow 1.x do TensorFlow 2.0. 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 należy zastąpić 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. Zobacz przewodnik po autografach, aby dowiedzieć się więcej o tym, jak to działa.

Zauważ, że:

  • W przeciwieństwie do v1.Session.run a 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ł uruchomiony w kolejności zapisania. tf.Variable przypisania tf.Variable i tf.assert są wykonywane automatycznie.

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

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

Wszelkie śledzenie zmiennych opartych na nazwach jest zdecydowanie odradzane w TF 2.0. 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. Zazwyczaj 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ę posiadania globalnych kolekcji. Ich właściwość .losses może zastąpić używanie kolekcji tf.GraphKeys.LOSSES .

Zobacz poradniki keras, aby uzyskać szczegółowe informacje.

3. Zaktualizuj swoje pętle treningowe

Użyj interfejsu API najwyższego poziomu, który działa w Twoim przypadku użycia. Wolisz tf.keras.Model.fit niż tworzenie 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 TF2 przekonwertuje symbole na ich odpowiedniki 2.0, jeśli taka konwersja jest bezpieczna, tj. Jeśli może określić, że zachowanie wersji 2.0 jest dokładnie równoważne (na przykład zmieni nazwę v1.arg_max na 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 do odpowiednika 2.0 (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ą:

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.
  • Brak 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 warstw, 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)
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:4: conv2d (from tensorflow.python.keras.legacy_tf_layers.convolutional) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.keras.layers.Conv2D` instead.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/convolutional.py:424: Layer.apply (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `layer.__call__` method instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:5: max_pooling2d (from tensorflow.python.keras.legacy_tf_layers.pooling) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.MaxPooling2D instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:6: flatten (from tensorflow.python.keras.legacy_tf_layers.core) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.Flatten instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:7: dropout (from tensorflow.python.keras.legacy_tf_layers.core) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.dropout instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:8: dense (from tensorflow.python.keras.legacy_tf_layers.core) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.Dense instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:9: batch_normalization (from tensorflow.python.keras.legacy_tf_layers.normalization) is deprecated and will be removed in a future version.
Instructions for updating:
Use 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.Tensor([[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]], shape=(1, 10), dtype=float32)

tf.Tensor(
[[ 0.07562444 -0.27538717  0.21692204  0.2411264  -0.01209673 -0.0923705
   0.19058049 -0.00468709 -0.17215249 -0.07528099]], shape=(1, 10), dtype=float32)

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 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.32132083  0.22252844 -0.11330387 -0.4613616  -0.08817139 -0.52697927
  -0.1538124   0.23069203 -0.15860984 -0.453844  ]], 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.08671833>]

Zmienne mieszane i v1.layers

Istniejący kod często miesza zmienne TF 1.x niższego poziomu 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 wzór to:

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

v1.variable_scope jest zasadniczo własną warstwą. Więc przepisz go jako tf.keras.layers.Layer . Zobacz przewodnik po szczegóły.

# 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:

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

    • Zawiń call() w 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 funkcji 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.0, nawet w tf.compat.v1 . Konwersja kodu za pomocą Slim do TF 2.0 jest bardziej v1.layers 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 rozdzielne warstwy Keras)
  • 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 TF2 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 dodatków TF .

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 ze zbiorów danych

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

W tym przykładzie załaduj MNISTdataset przy użyciu 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 niskiego poziomu kontroli nad procesem treningu, 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 o tym, jak to działa, zobacz samouczki ).

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 [==============================] - 0s 6ms/step - loss: 1.5665 - accuracy: 0.4969
Epoch 2/5
5/5 [==============================] - 0s 6ms/step - loss: 0.5249 - accuracy: 0.8656
Epoch 3/5
5/5 [==============================] - 0s 5ms/step - loss: 0.3246 - accuracy: 0.9438
Epoch 4/5
5/5 [==============================] - 0s 6ms/step - loss: 0.2407 - accuracy: 0.9719
Epoch 5/5
5/5 [==============================] - 0s 5ms/step - loss: 0.1841 - accuracy: 0.9906
5/5 [==============================] - 0s 4ms/step - loss: 1.5957 - accuracy: 0.5375
Loss 1.5956770181655884, Accuracy 0.5375000238418579

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.145 accuracy: 1.000
train:  loss: 0.183 accuracy: 0.984
train:  loss: 0.216 accuracy: 0.953
train:  loss: 0.229 accuracy: 0.938
train:  loss: 0.201 accuracy: 0.969

eval:  loss: 1.588 accuracy: 0.628
train:  loss: 0.097 accuracy: 1.000
train:  loss: 0.101 accuracy: 1.000
train:  loss: 0.086 accuracy: 1.000
train:  loss: 0.130 accuracy: 0.984
train:  loss: 0.127 accuracy: 1.000

eval:  loss: 1.580 accuracy: 0.766
train:  loss: 0.086 accuracy: 1.000
train:  loss: 0.081 accuracy: 1.000
train:  loss: 0.079 accuracy: 1.000
train:  loss: 0.076 accuracy: 1.000
train:  loss: 0.077 accuracy: 1.000

eval:  loss: 1.542 accuracy: 0.809
train:  loss: 0.067 accuracy: 1.000
train:  loss: 0.068 accuracy: 1.000
train:  loss: 0.063 accuracy: 1.000
train:  loss: 0.063 accuracy: 1.000
train:  loss: 0.056 accuracy: 1.000

eval:  loss: 1.503 accuracy: 0.816
train:  loss: 0.055 accuracy: 1.000
train:  loss: 0.056 accuracy: 1.000
train:  loss: 0.048 accuracy: 1.000
train:  loss: 0.051 accuracy: 1.000
train:  loss: 0.048 accuracy: 1.000

eval:  loss: 1.482 accuracy: 0.828

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 lub tf.data.Dataset aby uzyskać partie przykładów.
  2. Użyj tf.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 do metody call warstw i modeli z podklasą.
  • 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 inicjatorów zmiennych. Zmienne są inicjalizowane podczas tworzenia.
  • Nie ma potrzeby dodawania zależności sterowania ręcznego. Nawet w tf.function działa 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.0 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:

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.0 ma zależności automatycznego sterowania, nie musisz się o nie martwić.

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

# 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.207
  accuracy: 0.991
Epoch:  1
  loss:     0.167
  accuracy: 0.994
Epoch:  2
  loss:     0.147
  accuracy: 0.997
Epoch:  3
  loss:     0.123
  accuracy: 0.997
Epoch:  4
  loss:     0.109
  accuracy: 0.997

Nazwy metryk Keras

W TensorFlow 2.0 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 [==============================] - 0s 6ms/step - loss: 0.1233 - acc: 0.9937 - accuracy: 0.9937 - my_accuracy: 0.9937

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 .

Konwersja v1.train do keras.optimizers

Oto kwestie, 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 zawiera istotne zmiany w interfejsie API tf.summary używanym do zapisu 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 TF 2. Obejmuje to przewodnik migracji TensorBoard TF 2

Zapisywanie i ładowanie

Zgodność z punktem kontrolnym

TensorFlow 2.0 wykorzystuje punkty kontrolne oparte na obiektach .

Punkty kontrolne oparte na nazwach w starym stylu mogą być nadal ładowane, jeśli jesteś ostrożny. 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 tego, 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.x zapisane_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.0. 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 concrete_function v1.wrap_function 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.0.

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 & 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 konstruowania estymatorów w TensorFlow 2.0.

Zalecamy 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/tmp333woaev

Warning:tensorflow:Using temporary folder as model directory: /tmp/tmp333woaev

INFO:tensorflow:Using the Keras model provided.

INFO:tensorflow:Using the Keras model provided.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_estimator/python/estimator/keras.py:220: set_learning_phase (from tensorflow.python.keras.backend) is deprecated and will be removed after 2020-10-11.
Instructions for updating:
Simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_estimator/python/estimator/keras.py:220: set_learning_phase (from tensorflow.python.keras.backend) is deprecated and will be removed after 2020-10-11.
Instructions for updating:
Simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp333woaev', '_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, '_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/tmp333woaev', '_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, '_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/tmp333woaev/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/tmp333woaev/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/tmp333woaev/keras/keras_model.ckpt

INFO:tensorflow:Warm-starting from: /tmp/tmp333woaev/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/tmp333woaev/model.ckpt.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp333woaev/model.ckpt.

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:loss = 2.946777, step = 0

INFO:tensorflow:loss = 2.946777, 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/tmp333woaev/model.ckpt.

INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmp333woaev/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.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_v1.py:2048: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_v1.py:2048: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Starting evaluation at 2020-10-15T01:27:37Z

INFO:tensorflow:Starting evaluation at 2020-10-15T01:27:37Z

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Restoring parameters from /tmp/tmp333woaev/model.ckpt-25

INFO:tensorflow:Restoring parameters from /tmp/tmp333woaev/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.84716s

INFO:tensorflow:Inference Time : 0.84716s

INFO:tensorflow:Finished evaluation at 2020-10-15-01:27:38

INFO:tensorflow:Finished evaluation at 2020-10-15-01:27:38

INFO:tensorflow:Saving dict for global step 25: accuracy = 0.715625, global_step = 25, loss = 1.5356585

INFO:tensorflow:Saving dict for global step 25: accuracy = 0.715625, global_step = 25, loss = 1.5356585

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp333woaev/model.ckpt-25

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp333woaev/model.ckpt-25

INFO:tensorflow:Loss for final step: 0.52498615.

INFO:tensorflow:Loss for final step: 0.52498615.

({'accuracy': 0.715625, 'loss': 1.5356585, '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 zależności automatycznego sterowania.

Niestandardowy model_fn z minimalnymi zmianami

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

Używanie modeli 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/tmpnhx_c2r_

Warning:tensorflow:Using temporary folder as model directory: /tmp/tmpnhx_c2r_

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpnhx_c2r_', '_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, '_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/tmpnhx_c2r_', '_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, '_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/tmpnhx_c2r_/model.ckpt.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpnhx_c2r_/model.ckpt.

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:loss = 2.7539256, step = 0

INFO:tensorflow:loss = 2.7539256, 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/tmpnhx_c2r_/model.ckpt.

INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpnhx_c2r_/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 2020-10-15T01:27:41Z

INFO:tensorflow:Starting evaluation at 2020-10-15T01:27:41Z

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Restoring parameters from /tmp/tmpnhx_c2r_/model.ckpt-25

INFO:tensorflow:Restoring parameters from /tmp/tmpnhx_c2r_/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.94175s

INFO:tensorflow:Inference Time : 0.94175s

INFO:tensorflow:Finished evaluation at 2020-10-15-01:27:42

INFO:tensorflow:Finished evaluation at 2020-10-15-01:27:42

INFO:tensorflow:Saving dict for global step 25: accuracy = 0.678125, global_step = 25, loss = 1.5622549

INFO:tensorflow:Saving dict for global step 25: accuracy = 0.678125, global_step = 25, loss = 1.5622549

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpnhx_c2r_/model.ckpt-25

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpnhx_c2r_/model.ckpt-25

INFO:tensorflow:Loss for final step: 0.39462265.

INFO:tensorflow:Loss for final step: 0.39462265.

({'accuracy': 0.678125, 'loss': 1.5622549, 'global_step': 25}, [])

Niestandardowy model_fn z symbolami TF 2.0

Jeśli chcesz pozbyć się wszystkich symboli TF 1.x i zaktualizować swój własny model_fn do natywnego TF 2.0, musisz zaktualizować optymalizator i metryki do tf.keras.optimizers i tf.keras.metrics .

W niestandardowym model_fn , oprócz powyższych zmian , należy wykonać więcej ulepszeń:

W powyższym przykładzie my_model_fn zmigrowany kod z symbolami 2.0 jest pokazany 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 & 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/tmp3kddt__h

Warning:tensorflow:Using temporary folder as model directory: /tmp/tmp3kddt__h

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp3kddt__h', '_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, '_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/tmp3kddt__h', '_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, '_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/tmp3kddt__h/model.ckpt.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp3kddt__h/model.ckpt.

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:loss = 2.4914804, step = 0

INFO:tensorflow:loss = 2.4914804, 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/tmp3kddt__h/model.ckpt.

INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmp3kddt__h/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 2020-10-15T01:27:45Z

INFO:tensorflow:Starting evaluation at 2020-10-15T01:27:45Z

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Restoring parameters from /tmp/tmp3kddt__h/model.ckpt-25

INFO:tensorflow:Restoring parameters from /tmp/tmp3kddt__h/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.91708s

INFO:tensorflow:Inference Time : 0.91708s

INFO:tensorflow:Finished evaluation at 2020-10-15-01:27:46

INFO:tensorflow:Finished evaluation at 2020-10-15-01:27:46

INFO:tensorflow:Saving dict for global step 25: Accuracy = 0.690625, global_step = 25, loss = 1.554177

INFO:tensorflow:Saving dict for global step 25: Accuracy = 0.690625, global_step = 25, loss = 1.554177

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp3kddt__h/model.ckpt-25

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp3kddt__h/model.ckpt-25

INFO:tensorflow:Loss for final step: 0.3999393.

INFO:tensorflow:Loss for final step: 0.3999393.

({'Accuracy': 0.690625, 'loss': 1.554177, 'global_step': 25}, [])

Gotowe estymatory

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

  1. input_layer_partitioner : Usunięto w wersji 2.0.
  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. Nie jest wymagana migracja dla input_layer_partitioner ponieważ Distribution Strategy zajmie się nią automatycznie w TF 2.0.
  2. W przypadku loss_reduction sprawdź tf.keras.losses.Reduction dla obsługiwanych opcji.
  3. W przypadku argumentów optimizer , jeśli nie dnn_optimizer optimizer , dnn_optimizer lub linear_optimizer lub jeśli określisz argument optimizer jako string w swoim kodzie, nie musisz niczego zmieniać. tf.keras.optimizers używany jest tf.keras.optimizers . W przeciwnym razie musisz zaktualizować go z tf.compat.v1.train.Optimizer do odpowiedniego tf.keras.optimizers

Konwerter punktów kontrolnych

Migracja do keras.optimizers spowoduje przerwanie punktów kontrolnych zapisanych za pomocą TF 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 TF 2.0, wypróbuj narzędzie 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  32265      0 --:--:-- --:--:-- --:--:-- 32197

Narzędzie ma wbudowaną pomoc:

 python checkpoint_converter.py -h
2020-10-15 01:27:47.423752: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
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 w tf.TensorShape.dims .

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

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

Gdybyś miał to w TF 1.x:

value = shape[i].value

Następnie zrób to w TF 2.0:

value = shape[i]
value
16

Gdybyś miał to w TF 1.x:

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

Następnie zrób to w TF 2.0:

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

Jeśli miałeś to w TF 1.x (lub użyłeś innej metody wymiarowania):

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

Następnie zrób to w TF 2.0:

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ń w 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

Cały 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.0 wymaga trochę pracy, ale każda zmiana skutkuje:

  • Mniej linii kodu.
  • Większa przejrzystość i prostota.
  • Łatwiejsze debugowanie.