【问题标题】:Training gets progressively slower over time随着时间的推移,训练变得越来越慢
【发布时间】:2020-08-25 09:26:29
【问题描述】:

这是我第一次遇到这个问题。我使用这个模型已经有一段时间了,但数据较少。问题在于,在前 3 个 epoch 中,训练花费了 11 秒/步(31k 个样本 / 128 个批量大小),而在第 4 个 epoch 中,它花费了 18 秒/步。在第五步中,大约需要 45 秒/步。我使用的是 Keras,没有做任何自定义循环恶作剧。

有人能解释一下这种放缓吗?模型没有中断。我正在使用 TF 2.3

Epoch 1/1200
248/248 [==============================] - 2727s 11s/step - loss: 2.3481 - acc: 0.3818 - top3_acc: 0.5751 - recall: 0.2228 - precision: 0.6195 - f1: 0.3239 - val_loss: 0.9020 - val_acc: 0.8085 - val_top3_acc: 0.8956 - val_recall: 0.5677 - val_precision: 0.9793 - val_f1: 0.7179
Epoch 2/1200
248/248 [==============================] - 2712s 11s/step - loss: 1.0319 - acc: 0.7203 - top3_acc: 0.8615 - recall: 0.5489 - precision: 0.9245 - f1: 0.6865 - val_loss: 0.5547 - val_acc: 0.8708 - val_top3_acc: 0.9371 - val_recall: 0.7491 - val_precision: 0.9661 - val_f1: 0.8435
Epoch 3/1200
248/248 [==============================] - 4426s 18s/step - loss: 0.7094 - acc: 0.8093 - top3_acc: 0.9178 - recall: 0.6830 - precision: 0.9446 - f1: 0.7920 - val_loss: 0.4399 - val_acc: 0.8881 - val_top3_acc: 0.9567 - val_recall: 0.8140 - val_precision: 0.9606 - val_f1: 0.8808
Epoch 4/1200
 18/248 [=>............................] - ETA: 3:14:16 - loss: 0.6452 - acc: 0.8338 - top3_acc: 0.9223 - recall: 0.7257 - precision: 0.9536 - f1: 0.8240

编辑:我只是在数据的超小样本(20 项/类别)上运行此程序,并且步骤时间没有增加。 proof

编辑 2:模型摘要

