Skip to content

Commit cd3bde4

Browse files
committed
up
1 parent a4ff8d9 commit cd3bde4

File tree

9 files changed

+251
-57
lines changed

9 files changed

+251
-57
lines changed

NOTES.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Notes
2+
3+
4+
5+
## Inside Deep Learning Book
6+
7+
7.6. Convolutional Neural Networks (LeNet) @
8+
<https://d2l.ai/chapter_convolutional-neural-networks/lenet.html>
9+
10+
8.1. Deep Convolutional Neural Networks (AlexNet)
11+
@ <https://d2l.ai/chapter_convolutional-modern/alexnet.html>
12+
13+

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Various variants of LeNet v5 & friends
77

88

99

10-
## LeNet v5
10+
## LeNet v5 (Anno 1995)
1111

1212
The classic (original) LeNet v5
1313
has two convolutions layers
@@ -115,6 +115,14 @@ That's it.
115115

116116
The award-winning AlexNet is basically a LeNet5 scaled up 1000x and
117117
introduces relu activation, dropout layers, and more to the world (of deep neural networks).
118+
119+
![](lenet-to-alexnet.png)
120+
121+
> AlexNet is much deeper than the comparatively small LeNet-5.
122+
> AlexNet consists of eight layers: five convolutional layers,
123+
> two fully connected hidden layers, and one fully connected output layer.
124+
125+
118126
The summary of the model reads:
119127

120128

alexnet/SUMMARY.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ to generate - try
66

77
resulting in:
88

9-
## AlexNet input_size=(3, 224, 224)
9+
## AlexNet (via Torchvision) input_size=(3, 224, 224)
1010

