в идеале было бы решение, которое занимало бы размер не более двух переменных в памяти.
del
не часто требуется в Python.Повторение - это запах кода.Не повторяйте себя (принцип СУХОГО).Вы можете удалить повторение с помощью цикла.
def forward(self, A):
for _ in range(2):
Z = layer(A)
A = activation(Z)
return A
Вы будете повторно использовать две переменные A
и Z
.
Вы можете сжать это дальше, вложиввызовы, которые полностью удаляют Z
.
def forward(self, A):
for _ in range(2):
A = activation(layer(A))
return A
Если вы склонны к функциональности, этот паттерн известен как «уменьшить» (иногда также называемый «сгиб»).Это может быть менее "Pythonic", но функциональный стиль все еще довольно часто используется в коде Python.
from functools import reduce
def forward(self, X):
return reduce(lambda A, _: activation(layer(A)), range(2), X)
Или даже
def forward(self, X):
return reduce(lambda x, f: f(x), [layer, activation]*2, X)
Популярная библиотека toolz
также реализуетэтот шаблон
from toolz.functoolz import thread_first
def forward(self, X):
return thread_first(X, layer, activation, layer, activation)
Никаких промежуточных переменных не требуется, но вы можете добавлять комментарии, если вам от этого легче.
def forward(self, X):
return thread_first(
X, # A0
layer, # Z1
activation, # A1
layer, # Z2
activation, # A2
)
Они не применяются или что-то в этом роде.
Фактически, переменные вообще не требуются, за исключением параметра.
def forward(self, X):
return activate(layer(activate(layer(X))))
Функция действительно настолько проста, и суета вокруг имен переменных, кажется, слишком усложняет ее.
Для всего двух слоев это, вероятно, нормально, но версия с зацикливанием / сокращением упрощает добавление большего количества слоев позже, обновляя аргумент range()
, который может быть даже другим параметром для метода .forward()
.
не могли бы вы создать функцию, которая выполняет удаление и присваивание (с учетом ограничений области видимости) и каков там компромисс эффективности?
Вы не можете на самом делеdместные жители, за исключением del
(или когда они выходят за рамки видимости).Но вместо местных жителей вы можете создать собственное пространство имен.Это подкреплено диктовкой, которая лишь немного менее эффективна, чем местные жители, но ее здесь недостаточно.
from types import SimpleNamespace
class MonoNamespace(SimpleNamespace):
"""A namespace that holds only one attribute at a time."""
def __setattr__(self, name, value):
vars(self).clear()
vars(self)[name] = value
def forward(self, X):
ns = MonoNamespace(A0=X)
ns.Z1 = layer(ns.A0)
ns.A1 = activation(ns.Z1)
ns.Z2 = layer(ns.A1)
ns.A2 = activation(ns.Z2)
return ns.A2