ValueError: Please provide model inputs as a list or tuple of 2 or 3 elements: (input, target)

ValueError: Please provide model inputs as a list or tuple of 2 or 3 elements: (input, target)

报错信息

Traceback (most recent call last):  
  File "vae.py", line 170, in <module>  
    train_model(vae)  
  File "vae.py", line 161, in train_model  
    vae.fit(sequence, epochs=epochs)  
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/training.py", line 819, in fit
    use_multiprocessing=use_multiprocessing)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 235, in fit
    use_multiprocessing=use_multiprocessing)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 593, in _process_training_inputs
    use_multiprocessing=use_multiprocessing)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 706, in _process_inputs
    use_multiprocessing=use_multiprocessing)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/data_adapter.py", line 952, in __init__
    **kwargs)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/data_adapter.py", line 767, in __init__
    dataset = standardize_function(dataset)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 660, in standardize_function
    standardize(dataset, extract_tensors_from_dataset=False)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/training.py", line 2346, in _standardize_user_data
    all_inputs, y_input, dict_inputs = self._build_model_with_inputs(x, y)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/training.py", line 2523, in _build_model_with_inputs
    inputs, targets, _ = training_utils.extract_tensors_from_dataset(inputs)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/training_utils.py", line 1678, in extract_tensors_from_dataset
    inputs, targets, sample_weight = unpack_iterator_input(iterator)
  File "/home/fanjiarong/.local/lib/python2.7/site-packages/tensorflow_core/python/keras/engine/training_utils.py", line 1703, in unpack_iterator_input
    'Received %s' % next_element)

ValueError: Please provide model inputs as a list or tuple of 2 or 3 elements: (input, target) or (input, target, sample_weights)
Received tf.Tensor(
[[0.49803922 0.27058825 0.29803923 ... 0.         0.         0.        ]
 [0.49803922 0.27058825 0.29803923 ... 0.         0.         0.        ]
 [0.49803922 0.27058825 0.29803923 ... 0.         0.         0.        ]
 ...
 [0.49803922 0.27058825 0.29803923 ... 0.         0.         0.        ]
 [0.49803922 0.27058825 0.29803923 ... 0.         0.         0.        ]
 [0.49803922 0.27058825 0.29803923 ... 0.         0.         0.        ]], shape=(128, 7744), dtype=float32)   
2022-04-01 21:25:41.965783: W tensorflow/core/kernels/data/generator_dataset_op.cc:103] Error occurred when finalizing GeneratorDataset iterator: Cancelled: Operation was cancelled

分析程序

初始程序如下所示,在实现AE训练中的fit()函数报错,原因为函数接受的参数为向量化的种子文件(input),希望的参数为(input, target) or (input, target, sample_weights) 。我们需要明确对于分类问题,target应为input对应的类别,训练数据中包含数据及类别,可以直接读取;而对于自编码器target应为input对应的重构,需要将input输入AE网络中进行重构,此处使用fit()函数存在不妥。

class TrainSequence(keras.utils.Sequence):
    def __init__(self, input_file_dir, batch_size, configs = configs):
        pass
        
    def __len__(self):
        pass

    def __getitem__(self, idx):
        # 取一批
        batch_names = self.input_files[
            idx * self.batch_size: (idx + 1) * self.batch_size
        ]
        X_length = self.inpurt_sqrt_dim * self.inpurt_sqrt_dim
        a = vectorize_file(batch_names[0], X_length)
        b = vectorize_file(batch_names[1], X_length)
        test = np.array([a,b])
        # 读取并转为numpy矩阵,
        return np.array([vectorize_file(file_name, X_length) for file_name in batch_names])

sequence = TrainSequence(input_dir_path, batch_size, configs)
# 利用生成器提供数据
vae.fit(sequence, epochs=epochs)

修改程序

通过对自编码器的原理及训练过程进行学习,我们使用新的训练方式,通过GradientTape从头开始写训练/评估的循环,修改之后的代码如下所示。
tensorflow2.0 Seq2Seq多个输入时在model.fit()中使用生成器分批训练大量数据
自编码器(AutoEncoder)入门及TensorFlow实现
Tensorflow2 自定义训练

for epoch in range(epochs):
    print('epoch: ', epoch)
    for step, data in enumerate(sequence):
    	with tf.GradientTape() as tape:
         z_mean, z_log_var, z = self.encoder(data)
         reconstruction = self.decoder(z)
         # 重构损失函数
         # axis = -1指按最后一个dimension
         reconstruction_loss = tf.reduce_mean(keras.losses.binary_crossentropy(data, reconstruction))
         # 正则化约束损失函数
         kl_loss = -0.5 * (1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var))
         # 求和
         kl_loss = tf.reduce_mean(kl_loss)
         total_loss = reconstruction_loss + kl_loss
     grads = tape.gradient(total_loss, self.trainable_weights)
     self.optimizer.apply_gradients(zip(grads, self.trainable_weights))
     self.total_loss_tracker.update_state(total_loss)
     self.reconstruction_loss_tracker.update_state(reconstruction_loss)
     self.kl_loss_tracker.update_state(kl_loss)
vae.save_weights("vae_model_weight")

对于自编码器使用GradientTape从头开始写训练的循环可以避免上述错误。对于训练循环来说,主要包括下面几个部分:

  1. 用一个for循环来控制训练的轮次
  2. 在每轮训练过程中,用一个for循环来控制训练的批次
  3. 在每个批次中,构建一个GradientTape()
  4. 在这个域中,我们调用模型的前向传播,并计算loss
  5. 在域之外,我们计算loss对模型的参数的梯度
  6. 根据梯度,使用优化器更新模型的权重

你可能感兴趣的:(深度学习,神经网络)