【问题标题】:GradientTape: getting gradient of nanGradientTape:获取nan的渐变
【发布时间】:2021-12-06 18:10:50
【问题描述】:

我正在尝试计算 tensorflow 中的梯度,但返回 None。我已经将类型调整为tensorflow.python.framework.ops.EagerTensor,但是htis并没有解决问题。

这是目前为止的代码:

accuracy = tf.keras.metrics.CategoricalAccuracy('accuracy')
loss = tf.keras.metrics.CategoricalCrossentropy('loss')
  
for epoch in range(epochs):
    accuracy.reset_states()
    loss.reset_states()
    
    for batch in iterate_minibatches(X_train, y_train, batch_size):
        imgs = batch[0]
        labels = batch[1]
        with tf.GradientTape() as tape:
            preds = model(imgs)
            
            labels = tf.convert_to_tensor(labels, dtype=tf.float32)
            
            #print(loss(labels,preds))
            # Loss is crossentropy loss with regularization term for each parameter
            total_loss = loss(labels, preds) #+l2_penalty(model, theta_A) 

        grads = tape.gradient(total_loss, model.trainable_variables)
        model.optimizer.apply_gradients(zip(grads, model.trainable_variables))
       
        accuracy.update_state(labels, preds)
        loss.update_state(labels, preds)
        print("\rEpoch: {}, Batch: {}, Loss: {:.3f}, Accuracy: {:.3f}".format(
            epoch+1, batch+1, loss.result().numpy(), accuracy.result().numpy()), flush=True, end='')
        print("")
   
print("Task B accuracy after training trained model on Task B: {}".format(model.evaluate(task_B_test)))
print("Task A accuracy after training trained model on Task B: {}".format(model.evaluate(task_A_test)))

有谁知道为什么它没有转或我该如何解决这个问题?

编辑:我的错误消息如下所示:

AttributeError Traceback(最近一次调用最后一次) C:\Users\DC5DE~1.ALB\AppData\Local\Temp/ipykernel_13300/818221091.py 在 34 grads = tape.gradient(total_loss, model.trainable_variables) 35 ---> 36 model.optimizer.apply_gradients(zip(grads, model.trainable_variables)) 37 38 accuracy.update_state(labels, preds)

AttributeError: 'NoneType' 对象没有属性 'apply_gradients'

由于我不确定这是否与我将图像数据传递给 GradientTape 的方式有关,这里是我的小批量函数:

def iterate_minibatches(inputs, targets, batchsize, shuffle=False):
    assert inputs.shape[0] == targets.shape[0]
    if shuffle:
        indices = np.arange(inputs.shape[0])
        np.random.shuffle(indices)
    for start_idx in range(0, inputs.shape[0] - batchsize + 1, batchsize):
        if shuffle:
            excerpt = indices[start_idx:start_idx + batchsize]
        else:
            excerpt = slice(start_idx, start_idx + batchsize)
        yield inputs[excerpt], targets[excerpt]

另外:here 提到了一个类似的问题,但是没有任何可行的解决方案。

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    你把一些事情搞混了。您要么需要调用model.compile,要么定义自己的优化器并使用它。此外,您不应将指标与损失函数混为一谈。这是一个工作示例:

    import tensorflow as tf
    
    accuracy = tf.keras.metrics.CategoricalAccuracy('accuracy')
    metric = tf.keras.metrics.CategoricalCrossentropy('metric_ categorical_crossentropy')
    loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
    epochs = 2
    model = tf.keras.Sequential([
        tf.keras.layers.Dense(units=3, input_shape=(1,))
    ]) 
    optimizer = tf.keras.optimizers.Adam()
    
    dataset = tf.data.Dataset.from_tensor_slices((tf.random.normal((50, 1)), tf.random.normal((50, 3)))).batch(5)
    for epoch in range(epochs):
        accuracy.reset_states()
        metric.reset_states()
        
        for i, batch in enumerate(dataset):
            imgs = batch[0]
            labels = batch[1]
            print(imgs.shape, labels.shape)
            with tf.GradientTape() as tape:
                preds = model(imgs)
                          
                #print(loss(labels,preds))
                # Loss is crossentropy loss with regularization term for each parameter
                total_loss = loss(labels, preds) #+l2_penalty(model, theta_A) 
    
            grads = tape.gradient(total_loss, model.trainable_variables)
            optimizer.apply_gradients(zip(grads, model.trainable_variables))
           
            accuracy.update_state(labels, preds)
            metric.update_state(labels, preds)
            print("\rEpoch: {}, Batch: {}, Loss: {:.3f}, Accuracy: {:.3f}".format(
                epoch+1, i+1, metric.result().numpy(), accuracy.result().numpy()), flush=True, end='')
            print("")
    
    Epoch: 1, Batch: 1, Loss: 4.209, Accuracy: 0.200
    Epoch: 1, Batch: 2, Loss: 1.641, Accuracy: 0.400
    Epoch: 1, Batch: 3, Loss: 1.294, Accuracy: 0.333
    Epoch: 1, Batch: 4, Loss: 1.025, Accuracy: 0.300
    Epoch: 1, Batch: 5, Loss: -0.110, Accuracy: 0.320
    Epoch: 1, Batch: 6, Loss: 0.316, Accuracy: 0.267
    Epoch: 1, Batch: 7, Loss: -0.118, Accuracy: 0.257
    Epoch: 1, Batch: 8, Loss: -0.284, Accuracy: 0.225
    Epoch: 1, Batch: 9, Loss: -0.249, Accuracy: 0.244
    Epoch: 1, Batch: 10, Loss: -0.464, Accuracy: 0.260
    Epoch: 2, Batch: 1, Loss: 4.468, Accuracy: 0.200
    Epoch: 2, Batch: 2, Loss: 1.578, Accuracy: 0.400
    Epoch: 2, Batch: 3, Loss: 1.012, Accuracy: 0.400
    Epoch: 2, Batch: 4, Loss: 0.836, Accuracy: 0.350
    Epoch: 2, Batch: 5, Loss: -0.294, Accuracy: 0.360
    Epoch: 2, Batch: 6, Loss: 0.168, Accuracy: 0.300
    Epoch: 2, Batch: 7, Loss: -0.201, Accuracy: 0.286
    Epoch: 2, Batch: 8, Loss: -0.634, Accuracy: 0.250
    Epoch: 2, Batch: 9, Loss: -0.552, Accuracy: 0.267
    Epoch: 2, Batch: 10, Loss: -0.920, Accuracy: 0.280
    

    【讨论】:

      【解决方案2】:

      您需要使用tf.keras.losses.CategoricalCrossentropy 进行损失计算,而不是使用tf.keras.metrics.CategoricalCrossentropy,后者的工作方式不同并且会停止梯度传播。

      【讨论】:

      • 谢谢你,但不幸的是错误仍然存​​在......
      • AttributeError: 'NoneType' object has no attribute 'apply_gradients' 错误消息是因为您没有使用 model.compile(...) 使用优化器编译模型
      猜你喜欢
      • 2022-01-11
      • 2019-11-30
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多