#python #function #pytorch
Вопрос:
Мне любопытно, в чем разница между следующими строками кода:
a = torch.nn.BCELoss
и
b = torch.nn.BCELoss()
Я нахожу это очень интересным, что оба способа работают для потери Пайторча до н. э. Однако, если я попытаюсь сделать это с помощью пользовательской функции, я не смогу этого сделать:
b2 = my_func()
Это приводит к ошибке об отсутствующих аргументах. Только
a2 = my_func
работает. Моя функция определяется следующим образом:
def my_func(m,n):
return m n
Кроме того, почему это
b(x,y)
работает отлично, но
a(x,y)
Выдать ошибку? (Ошибка выполнения: Логическое значение тензора с более чем одним значением неоднозначно).
Комментарии:
1.
BCELoss
является классом,BCELoss()
создает объект экземпляра класса.
Ответ №1:
Классы-это первоклассные объекты (без каламбура) в Python; вы можете рассматривать их как значения, как и любое другое значение. torch.nn.BCELoss
это просто выражение, которое вычисляется как ссылка на класс. Классы могут быть вызваны, как torch.nn.BCELoss()
и вызов этого класса.
Вы также могли бы написать
x = torch.nn.BCELoss
b = x()
и это будет работать так же. x
и torch.nn.BCELoss
оба оценивают один и тот же class
объект.
Аналогично,
a2 = my_func
создает только a2
другое имя для функции, на которую ссылается my_func
. (Функции также являются объектами первого класса.)
b(x,y)
это то же самое torch.nn.BCELoss()(x,y)
, что, в то время a(x,y)
как это то же самое, что torch.nn.BCELoss(x,y)
. Первый вызывает экземпляр класса; второй-сам класс.
Ответ №2:
В Python есть «первоклассные функции», что означает, что функция на самом деле не является синтаксически особенной, как в Java. Вместо этого функция-это, по сути, просто объект, для которого __call__()
определен метод. Когда вы пишете функцию def
, python разберется с этой частью вручную.
Когда вы это сделаете
def my_func(m,n):
return m n
python создает объект с именем my_func
типа function
. При вызове он будет выполнять внутреннюю часть функции.
Вы можете либо вызвать функцию, которая выполнит ее и вернет требуемое значение ( m n
):
aa = my_func(1, 2)
# aa is now 3, because the function returned 1 2
или вы можете назначить функцию другой переменной, не вызывая ее.
bb = my_func
# the names `my_func` and `bb` now refer to the same thing, which is a function
cc = bb(3, 4)
# cc is now 7, because the function returned 3 4
Очевидно , что сейчас вы не можете позвонить cc()
, потому cc
что это целое число, а вызывать целое число не имеет смысла. Это относится к большинству функций — то, что они возвращают при вызове, обычно само по себе не поддается вызову.