Model: "functional_3"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_token (InputLayer)        [(None, 300)]        0                                            
__________________________________________________________________________________________________
masked_token (InputLayer)       multiple             0           input_token[0][0]                
__________________________________________________________________________________________________
tf_distil_bert_model (TFDistilB ((None, 300, 768),)  66362880    masked_token[1][0]               
__________________________________________________________________________________________________
tf_op_layer_strided_slice (Tens multiple             0           tf_distil_bert_model[1][0]       
__________________________________________________________________________________________________
efficientnetb5_input (InputLaye [(None, 456, 456, 3) 0                                            
__________________________________________________________________________________________________
batch_normalization (BatchNorma (None, 768)          3072        tf_op_layer_strided_slice[1][0]  
__________________________________________________________________________________________________
efficientnetb5 (Functional)     (None, 15, 15, 2048) 28513527    efficientnetb5_input[0][0]       
__________________________________________________________________________________________________
dense (Dense)                   (None, 256)          196864      batch_normalization[1][0]        
__________________________________________________________________________________________________
global_average_pooling2d (Globa (None, 2048)         0           efficientnetb5[1][0]             
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 140)          35980       dense[1][0]                      
__________________________________________________________________________________________________
dense_3 (Dense)                 (None, 140)          286860      global_average_pooling2d[1][0]   
__________________________________________________________________________________________________
concatenate (Concatenate)       (None, 280)          0           dense_1[1][0]                    
                                                                 dense_3[1][0]                    
__________________________________________________________________________________________________
dense_4 (Dense)                 (None, 100)          28100       concatenate[0][0]                
__________________________________________________________________________________________________
dropout_20 (Dropout)            (None, 100)          0           dense_4[0][0]                    
__________________________________________________________________________________________________
dense_5 (Dense)                 (None, 20)           2020        dropout_20[0][0]                 
==================================================================================================
Total params: 95,429,303
Trainable params: 30,120
Non-trainable params: 95,399,183

【问题讨论】:

  • 你在使用回调吗?网络在训练期间的核矩阵传播总是相同的,所以它必须是你注入的某个过程。
  • @RyanCocuzzo 我只有提前停止回调。您认为这会导致这种情况吗?
  • 你在做强化学习吗?如果你的更新是基于一定数量的剧集,那么在训练开始时,剧集往往很短,更新可能会很快。
  • 是的,如果它不是回调并且我们假设所有 keras 代码都可以正常工作,那么这将是一个技术性很强的问题,可能是梯度爆炸式增加计算时间,或者“死”神经元在整个培训过程中以指数速度恢复活力等。这些不太可能,我希望它们不相关。
  • 我认为您由于泄漏而内存不足。这导致了一些问题。这是一个示例 - datascience.stackexchange.com/questions/61224/… 在帖子中注意,OP 代码的纪元时间会逐渐增加,就像你的代码一样。 16s、18s、21s ...

标签: tensorflow keras


【解决方案1】:

症状:

这似乎是由于泄漏导致的内存问题。首先,您可以在小批量但具有完整数据的情况下以恒定的纪元时间运行模型,纪元时间逐渐增加(时间/步长也增加!)。我假设当你用完内存时,由于资源有限,它会导致纪元时间增加。在经过一定程度的网络搜索后,似乎其他在 keras 中发生内存泄漏的人也有类似的“症状”w.r.t 纪元

例如检查这个link -

POST TITLE - “在训练 Keras LSTM 模型以对图像序列进行二元分类时内存不足”

Using TensorFlow backend.
Epoch 1/60
1/1 [==============================] - 16s 16s/step - loss: 0.7258 - acc: 0.5400 - val_loss: 0.7119 - val_acc: 0.6200
Epoch 2/60
1/1 [==============================] - 18s 18s/step - loss: 0.7301 - acc: 0.4800 - val_loss: 0.7445 - val_acc: 0.4000
Epoch 3/60
1/1 [==============================] - 21s 21s/step - loss: 0.7312 - acc: 0.4200 - val_loss: 0.7411 - val_acc: 0.4200
(...training continues...)

注意到逐渐增加的纪元时间了吗?


诊断:

检查内存使用情况(不使用 tensorboard)的一种方法是使用回调。这是我制作的一个虚拟代码,可以帮助您使用回调在每个 epoch 后获取内存使用情况。

import numpy as np
import tensorflow.keras as keras
import resource

class MemoryCallback(keras.callbacks.Callback):
    def on_epoch_end(self, epoch, log={}):
        print(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)

def build_model(shape):
    f_input = keras.layers.Input(shape=(shape[1],))  # (100,)
    d1 = keras.layers.Dense(50, activation='tanh')(f_input)
    d1 = keras.layers.Dense(50, activation='tanh')(d1)
    softmax = keras.layers.Dense(10, activation='softmax')(d1)
    return keras.Model(f_input, softmax)

data = np.random.random((1000, 100))
model = build_model(data.shape)
model.compile(loss='mse', optimizer='SGD')
model.fit(x=data, y=np.random.random((1000,)), verbose=0, epochs=10, callbacks=[MemoryCallback()])
312844288
312897536
312909824
312918016
312918016
312926208
312930304
312934400
312938496
312950784

确保在此处设置verbose=0。确保重新启动内核/python IDE,然后运行它,以便在检查之前清除内存。我假设您应该会看到这个数字逐渐增加。

如果您使用的是 Mac 或 Linux,您还可以在模型运行时使用 HTOP 查看您的内存使用情况。您应该看到最大内存上限。您可以在 mac 上使用 brew install 或在 linux 上使用 sudo apt-get 安装 HTOP。


解决方案:

this stackoverflow post 中建议了此问题的解决方案,这有助于限制 tf 使用的内存。

import tensorflow as tf
from keras.backend.tensorflow_backend import set_session

config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.9 # fraction of memory
config.gpu_options.visible_device_list = "0"

set_session(tf.Session(config=config))

【讨论】:

  • 您好,我明天早上第一件事就是试用配置文件 :) 感谢您的回答。我还记下了所提问题的链接,我将对其进行审查
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多