簡體   English   中英

Floras16比keras中的float32慢

[英]Float16 slower than float32 in keras

我正在測試我的新NVIDIA Titan V,它支持float16操作。 我注意到在訓練期間,float16比float32(~500 ms /步)慢得多(~800 ms /步)。

要執行float16操作,我將keras.json文件更改為:

{
"backend": "tensorflow",
"floatx": "float16",
"image_data_format": "channels_last",
"epsilon": 1e-07
}

為什么float16操作這么慢? 我是否需要修改我的代碼而不僅僅是keras.json文件?

我在Windows 10上使用CUDA 9.0,cuDNN 7.0,tensorflow 1.7.0和keras 2.1.5。我的python 3.5代碼如下:

img_width, img_height = 336, 224

train_data_dir = 'C:\\my_dir\\train'
test_data_dir = 'C:\\my_dir\\test'
batch_size=128

datagen = ImageDataGenerator(rescale=1./255,
    horizontal_flip=True,   # randomly flip the images 
    vertical_flip=True) 

train_generator = datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='binary')

test_generator = datagen.flow_from_directory(
    test_data_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='binary')

# Architecture of NN
model = Sequential()
model.add(Conv2D(32,(3, 3), input_shape=(img_height, img_width, 3),padding='same',kernel_initializer='lecun_normal'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32,(3, 3),padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64,(3, 3),padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64,(3, 3),padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(AveragePooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(1))
model.add(Activation('sigmoid'))

my_rmsprop = keras.optimizers.RMSprop(lr=0.0001, rho=0.9, epsilon=1e-04, decay=0.0)
model.compile(loss='binary_crossentropy',
          optimizer=my_rmsprop,
          metrics=['accuracy'])

# Training 
nb_epoch = 32
nb_train_samples = 512
nb_test_samples = 512

model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples/batch_size,
    epochs=nb_epoch,
    verbose=1,
    validation_data=test_generator,
    validation_steps=nb_test_samples/batch_size)

# Evaluating on the testing set
model.evaluate_generator(test_generator, nb_test_samples)

cuDNN文檔 (第2.7節, 類型轉換子節),您可以看到:

注意:累加器是32位整數,它們包含溢出。

並且這適用於以下標准INT8數據類型:數據輸入,濾波器輸入和輸出。

在這些假設下,@ jiandercy是正確的,有一個float16到float32轉換然后在返回結果之前進行反向轉換,而float16會更慢。

我更新到CUDA 10.0,cuDNN 7.4.1,tensorflow 1.13.1,keras 2.2.4和python 3.7.3。 使用與OP中相同的代碼,使用float16 over float32,訓練時間稍微快一些。

我完全相信更復雜的網絡架構會在性能上表現出更大的差異,但我沒有對此進行測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM