Diego Carpintero commited on
Commit
bd42f73
1 Parent(s): ad9ba7d
Files changed (2) hide show
  1. model.py +152 -0
  2. model/fashion.mnist.base.pt +3 -0
model.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+
4
+ device = "cuda:0" if torch.cuda.is_available() else "cpu"
5
+
6
+
7
+ class Linear(nn.Module):
8
+ def __init__(self, in_features: int, out_features: int, std: float = 0.1):
9
+ """
10
+ Initialize the linear layer with random values for weights.
11
+
12
+ The weights and biases are registered as parameters, allowing for
13
+ gradient computation and update during backpropagation.
14
+ """
15
+ super(Linear, self).__init__()
16
+ self.in_features = in_features
17
+ self.out_features = out_features
18
+
19
+ weight = torch.randn(in_features, out_features, requires_grad=True) * std
20
+ bias = torch.zeros(out_features, requires_grad=True) * std
21
+
22
+ self.weight = nn.Parameter(weight)
23
+ self.bias = nn.Parameter(bias)
24
+
25
+ self.to(device=device)
26
+
27
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
28
+ """
29
+ Perform linear transformation by multiplying the input tensor
30
+ with the weight matrix, and adding the bias.
31
+ """
32
+ return x @ self.weight + self.bias
33
+
34
+ def __repr__(self) -> str:
35
+ return f"in_features={self.in_features}, out_features={self.out_features}, bias={self.bias is not None}"
36
+
37
+
38
+ class ReLU(nn.Module):
39
+ """
40
+ Rectified Linear Unit (ReLU) activation function.
41
+ """
42
+
43
+ @staticmethod
44
+ def forward(x: torch.Tensor) -> torch.Tensor:
45
+ return torch.max(x, torch.zeros_like(x))
46
+
47
+
48
+ class Sequential(nn.Module):
49
+ """
50
+ Sequential container for stacking multiple modules,
51
+ passing the output of one module as input to the next.
52
+ """
53
+
54
+ def __init__(self, *layers):
55
+ """
56
+ Initialize the Sequential container with a list of layers.
57
+ """
58
+ super(Sequential, self).__init__()
59
+ self.layers = nn.ModuleList(layers)
60
+
61
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
62
+ for layer in self.layers:
63
+ x = layer(x)
64
+ return x
65
+
66
+ def __repr__(self) -> str:
67
+ layer_str = "\n".join(
68
+ [f" ({i}): {layer}" for i, layer in enumerate(self.layers)]
69
+ )
70
+ return f"{self.__class__.__name__}(\n{layer_str}\n)"
71
+
72
+
73
+ class Flatten(nn.Module):
74
+ """
75
+ Reshape the input tensor by flattening all dimensions except the first dimension.
76
+ """
77
+
78
+ @staticmethod
79
+ def forward(x: torch.Tensor) -> torch.Tensor:
80
+ """
81
+ Note that x.view(x.size(0), -1) reshapes the x tensor to (x.size(0), N)
82
+ where N is the product of the remaining dimensions.
83
+
84
+ E.g. (batch_size, 28, 28) -> (batch_size, 784)
85
+ """
86
+ return x.view(x.size(0), -1)
87
+
88
+
89
+ class Dropout(nn.Module):
90
+ """
91
+ Dropout layer for regularization by randomly setting input elements to zero
92
+ with probability p during training.
93
+ """
94
+
95
+ def __init__(self, p=0.2):
96
+ super(Dropout, self).__init__()
97
+ self.p = p
98
+
99
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
100
+ if self.training:
101
+ mask = (torch.rand(x.shape) > self.p).float().to(x) / (1 - self.p)
102
+ return x * mask
103
+ return x
104
+
105
+
106
+ class Classifier(nn.Module):
107
+ """
108
+ Classifier model consisting of a sequence of linear layers and ReLU activations,
109
+ followed by a final linear layer that outputs logits (unnormalized scores)
110
+ for each of the 10 garment classes.
111
+ """
112
+
113
+ def __init__(self):
114
+ """
115
+ The output logits of the last layer can be passed directly to
116
+ a loss function like CrossEntropyLoss, which will apply the
117
+ softmax function internally to calculate a probability distribution.
118
+ """
119
+ super(Classifier, self).__init__()
120
+ self.labels = [
121
+ "T-shirt/Top",
122
+ "Trouser/Jeans",
123
+ "Pullover",
124
+ "Dress",
125
+ "Coat",
126
+ "Sandal",
127
+ "Shirt",
128
+ "Sneaker",
129
+ "Bag",
130
+ "Ankle-Boot",
131
+ ]
132
+
133
+ self.main = Sequential(
134
+ Flatten(),
135
+ Linear(in_features=784, out_features=256),
136
+ ReLU(),
137
+ Dropout(0.2),
138
+ Linear(in_features=256, out_features=64),
139
+ ReLU(),
140
+ Dropout(0.2),
141
+ Linear(in_features=64, out_features=10),
142
+ )
143
+
144
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
145
+ return self.main(x)
146
+
147
+ def predictions(self, x):
148
+ with torch.no_grad():
149
+ logits = self.forward(x)
150
+ probs = torch.nn.functional.softmax(logits, dim=1)
151
+ predictions = dict(zip(self.labels, probs.cpu().detach().numpy().flatten()))
152
+ return predictions
model/fashion.mnist.base.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6d1ff059b2004f587490496d2588801dc6a2ab6dc9374ecdf99e4e07df3320b3
3
+ size 875991