警告:tensorflow:层my_model正在将输入张量从dtype float64转换为层的dt​​ype float32,这是TensorFlow 2中的新行为

时间:2019-12-18 21:20:35

标签: python tensorflow machine-learning deep-learning neural-network

在我的Tensorflow神经网络开始训练之前,会打印出以下警告:

  

警告:tensorflow:层my_model正在从投射输入张量   dtype float64到层的float32的dtype,这是新行为   在TensorFlow 2中。该图层具有dtype float32,因为它是dtype   默认为floatx。如果您打算在float32中运行此层,则可以   可以放心地忽略此警告。

     

如有疑问,可能会出现此警告   仅当将TensorFlow 1.X模型移植到TensorFlow时才有问题   2.要将所有层默认更改为dtype float64,请调用tf.keras.backend.set_floatx('float64')

     

要仅更改此层,   将dtype ='float64'传递给图层构造函数。如果你是作者   在此层,您可以通过传递autocast = False来禁用自动广播   到基本的Layer构造函数。

现在,根据给出的建议,我能够使此错误消息静音。但是,我想深入了解并手动设置正确的dtypes

完整代码:

import tensorflow as tf
from tensorflow.keras.layers import Dense, Concatenate
from tensorflow.keras import Model
from sklearn.datasets import load_iris
tf.keras.backend.set_floatx('float64')
iris, target = load_iris(return_X_y=True)

X = iris[:, :3]
y = iris[:, 3]

ds = tf.data.Dataset.from_tensor_slices((X, y)).shuffle(25).batch(8)

class MyModel(Model):
  def __init__(self):
    super(MyModel, self).__init__()
    self.d0 = Dense(16, activation='relu')
    self.d1 = Dense(32, activation='relu')
    self.d2 = Dense(1, activation='linear')

  def call(self, x):
    x = self.d0(x)
    x = self.d1(x)
    x = self.d2(x)
    return x

model = MyModel()

loss_object = tf.keras.losses.MeanSquaredError()

optimizer = tf.keras.optimizers.Adam(learning_rate=5e-4)

loss = tf.keras.metrics.Mean(name='loss')
error = tf.keras.metrics.MeanSquaredError()

@tf.function
def train_step(inputs, targets):
    with tf.GradientTape() as tape:
        predictions = model(inputs)
        run_loss = loss_object(targets, predictions)
    gradients = tape.gradient(run_loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    loss(run_loss)
    error(predictions, targets)

for epoch in range(10):
  for data, labels in ds:
    train_step(data, labels)

  template = 'Epoch {:>2}, Loss: {:>7.4f}, MSE: {:>6.2f}'
  print(template.format(epoch+1,
                        loss.result(),
                        error.result()*100))
  # Reset the metrics for the next epoch
  loss.reset_states()
  error.reset_states()

1 个答案:

答案 0 :(得分:5)

tl; dr 为避免这种情况,请将您的输入内容投射到float32

X = tf.cast(iris[:, :3], tf.float32) 
y = tf.cast(iris[:, 3], tf.float32)

或使用numpy

X = np.array(iris[:, :3], dtype=np.float32)
y = np.array(iris[:, 3], dtype=np.float32)

说明

默认情况下,Tensorflow使用floatx,默认为float32,这是深度学习的标准。您可以验证以下内容:

import tensorflow as tf
tf.keras.backend.floatx()
Out[3]: 'float32'

您提供的输入(虹膜数据集)的dtype为float64,因此Tensorflow的权重默认dtype与输入之间不匹配。 Tensorflow不喜欢这样,因为强制转换(更改dtype)的成本很高。在处理不同dtypes的张量时(例如,比较float32 logits和float64标签),Tensorflow通常会引发错误。

正在谈论的“新行为”:

图层my_model_1正在将dtype float64的输入张量强制转换为float32层的dtype,这是TensorFlow 2中的新行为

是它将自动将输入dtype强制转换为float32。在这种情况下,Tensorflow 1.X可能引发了异常,尽管我不能说我曾经使用过它。