#python #tensorflow #keras #deep-learning
#python #тензорный поток #keras #глубокое обучение
Вопрос:
Кажется, я не могу найти причину проблемы или аналогичную проблему в Интернете. Я буду обновлять, когда разберусь с этим.
Предыстория
В качестве проекта я создаю скрипт на python с использованием tensorflow и keras API для создания пользовательской U-сети с помощью подкласса модели (следуя, например, этому руководству keras). Я создал свои собственные классы слоев, класс модели, я настроил параметры, загрузил данные и т. Д. И вызвал a model.fit(...)
.
Проблема
Я получаю следующую ошибку и трассировку:
Epoch 1/50
Traceback (most recent call last):
File "C:...pathtomaincodemy_code.py", line 418, in <module>
history = model.fit(x=train_ds, validation_data=val_ds, epochs=epochs, verbose=1)
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythonkerasenginetraining.py", line 108, in _method_wrapper
return method(self, *args, **kwargs)
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythonkerasenginetraining.py", line 1098, in fit
tmp_logs = train_function(iterator)
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythoneagerdef_function.py", line 780, in __call__
result = self._call(*args, **kwds)
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythoneagerdef_function.py", line 823, in _call
self._initialize(args, kwds, add_initializers_to=initializers)
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythoneagerdef_function.py", line 697, in _initialize
*args, **kwds))
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythoneagerfunction.py", line 2855, in _get_concrete_function_internal_garbage_collected
graph_function, _, _ = self._maybe_define_function(args, kwargs)
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythoneagerfunction.py", line 3213, in _maybe_define_function
graph_function = self._create_graph_function(args, kwargs)
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythoneagerfunction.py", line 3075, in _create_graph_function
capture_by_value=self._capture_by_value),
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythonframeworkfunc_graph.py", line 986, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythoneagerdef_function.py", line 600, in wrapped_fn
return weak_wrapped_fn().__wrapped__(*args, **kwds)
File "C:...anaconda3envsmy_envlibsite-packagestensorflowpythonframeworkfunc_graph.py", line 973, in wrapper
raise e.ag_error_metadata.to_exception(e)
TypeError: in user code:
C:...anaconda3envsmy_envlibsite-packagestensorflowpythonkerasenginetraining.py:806 train_function *
return step_function(self, iterator)
TypeError: tf__call() got multiple values for argument 'training'
Ошибка возникает в keras training.py сценарий. Однако я новичок в объектно-ориентированном программировании, tensorflow и keras, и поэтому моя первая мысль заключается в том, что проблема возникает либо из-за того, как я определяю аргументы своих методов класса, либо из-за того, как я использую набор инструментов tensorflow. Ниже приведена упрощенная версия моего кода, которая может помочь:
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Conv2D, Layer, MaxPool2D, UpSampling2D, Input, GaussianNoise
from tensorflow.keras.layers import Softmax, LeakyReLU, ReLU, Concatenate, BatchNormalization
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
import os
import pickle
tf.config.experimental.list_physical_devices('GPU')
# === Define layer and model classes ===
# ... define custom subclasses that inherit keras.layer.Layer
# ... example:
class sampleLayer2(Layer):
def __init__(self, name='layer1', **kwargs):
super().__init__()
self.sample_layer1 = sampleLayer1(...)
self.relu = ReLU()
self.batch_norm = BatchNormalization()
def call(self, layer_in, training=False):
x = self.sample_layer1(layer_in)
x = self.batch_norm(inputs=x)
x = self.relu(x)
# ...
return x
# ...
# ... other custom subclasses similar to above example...
# ...
# define model:
class UNet(Model):
def __init__(self, input_shape, name='unet', **kwargs):
super().__init__()
self.inputs = Input(input_shape)
self.sample_layera = sampleLayerA()
self.sample_layerb = sampleLayerB()
self.sample_layerc = sampleLayerC()
self.sample_layerd = sampleLayerD()
self.sample_layere = sampleLayerE()
# ... other layers that adjust depth ...
self.gaussian = GaussianNoise(.12)
self.pool = MaxPool2D(pool_size=(2, 2), strides=(2, 2)) # reduce feature dimensions
self.upsample = UpSampling2D(size=(2, 2)) # increase feature dimensions
self.batch_norm = BatchNormalization()
self.concat = Concatenate()
self.softmax = Softmax()
def call(self, training=False):
a = self.inputs
a = self.gaussian(a)
a = self.sample_layera(a) # begin encoder
b = self.pool(a)
b = self.sample_layerb(b)
c = self.pool(b)
c = self.sample_layerc(c)
d = self.pool(c)
d = self.sample_layerd(d)
e = self.pool(d)
e = self.sample_layere(e)
e_up = self.upsample(e)
# ... layer adjusting depth ...
d = self.concat([e_up, d])
d = self.sample_layerd(d)
d_up = self.upsample(d)
# ... layer adjusting depth ...
c = self.concat([d_up, c])
c = self.sample_layerc(c)
c_up = self.upsample(c)
# ... layer adjusting depth ...
b = self.concat([c_up, b])
b = self.sample_layerb(b)
b_up = self.upsample(b)
# ... layer adjusting depth ...
a = self.concat([b_up, a])
a = self.sample_layera(a)
# ... layer adjusting depth ...
# ... layer adjusting depth ...
a = self.batch_norm(inputs=a)
final_layer = self.softmax(a)
model = Model(inputs=self.inputs, outputs=final_layer)
return model
# === Define Parameters ===
np.random.seed(27)
tf.random.set_seed(27)
img_height = ## some number
img_width = ##
input_depth = ##
epochs = 50
learning_rate = 5e-4
batch_size_train = 32
batch_size_val = 128
opt = Adam(lr=learning_rate, beta_1=.9, beta_2=.999, epsilon=1e-8)
# === Set up Datasets ===
# ...
# ... define data directories
# ...
# ...
# ... define generators that ingest and process input and output data
# ...
# ...
# ... Using generators, create tf.data.Dataset objects for training and validation set ...
# ... result is train_ds_in, train_ds_out, val_ds_in, val_ds_out ...
train_ds = tf.data.Dataset.zip((train_ds_in, train_ds_out)) # combine input-output pairs in new dataset
train_ds = train_ds.shuffle(100).batch(batch_size_train) # set batches and shuffling of the dataset
# ...same for validation data ...
val_ds = tf.data.Dataset.zip((val_ds_in, val_ds_out))
val_ds = val_ds.shuffle(100).batch(batch_size_val)
# === Compile and fit the model ===
input_size = (None, img_height, img_width, input_depth)
model = UNet(input_size)
model.compile(optimizer=opt, loss='mae', metrics=['accuracy'])
# we already have batches and shuffling
history = model.fit(x=train_ds, validation_data=val_ds, epochs=epochs, verbose=1)
Мои попытки решить
Я попытался вставить *args
or **kwargs
в качестве аргументов как для модели, так и для слоя __init__
и call
методов, и никаких изменений. Для всех экземпляров, где BatchNormalization()
вызывается, я вставил trainable=training
и никаких изменений. Наконец, я удалил training=None
аргумент из метода UNet call
и получил немного другую ошибку:
TypeError: in user code:
C:...anaconda3envsmy_envlibsite-packagestensorflowpythonkerasenginetraining.py:806 train_function *
return step_function(self, iterator)
TypeError: tf__call() takes 1 positional argument but 2 were given
Похоже, проблема в call
методе в классе UNet. Для справки я использую python версии 3.7.7, tensorflow версии 2.3.1, tf.keras версии 2.4.0 …
Есть ли очевидная проблема с моим подходом, которая вызывает эту проблему?Любые полезные советы приветствуются. Спасибо.
Ответ №1:
Я удалил, а затем переустановил tensorflow
, my_env
и я больше не получаю ошибку.
tensorflow-gpu
ранее был установлен, когда tensorflow
уже существовал my_env
, что может привести к несовместимости или конкурирующим модулям.