在我的TensorFlow神经网络开始训练之前,会打印出以下警告:
警告:tensorflow:层my_model正在将输入张量从dtype float64转换为该层的dtype float32,这是TensorFlow 2中的新行为。该层的dtype为float32,因为它的dtype默认值为floatx。如果您打算以float32运行此层,您可以安全地忽略此警告。
如果有疑问,此警告可能仅在您将TensorFlow 1.X模型移植到TensorFlow 2时才是个问题。要将所有层的dtype默认设置为float64,请调用
tf.keras.backend.set_floatx('float64')
。
要仅更改此层,请在层构造函数中传递dtype=’float64’。如果您是此层的作者,您可以通过在基础层构造函数中传递autocast=False来禁用自动转换。
现在,根据错误消息,我可以通过将后端设置为 'float64'
来静音此错误消息。但是,我希望深入了解并手动设置正确的 dtypes
。
完整代码:
import tensorflow as tffrom tensorflow.keras.layers import Dense, Concatenatefrom tensorflow.keras import Modelfrom sklearn.datasets import load_irisiris, 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 xmodel = 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.functiondef 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()
回答:
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 tftf.keras.backend.floatx()
Out[3]: 'float32'
您提供的输入(Iris数据集)是dtype float64
,因此TensorFlow的权重默认dtype与输入之间存在不匹配。TensorFlow不喜欢这种情况,因为转换dtype(更改dtype)成本高昂。TensorFlow在处理不同dtype的张量时通常会抛出错误(例如,比较 float32
logits 和 float64
标签)。
它提到的“新行为”:
层my_model_1正在将输入张量从dtype float64转换为该层的dtype float32,这是TensorFlow 2中的新行为
是指它会自动将输入dtype转换为 float32
。TensorFlow 1.X在这种情况下可能会抛出异常,尽管我从未使用过它。