Во-первых, я должен упомянуть, что у меня версия torch 0.3.1, но я буду рад обновить ее, если это необходимо.
Я все еще учусь, поэтому, пожалуйста, дайте мне знать, если я что-то неправильно понял.
Я обязательно строю несколько графиков, используя переменные. Со временем математические выражения могут быть довольно сложными, и некоторые части графиков могут быть созданы с использованием функций градиента autograd, с которыми затем можно будет работать.
Я могу создать любое выражение, которое захочу. Единственная загвоздка в том, что построение этого графика может быть довольно «медленным» - для относительно простых операций (умножение матриц 4x4) это может занять несколько мс.
Однако, как только эти графики будут сгенерированы, я надеюсь, что смогу обновлять значения определенных переменных и оценивать выходные данные графика (или любого узла, на самом деле) намного быстрее. Я считаю, что это, вероятно, так, поскольку оценка должна полностью выполняться в серверной части C, что должно быть довольно оптимизировано для скорости? Другими словами, построение графа в python может быть медленным, поскольку оно включает python для циклов и т.п., но переоценка графа со статической топологией должна быть быстрой.
Верна ли эта интуиция? Если да, как я могу эффективно переназначить значение и заново оценить график?
Если вы говорите об обновлении значений входных переменных, и вы просто хотите оценить прогресс графика и не собираетесь вызывать .backward()
, вы можете использовать volatile=True
на входных Variable
(s) в Pytorch 0.3.
Эта функция удалена в версии 0.4 и заменена диспетчером контекста with torch.no_grad():
.
Обычно это делается во время вывода. Если вы это сделаете, график не будет создан, что устранит накладные расходы.
Из документов Pytorch 0.3:
Volatile is recommended for purely inference mode, when you’re sure you won’t be even calling .backward(). It’s more efficient than any other autograd setting - it will use the absolute minimal amount of memory to evaluate the model. volatile also determines that requires_grad is False.
а также
Volatile differs from requires_grad in how the flag propagates. If there’s even a single volatile input to an operation, its output is also going to be volatile. Volatility spreads across the graph much easier than non-requiring gradient - you only need a single volatile leaf to have a volatile output, while you need all leaves to not require gradient to have an output that doesn’t require gradient. Using volatile flag you don’t need to change any settings of your model parameters to use it for inference. It’s enough to create a volatile input, and this will ensure that no intermediate states are saved.
Поэтому, если вы используете Pytorch 0.3 и хотите сделать эффективный вывод, вы используете volatile=True
на своих входах.
Менеджер контекста был представлен в Pytorch 0.4. Из Pytorch руководство по миграции между 0,3 и 0,4:
The volatile flag is now deprecated and has no effect. Previously, any computation that involves a Variable with volatile=True wouldn’t be tracked by autograd. This has now been replaced by a set of more flexible context managers including torch.no_grad(), torch.set_grad_enabled(grad_mode), and others.
Поэтому, когда вы говорите: «Тогда, если есть способ превратить все переменные этого графика в энергонезависимые, я могу просто выполнить вывод»., установка входа как volatile
или использование no_grad
сделает именно это.
Что касается примера использования torch.no_grad()
, посмотрите на функцию test
в этот сценарий.
Я не знаю ни одного метода, позволяющего избежать создания графа на каждой итерации в режиме обучения в Pytorch. За динамические графики приходится платить. Если вы этого хотите, преобразуйте свою модель в Tensorflow / Caffe2 / любую библиотеку, поддерживающую статические графики, даже если, по моему опыту, они не обязательно будут быстрее.
Теперь, когда я думаю об этом, это все еще может работать. Если я беру градиент с помощью автограда, я создаю новый график, если я правильно это понимаю. Затем, если есть способ превратить все переменные этого графика в энергонезависимые, я могу просто выполнить вывод. Я предполагаю, что диспетчер контекста - более чистый способ сделать это, верно?
Можете ли вы привести простой пример того, как вы могли бы использовать это в pytorch 0.4?
Обновлено, чтобы ответить на ваши вопросы
Спасибо за ваш ответ. Единственная проблема с этим решением заключается в том, что вы не можете получить градиенты чего-то нестабильного. Топология графа должна быть статической независимо от того, вычисляются ли градиенты относительно изменяющейся переменной или нет. Есть ли способ изменить значение, относительно которого вычисляются градиенты?