1111
```
1212
AlexNet(
@@ -78,5 +78,73 @@ Estimated Total Size (MB): 242.03
7878

7979

8080

81+
## AlexNet input_size=(3, 224, 224)
82+
83+
```
84+
AlexNet(
85+
(layers): Sequential(
86+
(0): Conv2d(3, 96, kernel_size=(11, 11), stride=(4, 4), padding=(1, 1))
87+
(1): ReLU()
88+
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
89+
(3): Conv2d(96, 256, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
90+
(4): ReLU()
91+
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
92+
(6): Conv2d(256, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
93+
(7): ReLU()
94+
(8): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
95+
(9): ReLU()
96+
(10): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
97+
(11): ReLU()
98+
(12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
99+
(13): Flatten(start_dim=1, end_dim=-1)
100+
(14): Linear(in_features=6400, out_features=4096, bias=True)
101+
(15): ReLU()
102+
(16): Dropout(p=0.5, inplace=False)
103+
(17): Linear(in_features=4096, out_features=4096, bias=True)
104+
(18): ReLU()
105+
(19): Dropout(p=0.5, inplace=False)
106+
(20): Linear(in_features=4096, out_features=1000, bias=True)
107+
)
108+
)
109+
Total number of trainable model parameters: 50844008
110+
about 192.45 MBs, 197836.61 KBs
111+
112+
----------------------------------------------------------------
113+
Layer (type) Output Shape Param #
114+
================================================================
115+
Conv2d-1 [-1, 96, 54, 54] 34,944
116+
ReLU-2 [-1, 96, 54, 54] 0
117+
MaxPool2d-3 [-1, 96, 26, 26] 0
118+
Conv2d-4 [-1, 256, 26, 26] 614,656
119+
ReLU-5 [-1, 256, 26, 26] 0
120+
MaxPool2d-6 [-1, 256, 12, 12] 0
121+
Conv2d-7 [-1, 384, 12, 12] 885,120
122+
ReLU-8 [-1, 384, 12, 12] 0
123+
Conv2d-9 [-1, 384, 12, 12] 1,327,488
124+
ReLU-10 [-1, 384, 12, 12] 0
125+
Conv2d-11 [-1, 256, 12, 12] 884,992
126+
ReLU-12 [-1, 256, 12, 12] 0
127+
MaxPool2d-13 [-1, 256, 5, 5] 0
128+
Flatten-14 [-1, 6400] 0
129+
Linear-15 [-1, 4096] 26,218,496
130+
ReLU-16 [-1, 4096] 0
131+
Dropout-17 [-1, 4096] 0
132+
Linear-18 [-1, 4096] 16,781,312
133+
ReLU-19 [-1, 4096] 0
134+
Dropout-20 [-1, 4096] 0
135+
Linear-21 [-1, 1000] 4,097,000
136+
================================================================
137+
Total params: 50,844,008
138+
Trainable params: 50,844,008
139+
Non-trainable params: 0
140+
----------------------------------------------------------------
141+
Input size (MB): 0.57
142+
Forward/backward pass size (MB): 10.23
143+
Params size (MB): 193.95
144+
Estimated Total Size (MB): 204.76
145+
----------------------------------------------------------------
146+
```
147+
148+
81149

82150

alexnet/eval.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55

66
### local imports
7-
from model import model
7+
from models import model
88

99

1010

alexnet/model.py

Lines changed: 0 additions & 38 deletions
This file was deleted.

alexnet/models.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
####
2+
# alexnet models
3+
4+
5+
import torch
6+
import torch.nn as nn
7+
from torchvision import models
8+
from torchvision.models import AlexNet_Weights
9+
10+
## pre-built via torchvision including weights
11+
model = models.alexnet( weights=AlexNet_Weights.IMAGENET1K_V1 )
12+
13+
14+
15+
####
16+
# do-it-yourself version via
17+
# https://d2l.ai/chapter_convolutional-modern/alexnet.html
18+
19+
20+
class AlexNet(nn.Module):
21+
def __init__(self,num_classes=1000):
22+
super(AlexNet, self).__init__()
23+
24+
self.layers = nn.Sequential(
25+
nn.LazyConv2d(96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
26+
nn.MaxPool2d(kernel_size=3, stride=2),
27+
nn.LazyConv2d(256, kernel_size=5, padding=2), nn.ReLU(),
28+
nn.MaxPool2d(kernel_size=3, stride=2),
29+
nn.LazyConv2d(384, kernel_size=3, padding=1), nn.ReLU(),
30+
nn.LazyConv2d(384, kernel_size=3, padding=1), nn.ReLU(),
31+
nn.LazyConv2d(256, kernel_size=3, padding=1), nn.ReLU(),
32+
nn.MaxPool2d(kernel_size=3, stride=2),
33+
nn.Flatten(),
34+
nn.LazyLinear(4096), nn.ReLU(),
35+
nn.Dropout(p=0.5),
36+
nn.LazyLinear(4096), nn.ReLU(),
37+
nn.Dropout(p=0.5),
38+
nn.LazyLinear(num_classes)
39+
)
40+
41+
def forward(self, x):
42+
# Forward pass through the network
43+
return self.layers( x )
44+
45+
46+
47+
48+
if __name__ == '__main__':
49+
# Print the model summaries
50+
from torchsummary import summary
51+
52+
def print_model( model, input_size ):
53+
print( "="*20,
54+
f"\n= {model.__class__.__name__} input_size={input_size}" )
55+
56+
print()
57+
print(model)
58+
59+
num_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
60+
print("Total number of trainable model parameters:", num_params)
61+
total_bytes = num_params * 4 # assume float32 (4 bytes)
62+
print( f"about {total_bytes / (1028 *1028) :.2f} MBs, {total_bytes / 1028 :.2f} KBs" )
63+
64+
print( "\nsummary:")
65+
summary(model, input_size)
66+
67+
68+
print_model( model, input_size=(3, 224, 224) )
69+
70+
model = AlexNet()
71+
x = torch.randn(3,224,224).unsqueeze(0)
72+
y = model.forward( x )
73+
## note - (auto-)summary not working for now (not working with Lazy) e.g.
74+
## ValueError: Attempted to use an uninitialized parameter in
75+
## <method 'numel' of 'torch._C.TensorBase' objects>.
76+
## This error happens when you are using a `LazyModule`
77+
## or explicitly manipulating `torch.nn.parameter.UninitializedParameter` objects.
78+
## When using LazyModules Call `forward` with a dummy batch to initialize
79+
## the parameters before calling torch functions
80+
print_model( model, input_size=(3, 224, 224) )
81+
print("bye")
82+

lenet-to-alexnet.png

56.6 KB
Loading

models.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,15 @@ def __init__(self):
5050

5151
self.layers = nn.Sequential(
5252
# Layer 1: Convolutional layer with 6 filters of size 5x5
53-
nn.Conv2d(1, 6, kernel_size=5),
54-
nn.Tanh(),
53+
nn.Conv2d(1, 6, kernel_size=5), nn.Tanh(),
5554
nn.AvgPool2d(kernel_size=2, stride=2), # Subsampling (avg pooling)
5655
# Layer 2: Convolutional layer with 16 filters of size 5x5
57-
nn.Conv2d(6, 16, kernel_size=5),
58-
nn.Tanh(),
56+
nn.Conv2d(6, 16, kernel_size=5), nn.Tanh(),
5957
nn.AvgPool2d(kernel_size=2, stride=2), # Subsampling (avg pooling)
6058
nn.Flatten(),
6159
# Fully connected layers
62-
nn.Linear(16 * 5 * 5, 120), # Flattened output from previous layer
63-
nn.Tanh(),
64-
nn.Linear(120, 84),
65-
nn.Tanh(),
60+
nn.Linear(16 * 5 * 5, 120), nn.Tanh(), # Flattened output from previous layer
61+
nn.Linear(120, 84), nn.Tanh(),
6662
nn.Linear(84, 10) # Output layer with 10 classes
6763
)
6864

@@ -148,19 +144,15 @@ def __init__(self):
148144

149145
self.layers = nn.Sequential(
150146
# Layer 1: Convolutional layer with 6 filters of size 5x5
151-
nn.Conv2d(1, 6, kernel_size=5, padding=2),
152-
nn.ReLU(),
147+
nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.ReLU(),
153148
nn.MaxPool2d(kernel_size=2, stride=2), # Subsampling (max pooling)
154149
# Layer 2: Convolutional layer with 16 filters of size 5x5
155-
nn.Conv2d(6, 16, kernel_size=5),
156-
nn.ReLU(),
150+
nn.Conv2d(6, 16, kernel_size=5), nn.ReLU(),
157151
nn.MaxPool2d(kernel_size=2, stride=2), # Subsampling (max pooling)
158152
nn.Flatten(),
159153
# Fully connected layers
160-
nn.Linear(16 * 5 * 5, 120), # Flattened output from previous layer
161-
nn.ReLU(),
162-
nn.Linear(120, 84),
163-
nn.ReLU(),
154+
nn.Linear(16 * 5 * 5, 120), nn.ReLU(), # Flattened output from previous layer
155+
nn.Linear(120, 84), nn.ReLU(),
164156
nn.Linear(84, 10) # Output layer with 10 classes
165157
)
166158

prompts/LAZY.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Q: pytorchh - what is nn.LazyLinear and nn.LazyConv2D?
2+
3+
4+
A: In PyTorch, `nn.LazyLinear` and `nn.LazyConv2d` are layers designed to provide **lazy initialization** of parameters. These layers are part of the `torch.nn` module and are useful when you don't want to specify the exact dimensions of the input at the time of model construction. Instead, the dimensions are inferred dynamically during the first forward pass.
5+
6+
### 1. `nn.LazyLinear`
7+
`nn.LazyLinear` is a variant of `nn.Linear` where the input size is not explicitly specified during the layer's creation. Instead, it will automatically infer the input size the first time the layer is used in a forward pass.
8+
9+
#### Usage:
10+
- **Lazy Initialization**: You don’t need to know the input size of the layer in advance.
11+
- The first time the layer receives an input, it will automatically compute the input size and initialize the weight and bias accordingly.
12+
13+
#### Example:
14+
```python
15+
import torch
16+
import torch.nn as nn
17+
18+
# Define a model with LazyLinear layer
19+
model = nn.Sequential(
20+
nn.LazyLinear(10), # Lazy Linear layer, output size = 10
21+
)
22+
23+
# Example input tensor (e.g., batch_size=5, input_features=20)
24+
x = torch.randn(5, 20) # (batch_size, input_features)
25+
output = model(x)
26+
27+
print(output.shape) # Will print: torch.Size([5, 10])
28+
```
29+
30+
In this case, the `nn.LazyLinear` layer does not require you to specify the input features in the constructor. Instead, when the model is first run with the input `x`, it infers that the input has `20` features (from the shape of `x`), and automatically initializes the weights accordingly.
31+
32+
### 2. `nn.LazyConv2d`
33+
`nn.LazyConv2d` is a similar variant of the convolutional layer (`nn.Conv2d`), but again, without the need to specify the number of input channels or kernel size during the initialization. Like `LazyLinear`, the input shape (number of input channels and spatial dimensions) is inferred dynamically when the model first performs a forward pass.
34+
35+
#### Example:
36+
```python
37+
import torch
38+
import torch.nn as nn
39+
40+
# Define a model with LazyConv2d layer
41+
model = nn.Sequential(
42+
nn.LazyConv2d(16, kernel_size=3), # Lazy Conv2d, output channels = 16, kernel size = 3
43+
)
44+
45+
# Example input tensor (e.g., batch_size=5, channels=3, height=28, width=28)
46+
x = torch.randn(5, 3, 28, 28) # (batch_size, input_channels, height, width)
47+
output = model(x)
48+
49+
print(output.shape) # Will print: torch.Size([5, 16, 26, 26])
50+
```
51+
52+
In this example, the `nn.LazyConv2d` layer does not require the `in_channels` to be specified. It will automatically infer that the input has `3` channels (based on the input `x` shape), and initialize the weights accordingly.
53+
54+
### Key Differences Between Regular and Lazy Layers:
55+
56+
- **Regular Layers (`nn.Linear`, `nn.Conv2d`)**: When using these layers, you need to specify the input size when defining the layer. For example, `nn.Linear(in_features, out_features)` or `nn.Conv2d(in_channels, out_channels, kernel_size)`.
57+
58+
- **Lazy Layers (`nn.LazyLinear`, `nn.LazyConv2d`)**: These layers allow you to define the output size of the layer (e.g., `out_features` or `out_channels`), but the input size is inferred automatically from the first forward pass. This can be useful when you don't know the input shape ahead of time or for more flexible model definitions.
59+
60+
### Use Cases for Lazy Layers:
61+
- **Flexible architectures**: Lazy layers are helpful when you're designing a model where the input shape may vary or isn't known at the time of defining the architecture.
62+
- **Preliminary models**: If you're prototyping a model and don’t have a fixed dataset size, lazy layers let you experiment without worrying about the exact input dimensions.
63+
64+
### Summary:
65+
- `nn.LazyLinear`: A version of `nn.Linear` where the input size is inferred during the first forward pass.
66+
- `nn.LazyConv2d`: A version of `nn.Conv2d` where the input size is inferred during the first forward pass.
67+
68+
Both layers allow you to build more flexible and adaptable models without having to specify the input size explicitly.
69+

0 commit comments

Comments
 (0)