首页 > 解决方案 > 如何使用 Tensorflow BatchDataset 训练模型?

问题描述

我正在尝试在 Tensorflow(2.4.1)中训练具有两个输入的模型。为此,我有一个批处理数据集,例如张量:

{'spectrogram': <tf.Tensor: shape=(7811, 129, 1), dtype=float32, numpy=
array([[[0.],
        [0.],
        [0.],
        ...,
        [0.],
        [0.],
        [0.]]], dtype=float32)>, 'label': <tf.Tensor: shape=(), dtype=string, numpy=b'Diese Feuerwehrleute verdienen Vertrauen.'>}

但是每次我尝试训练它时,它都会抛出这个错误:AttributeError: 'NoneType' object has no attribute 'shape'

我确定此错误源于此:

for batch in train_ds.take(1):
    print(batch.shape)

因为对 train 数据集的这个操作会引发类似的错误:AttributeError: 'dict' object has no attribute 'shape'

为了提供一些背景信息,这是我的一段代码:

train_list, validation_list, test_list = load_json_into_lists(TRAIN_DS_PATH, TEST_DS_PATH)
train_ds = preprocess_dataset(train_list)
val_ds = preprocess_dataset(validation_list)
test_ds = preprocess_dataset(test_list)

for batch in train_ds.take(1):
    # input_shape = batch["spectrogram"]
    # label_shape = batch["label"]
    print(batch)


    #print(batch.shape)
    #print('Input shape:', input_shape)
    #print(label_shape)

input_shape = (7811, 129, 1)

train_ds = train_ds.cache().prefetch(AUTOTUNE)
val_ds = val_ds.cache().prefetch(AUTOTUNE)

model = build_model(input_shape)
model.summary()

earlyStopping = Keras.callbacks.EarlyStopping(monitor="val_loss", mode="min", patience=10, restore_best_weights=True)
#modelCheckpoint = Keras.callbacks.ModelCheckpoint(SAVED_MODEL_PATH, monitor="val_acc", verbose=1, save_best_only=True, mode="max")

train_ds = train_ds.batch(BATCH_SIZE)
val_ds = val_ds.batch(BATCH_SIZE)

print(type(train_ds))

history = model.fit(
    train_ds, 
    validation_data=val_ds, 
    epochs=EPOCHS, 
    callbacks=[earlyStopping]
)

这是数据集和模型的请求构建:(数据集)文件参数是一个列表列表,如:[["filename","label"],["filename", "label"], [...] ]

@tf.autograph.experimental.do_not_convert
def preprocess_dataset(files):

    # Creating a new list, just including the filenames
    filenames_train_list = [sample[0] for sample in files]

    # Converting the filenames into tensors
    filename_tensors = string_to_tensor(tf.constant(filenames_train_list))

    # Creating a tensorflow dataset containing audio filenames
    files_ds = tf.data.Dataset.from_tensor_slices(filename_tensors)

    # Conversion into a waveform dataset (filenames converted to waveforms)
    waveform_ds = files_ds.map(lambda file_path: tf.py_function(get_waveform_and_label, [file_path], [tf.float32, tf.string]), num_parallel_calls=AUTOTUNE) 

    # Next Conversion: waveforms into spectrograms
    spectrogram_ds = waveform_ds.map(
        get_spectrogram_and_label, num_parallel_calls=AUTOTUNE
    )

    return spectrogram_ds 

与数据集关联的get_spectrogram_and_label()and函数:get_waveform_and_label()

    def get_spectrogram_and_label(waveform, label_in):
        spectrogram = get_spectrogram(waveform)
        spectrogram = tf.expand_dims(spectrogram, -1)
        return {"spectrogram": spectrogram, "label": label_in}

# Subfunction of get_waveform_and_label() to get the label 
# for a certain audio file
def get_label(file_path):

    # get the loaded lists
    train_list, _, _ = load_json_into_lists(TRAIN_DS_PATH, TEST_DS_PATH)

    for sublist in train_list:
        if sublist[0] == str(bytes.decode(file_path.numpy())):

            return string_to_tensor(sublist[1])

# Sub1function of get_waveform_and_label() to get the waveform 
# for a certain audio file
def get_waveform(file_path):

    # get the loaded lists
    train_list, _, _ = load_json_into_lists(TRAIN_DS_PATH, TEST_DS_PATH)

    for sublist in train_list:
        if sublist[0] == str(bytes.decode(file_path.numpy())):
            file_to_read = str("/Users/pietmuller/Dokumente/code/AI/E2EASRS/de/cv_valid_data/" + sublist[0])
            audio_binary = tf.io.read_file(file_to_read)
            waveform = decode_audio(audio_binary)

            return waveform

# Returning waveform and label for a certain filepath
def get_waveform_and_label(file_path):

    # get label
    label_ = get_label(file_path)

    # print("file_path: ", file_path)
    # print("label: ", label_)
    # print("label_, type(): ", type(label_))

    # get waveform
    waveform_ = get_waveform(file_path)

    # print("file_path: ", file_path)
    # print("waveform_: ", waveform_)
    # print("waveform_, type(): ", type(waveform_))

    return waveform_, label_

(模型)

