Recently, while going through D2L (Dive into Deep Learning) code, I frequently noticed the “@” symbol appearing at the very top of classes or functions. Although Chapter 2 explains the comment #@save (indicating the following function is pre-defined in the package and can be used directly without redefinition), it does not explain the usage of the “@” symbol itself.
After researching, I found that “@” has two main meanings in Python:
In some textbooks, matrix multiplication is calculated using the matmul method (e.g., PyTorch’s torch.matmul). However, you can directly use “@” to represent matrix multiplication, as shown in this example:
import torch
from torch.utils import benchmark
typ = torch.float16
n = 1024*16
a = torch.randn(n,n).type(typ).cuda()
b = torch.randn(n,n).type(typ).cuda()
t = benchmark.Timer (
stmt='a @ b', # The "@" here means matrix multiplication
globals={'a':a,'b':b}
)
x=t.timeit(50)
2*n**3/x.median/1e12
Note: This usage is not exclusive to PyTorch—you’ll find it defined in the official Python documentation as well.
As an aside, I came across this code in one of Li Mu’s posts. For reference, the RTX 3060 scores around 28 on this benchmark—you can use it to test your GPU’s FP16 (half-precision floating-point) performance.
A decorator is a form of syntactic sugar (designed to reduce code redundancy). It means the class/function below the “@” symbol is passed as an argument to the function following the “@”.
For example, the official Python documentation provides this example—these two function definitions are equivalent:
def f(arg):
...
f = staticmethod(f)
@staticmethod
def f(arg):
...
As you can see, f is the argument to staticmethod.
Now let’s return to the code snippet from the start:
First, LinearRegression is a pre-defined class (not shown in the snippet). Second, d2l.add_to_class(LinearRegression) means the following function is added to the LinearRegression class as one of its methods.
If this example is still confusing, take a look at these screenshots:
You can see that model (an instance of the LinearRegression class) gains access to the newly added get_w_b() method after the decorator is applied.
I hope these will help someone in need~