Разница между a = Потерей и a = Потерей()

#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 что это целое число, а вызывать целое число не имеет смысла. Это относится к большинству функций — то, что они возвращают при вызове, обычно само по себе не поддается вызову.