在我的Tensorflow神经网络开始训练之前,会打印出以下警告:
警告:tensorflow:Layer 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构造函数来禁用自动广播。
警告:tensorflow:Layer 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')。
tf.keras.backend.set_floatx('float64')
要仅更改此层,请将dtype =’float64’传递给该层构造函数。如果您是该层的作者,则可以通过将autocast = False传递给基本Layer构造函数来禁用自动广播。
现在,基于错误消息, 我可以 通过将后端设置为 来使此错误消息静音'float64'。但是,我想深入了解并dtypes手动设置正确的位置。
'float64'
dtypes
完整代码:
import tensorflow as tf from tensorflow.keras.layers import Dense, Concatenate from tensorflow.keras import Model from sklearn.datasets import load_iris 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()
tl; dr 为避免这种情况,请将您的输入投射到float32
float32
X = tf.cast(iris[:, :3], tf.float32) y = tf.cast(iris[:, 3], tf.float32)
或搭配numpy:
numpy
X = np.array(iris[:, :3], dtype=np.float32) y = np.array(iris[:, 3], dtype=np.float32)
说明
默认情况下,Tensorflow使用floatx,默认为float32,这是深度学习的标准。您可以验证以下内容:
floatx
import tensorflow as tf tf.keras.backend.floatx() Out[3]: 'float32'
您提供的输入(虹膜数据集)的输入类型为dtype float64,因此Tensorflow的默认权重dtype与输入之间不匹配。Tensorflow不喜欢这样,因为强制转换(更改dtype)的成本很高。操作不同dtype的张量时(例如,比较float32logit和float64标签),Tensorflow通常会引发错误。
float64
它所谈论的“新行为”:
图层my_model_1正在将dtype float64的输入张量转换为该图层的float32的dtype,这是TensorFlow 2中的新行为
是它将自动将输入dtype强制转换为float32。在这种情况下,Tensorflow 1.X可能引发了异常,尽管我不能说我曾经使用过它。