Обучение нарушилось с ошибкой ResourceExausted
Я новичок в области тензорного потока и машинного обучения. Недавно я работаю над моделью. Моя модель похожа на ниже,
-
Уровень символов Вложение Vector → Поиск встраивания → LSTM1
-
Уровень слова Встраивание Vector- > Поиск вложения → LSTM2
-
[LSTM1 + LSTM2] → однослойный слой MLP- > softmax
-
[LSTM1 + LSTM2] → Однослойный MLP- > дискриминатор WGAN
-
Код модели rnn
пока я работаю над этой моделью, я получил следующую ошибку. Я думал, что моя партия слишком большая. Таким образом, я попытался уменьшить размер партии от 20 до 10, но это не сработает.
ResourceExhaustedError (см. выше для отслеживания): OOM при распределении тензор с формой [24760,100] [[ Node: chars/bidirectional_rnn/bw/bw/while/bw/lstm_cell/split = Разделить [T = DT_FLOAT, num_split = 4, _device = "/работа: локальный/реплика: 0/задача: 0/устройство: ГПУ: 0" ] (gradients_2/Add_3/у, chars/bidirectional_rnn/bw/bw/while/bw/lstm_cell/BiasAdd)]] [[Node: bi-lstm/bidirectional_rnn/bw/bw/stack/_167 = _Recvclient_terminated = false, recv_device = "/job: localhost/replica: 0/task: 0/device: CPU: 0", send_device = "/работа: локальный/реплика: 0/задача: 0/устройства: GPU: 0", send_device_incarnation = 1, tensor_name = "edge_636_bi-LSTM/bidirectional_rnn/мт/мт/стопка", tensor_type = DT_INT32, _device = "/работа: локальный/реплика: 0/задача: 0/Устройство: ЦП: 0" ]]
с формой [24760,100] означает 2476000 * 32/8 * 1024 * 1024 = 9.44519043 МБ памяти. Я запускаю код на графическом процессоре titan X (11 ГБ). Что может пойти не так? Почему произошел этот тип ошибки?
* Дополнительная информация *: размер LSTM1 равен 100. Для двунаправленного LSTM он становится 200.
Размер LSTM2 равен 300. Для двунаправленного LSTM оно составляет 600.
* Примечание *: ошибка произошла после 32 эпох. Мой вопрос в том, почему после 32 эпохи есть ошибка. Почему бы не в начальную эпоху.
Ответы
Ответ 1
В наши дни я много настраивал, чтобы решить эту проблему.
Наконец, я не решил тайну размера памяти, описанной в вопросе. Я предполагаю, что при вычислении градиента tensoflow накапливается много дополнительной памяти для вычисления градиента. Мне нужно проверить источник тензорного потока, который кажется очень громоздким в это время. Вы можете проверить, сколько памяти ваша модель использует на терминале по следующей команде:
nvidia-smi
Судя по этой команде, вы можете угадать, сколько дополнительной памяти вы можете использовать.
Но решение этого типа проблемы заключается в уменьшении размера партии,
В моем случае уменьшается размер партии до 3 работ. Это может варьироваться модели к модели.
Но что, если вы используете модель, где матрица внедрения намного больше, чем вы не можете загрузить их в память?
Решение состоит в том, чтобы написать какой-то больной код.
Вам нужно искать матрицу внедрения, а затем загрузить вложение в модель. Короче говоря, для каждой партии вам нужно предоставить матрицы поиска в модель (подавать их по аргументу feed_dict в sess.run()
).
Затем вы столкнетесь с новой проблемой,
Вы не можете сделать вложения trainable
таким образом. Решение состоит в том, чтобы использовать вложение в placeholder
и назначить их <<24 > (например, A
). После каждой серии обучения алгоритм обучения обновляет переменную A
. Затем вычислите вывод вектора A
тензорным потоком и назначьте их своей матрице встраивания, которая находится вне модели. (Я сказал, что процесс мучительный)
Теперь ваш следующий вопрос должен быть, что, если вы не можете кормить поиск встраивания в модель, потому что он такой большой. Это фундаментальная проблема, которую вы не можете избежать. Вот почему NVIDIA GTX 1080, 1080ti и NVIDA TITAN Xp имеют такую разницу в цене, хотя у NVIDIA 1080ti и 1080 есть более высокая частота для запуска исполнения.
Ответ 2
* Примечание *: Ошибка произошла после 32 эпох. Мой вопрос в том, почему после 32 эпохи есть ошибка. Почему бы не в начальную эпоху.
Это важный ключ к тому, что граф не статичен во время выполнения. Под этим я подразумеваю, что вы скорее всего выполняете sess.run(tf.something)
вместо
my_something = tf.something
with tf.Session() as sess:
sess.run(my_something)
Я столкнулся с той же проблемой, пытающейся реализовать RNN с состоянием. Я бы иногда был reset состоянием, поэтому я делал sess.run([reset if some_condition else tf.no_op()])
. Просто добавив nothing = tf.no_op()
к моему графику и используя sess.run([reset if some_condition else nothing])
решил мою проблему.
Если бы вы могли опубликовать цикл обучения, было бы легче сказать, что это не так.