Python 在张量流模型训练中启用混合精度会降低速度,而不是提高速度

Python 在张量流模型训练中启用混合精度会降低速度,而不是提高速度,python,tensorflow,keras,Python,Tensorflow,Keras,我正在使用NVIDIA RTX-2060(带图灵核心)进行深度学习模型培训。正如在线论坛上提到的,启用混合精度训练有助于图灵体系结构卡比不使用混合精度训练时训练更快。当我启用混合精度训练时,每一步的时间增加而不是减少。我无法理解为什么会发生这种情况,我真的很感激任何人提出解决方案。我花了这么多钱买这个gpu,如果我不能让它更快地训练模型,那就没用了 代码: 将tensorflow导入为tf def create_model(): 模型=keras.连续([ keras.layers.Flatte

我正在使用NVIDIA RTX-2060(带图灵核心)进行深度学习模型培训。正如在线论坛上提到的,启用混合精度训练有助于图灵体系结构卡比不使用混合精度训练时训练更快。当我启用混合精度训练时,每一步的时间增加而不是减少。我无法理解为什么会发生这种情况,我真的很感激任何人提出解决方案。我花了这么多钱买这个gpu,如果我不能让它更快地训练模型,那就没用了

代码:

将tensorflow导入为tf
def create_model():
模型=keras.连续([
keras.layers.Flatten(输入_形状=(32,32,3)),
keras.层.致密(3000,活化='relu'),
keras.层.致密(1000,活化='relu'),
keras。层。致密(10层,S形)
])
compile(优化器='SDG',
损失='categorical_crossentropy',
指标=[‘准确度’])
回归模型
tf.keras.mixed_precision.set_global_policy('mixed_float16'))
%%timeit-n1-r1#执行此单元格一次所需的时间
模型=创建_模型()
模型拟合(X序列按比例,y序列按类别,历代=50)
你必须知道的事情:

import tensorflow as tf
from tensorflow import keras


def create_model():
    model = keras.Sequential([
        keras.layers.Flatten(input_shape=(32, 32, 3)),
        keras.layers.Dense(3000, activation='relu'),
        keras.layers.Dense(1000, activation='relu'),
        # keras.layers.Dense(10, activation='sigmoid'),
        keras.layers.Dense(10,),
        keras.layers.Activation('sigmoid', dtype='float32'),
    ])

    model.compile(optimizer='SGD',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

    return model


tf.keras.mixed_precision.set_global_policy('mixed_float16')

(X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()

# There are 10 image classes
classes = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"]

X_train_scaled = X_train / 255
X_test_scaled = X_test / 255

y_train_categorical = keras.utils.to_categorical(y_train, num_classes= 10, dtype='float')
y_test_categorical = keras.utils.to_categorical(y_test, num_classes= 10, dtype='float')

with tf.device('/GPU:0'):
    model = create_model()
    model.fit(X_train_scaled, y_train_categorical, epochs=50)

model.evaluate(X_test_scaled, y_test_categorical)
我已经成功安装了cuda和cudnn,tensorflow可以检测到我的gpu

我已经安装了tensorflow gpu

我正在用nvidia rtx 2060 gpu在ciphar10数据集上训练我的模型


我一直在使用Jupyter笔记本进行基准测试:

当您使用CIFAR数据集时,我认为您的最后一层激活应该
softmax
,而不是
sigmoid
,以及您的损失函数
Category\u crossentropy
。并确保它是
float32

keras.layers.Dense(10, activation='softmax', dtype=tf.float32)
def create_model():
    model = keras.Sequential([
        keras.layers.Flatten(input_shape=(32, 32, 3)),
        keras.layers.Dense(3000, activation='relu'),
        keras.layers.Dense(1000, activation='relu'),
        # keras.layers.Dense(10, activation='sigmoid'), # NOTE: Replaced this line by two lines below
        keras.layers.Dense(10,),
        keras.layers.Activation('sigmoid', dtype='float32'),
    ])

    model.compile(optimizer='SGD',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

    return model

您应该在开始时设置一个混合精度全局策略,就在
tf
导入之后。以下是在GPU上使用混合精度时的一些提示。从

增加批处理大小 如果不影响模型质量,请在使用
混合精度时尝试以双倍的
批量运行。由于
float16
张量占用了一半的内存,这通常允许您将
批处理大小增加一倍,而无需在内存不足的情况下运行。增加批大小通常会增加训练吞吐量,即模型每秒可运行的训练元素

确保使用GPU张量磁芯 现代NVIDIA GPU使用一种称为“Tensor Cores”的特殊硬件单元,它可以非常快速地将
float16
矩阵相乘。然而,张量核要求张量的某些维数为8的倍数

在下面的例子中,当且仅当张量核需要是8的倍数时,参数才为粗体

  • tf.keras.layers.Dense(单位=64
  • tf.keras.layers.Conv2d(过滤器=48,内核大小=7,步长=3)
  • tf.keras.layers.LSTM(单位=64
  • tf.keras.Model.fit(历代=2,批量大小=128


如果正确遵循此过程,则应充分利用
混合精度
。这是NVIDIA的一篇好文章。

当您使用CIFAR数据集时,我认为您的最后一层激活应该
softmax
,而不是
sigmoid
,以及您的损失函数
分类交叉熵。并确保它是
float32

keras.layers.Dense(10, activation='softmax', dtype=tf.float32)
def create_model():
    model = keras.Sequential([
        keras.layers.Flatten(input_shape=(32, 32, 3)),
        keras.layers.Dense(3000, activation='relu'),
        keras.layers.Dense(1000, activation='relu'),
        # keras.layers.Dense(10, activation='sigmoid'), # NOTE: Replaced this line by two lines below
        keras.layers.Dense(10,),
        keras.layers.Activation('sigmoid', dtype='float32'),
    ])

    model.compile(optimizer='SGD',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

    return model

您应该在开始时设置一个混合精度全局策略,就在
tf
导入之后。以下是在GPU上使用混合精度时的一些提示。从

增加批处理大小 如果不影响模型质量,请在使用
混合精度时尝试以双倍的
批量运行。由于
float16
张量占用了一半的内存,这通常允许您将
批处理大小增加一倍,而无需在内存不足的情况下运行。增加批大小通常会增加训练吞吐量,即模型每秒可运行的训练元素

确保使用GPU张量磁芯 现代NVIDIA GPU使用一种称为“Tensor Cores”的特殊硬件单元,它可以非常快速地将
float16
矩阵相乘。然而,张量核要求张量的某些维数为8的倍数

在下面的例子中,当且仅当张量核需要是8的倍数时,参数才为粗体

  • tf.keras.layers.Dense(单位=64
  • tf.keras.layers.Conv2d(过滤器=48,内核大小=7,步长=3)
  • tf.keras.layers.LSTM(单位=64
  • tf.keras.Model.fit(历代=2,批量大小=128


如果正确遵循此过程,则应充分利用
混合精度
。是NVIDIA的一个很好的读物。

根据的官方指南,要正确使用混合精度,您的
sigmoid
在模型末尾的激活应该是
float32
。因为我们设置了策略
mixed\u float16
,所以激活的
compute\u dtype
float16
。因此,我们必须将该层的策略覆盖为
float32

keras.layers.Dense(10, activation='softmax', dtype=tf.float32)
def create_model():
    model = keras.Sequential([
        keras.layers.Flatten(input_shape=(32, 32, 3)),
        keras.layers.Dense(3000, activation='relu'),
        keras.layers.Dense(1000, activation='relu'),
        # keras.layers.Dense(10, activation='sigmoid'), # NOTE: Replaced this line by two lines below
        keras.layers.Dense(10,),
        keras.layers.Activation('sigmoid', dtype='float32'),
    ])

    model.compile(optimizer='SGD',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

    return model
把所有内容放在一起,我们就有了训练CIFAR10数据集的完整源代码,精度参差不齐:

import tensorflow as tf
from tensorflow import keras


def create_model():
    model = keras.Sequential([
        keras.layers.Flatten(input_shape=(32, 32, 3)),
        keras.layers.Dense(3000, activation='relu'),
        keras.layers.Dense(1000, activation='relu'),
        # keras.layers.Dense(10, activation='sigmoid'),
        keras.layers.Dense(10,),
        keras.layers.Activation('sigmoid', dtype='float32'),
    ])

    model.compile(optimizer='SGD',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

    return model


tf.keras.mixed_precision.set_global_policy('mixed_float16')

(X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()

# There are 10 image classes
classes = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"]

X_train_scaled = X_train / 255
X_test_scaled = X_test / 255

y_train_categorical = keras.utils.to_categorical(y_train, num_classes= 10, dtype='float')
y_test_categorical = keras.utils.to_categorical(y_test, num_classes= 10, dtype='float')

with tf.device('/GPU:0'):
    model = create_model()
    model.fit(X_train_scaled, y_train_categorical, epochs=50)

model.evaluate(X_test_scaled, y_test_categorical)
使用我的GPU
NVIDIA RTX2080
,我使用混合精度比较了有(称为
P1
)和无(称为
P2
)的性能,发现:

  • 训练时间:因为每一步的时间是四舍五入的,而