def build_model(input_shape):

    time_dense_size = 32

    # Inputs to the model
    input_spectrogram = Input(shape=(input_shape), name="spectrogram", dtype="float32")

    labels = Input(shape=(None,), name="label", dtype="float32")

    #normalization = Keras.layers.experimental.preprocessing.Normalization()(input_spectrogram)

    # First conv block
    x = Conv2D(32, (3, 3), activation="relu", padding="same", name="Conv1")(input_spectrogram)
    x = MaxPooling2D(pool_size=(2, 2), name="pool1")(x)

    # Second conv block
    x = Conv2D(64, (3, 3), activation="relu", padding="same", name="Conv2")(x)
    x = MaxPooling2D(pool_size=(2, 2), name="pool2")(x)

    conv_to_rnn_dims = (7811 // (2 ** 2), (129 // (2 ** 2)) * 64)
    x = Keras.layers.Reshape(target_shape=conv_to_rnn_dims, name="reshape")(x)
    x = Dense(time_dense_size, activation="relu", name="dense1")(x)

    # RNNs
    gru_1 = Bidirectional(GRU(512, return_sequences=True, dropout=0.25, name="gru1"))(x)
    gru_1b = Bidirectional(GRU(512, return_sequences=True, dropout=0.25, name="gru1b"))(x)
    gru_1_merged = add([gru_1, gru_1b])

    gru_2 = Bidirectional(GRU(512, return_sequences=True, dropout=0.25, name="gru2"))(gru_1_merged)
    gru_2b = Bidirectional(GRU(512, return_sequences=True, dropout=0.25, name="gru2b"))(gru_1_merged)

    # Transforms RNN output to character activations:
    # x = Dense(NUM_CLASSES, name="dense2output")(concatenate([gru_2, gru_2b]))
    # y_pred = Activation("softmax", name="softmax")(x)

    x = Dense(NUM_CLASSES + 1, activation="softmax", name="softmax_dense")(concatenate([gru_2, gru_2b]))

    output = CTCLayer(name="ctc_loss")(labels, x)

    model = Keras.models.Model(
        inputs=[input_spectrogram, labels], outputs=output, name="sr_v1"
    )

    # Optimizer
    optimizer = Keras.optimizers.Adam(learning_rate=LEARNING_RATE)

    # Compile and return the model
    model.compile(optimizer=optimizer, metrics=["accuracy"])

    #Keras.utils.plot_model(model, "jarvis_v1.png")

    return model

这是完整的错误消息:

Traceback (most recent call last):
  File "train.py", line 368, in <module>
    main()
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/autograph/impl/api.py", line 620, in wrapper
    return func(*args, **kwargs)
  File "train.py", line 361, in main
    history = model.fit(
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 1100, in fit
    tmp_logs = self.train_function(iterator)
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py", line 828, in __call__
    result = self._call(*args, **kwds)
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py", line 871, in _call
    self._initialize(args, kwds, add_initializers_to=initializers)
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py", line 725, in _initialize
    self._stateful_fn._get_concrete_function_internal_garbage_collected(  # pylint: disable=protected-access
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/eager/function.py", line 2969, in _get_concrete_function_internal_garbage_collected
    graph_function, _ = self._maybe_define_function(args, kwargs)
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/eager/function.py", line 3361, in _maybe_define_function
    graph_function = self._create_graph_function(args, kwargs)
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/eager/function.py", line 3196, in _create_graph_function
    func_graph_module.func_graph_from_py_func(
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/framework/func_graph.py", line 990, in func_graph_from_py_func
    func_outputs = python_func(*func_args, **func_kwargs)
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py", line 634, in wrapped_fn
    out = weak_wrapped_fn().__wrapped__(*args, **kwds)
  File "/Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/framework/func_graph.py", line 977, in wrapper
    raise e.ag_error_metadata.to_exception(e)
AttributeError: in user code:

    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:805 train_function  *
        return step_function(self, iterator)
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:795 step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py:1259 run
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py:2730 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py:3417 _call_for_each_replica
        return fn(*args, **kwargs)
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:788 run_step  **
        outputs = model.train_step(data)
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:758 train_step
        self.compiled_metrics.update_state(y, y_pred, sample_weight)
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/compile_utils.py:387 update_state
        self.build(y_pred, y_true)
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/compile_utils.py:317 build
        self._metrics = nest.map_structure_up_to(y_pred, self._get_metric_objects,
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/util/nest.py:1159 map_structure_up_to
        return map_structure_with_tuple_paths_up_to(
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/util/nest.py:1257 map_structure_with_tuple_paths_up_to
        results = [
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/util/nest.py:1258 <listcomp>
        func(*args, **kwargs) for args in zip(flat_path_gen, *flat_value_gen)
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/util/nest.py:1161 <lambda>
        lambda _, *values: func(*values),  # Discards the path arg.
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/compile_utils.py:418 _get_metric_objects
        return [self._get_metric_object(m, y_t, y_p) for m in metrics]
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/compile_utils.py:418 <listcomp>
        return [self._get_metric_object(m, y_t, y_p) for m in metrics]
    /Users/pietmuller/Dokumente/code/AI/E2EASRS/tensor_venv/lib/python3.8/site-packages/tensorflow/python/keras/engine/compile_utils.py:439 _get_metric_object
        y_t_rank = len(y_t.shape.as_list())

    AttributeError: 'NoneType' object has no attribute 'shape'

标签: pythontensorflowmachine-learningkerasdeep-learning

解决方案


推荐阅读