maxsn2200 commited on
Commit
21532d1
·
verified ·
1 Parent(s): d3d6b31

Upload 5 files

Browse files
Files changed (5) hide show
  1. activations.py +46 -0
  2. app.py +0 -0
  3. layers.py +139 -0
  4. model_weights.npz +3 -0
  5. requirements.txt +2 -0
activations.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import math
3
+
4
+
5
+ class ReLU:
6
+ def __init__(self):
7
+ self.mask = None
8
+
9
+ def forward(self, x):
10
+ self.mask = (x > 0)
11
+ return x * self.mask
12
+
13
+ def backward(self, grad):
14
+ return grad * self.mask
15
+
16
+
17
+ class GELU:
18
+ def __init__(self, approximate='none'):
19
+ self.approximate = approximate
20
+ self.x = None
21
+
22
+ def forward(self, x):
23
+ self.x = x
24
+ if self.approximate == 'tanh':
25
+ inner = np.sqrt(2 / np.pi) * (x + 0.044715 * np.power(x, 3))
26
+ return 0.5 * x * (1 + np.tanh(inner))
27
+ else:
28
+ erf_vec = np.vectorize(math.erf)
29
+ return 0.5 * x * (1 + erf_vec(x / np.sqrt(2)))
30
+
31
+ def backward(self, grad):
32
+ x = self.x
33
+ if self.approximate == 'tanh':
34
+ c = np.sqrt(2 / np.pi)
35
+ inner = c * (x + 0.044715 * np.power(x, 3))
36
+ tanh_inner = np.tanh(inner)
37
+ d_inner = c * (1.0 + 3.0 * 0.044715 * np.square(x))
38
+ dx = 0.5 * (1.0 + tanh_inner) + 0.5 * x * (1.0 - np.square(tanh_inner)) * d_inner
39
+ return grad * dx
40
+ else:
41
+ erf_vec = np.vectorize(math.erf)
42
+ cdf = 0.5 * (1.0 + erf_vec(x / np.sqrt(2)))
43
+ pdf = (1.0 / np.sqrt(2.0 * np.pi)) * np.exp(-0.5 * np.square(x))
44
+ dx = cdf + x * pdf
45
+ return grad * dx
46
+
app.py ADDED
File without changes
layers.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+
4
+ class Dense:
5
+ def __init__(self, input_size, output_size):
6
+ # small weights no gradient explosion
7
+ self.weights = np.random.randn(input_size, output_size) * 0.01
8
+ self.biases = np.zeros((1, output_size))
9
+ self.dweights = None
10
+ self.dbiases = None
11
+
12
+ def forward(self, input_data):
13
+ self.input = input_data # falttened 1D vector
14
+ return np.dot(self.input, self.weights) + self.biases
15
+
16
+ def backward(self, output_gradient, learning_rate=None):
17
+ # calculating gradient
18
+ self.dweights = self.input.T @ output_gradient # @ is matrix product
19
+ self.dbiases = np.sum(output_gradient, axis=0, keepdims=True)
20
+ input_gradient = output_gradient @ self.weights.T
21
+
22
+ # updating parameters if learning_rate is provided
23
+ if learning_rate is not None:
24
+ self.weights -= learning_rate * self.dweights
25
+ self.biases -= learning_rate * self.dbiases
26
+
27
+ return input_gradient
28
+
29
+
30
+ class Conv:
31
+ def __init__(self, input_shape, kernel_size, num_kernels):
32
+ input_depth, input_height, input_width = input_shape
33
+
34
+ self.input_shape = input_shape
35
+ self.input_depth = input_depth
36
+ self.num_kernels = num_kernels
37
+
38
+ # output shape depends on num kernels
39
+ # ie. num kernels = num of output feature maps
40
+ # no input_depth in output shape because each kernel process all input channels
41
+ self.output_shape = (
42
+ num_kernels,
43
+ input_height - kernel_size + 1,
44
+ input_width - kernel_size + 1,
45
+ )
46
+
47
+ self.kernel_shape = (
48
+ num_kernels,
49
+ input_depth, # color channels
50
+ kernel_size, # k_height
51
+ kernel_size, # k_width
52
+ )
53
+ self.kernels = np.random.randn(*self.kernel_shape) * 0.1
54
+ self.biases = np.zeros((num_kernels, 1, 1))
55
+ self.dkernels = None
56
+ self.dbiases = None
57
+
58
+ def forward(self, input_data):
59
+ self.input = input_data
60
+ from numpy.lib.stride_tricks import sliding_window_view
61
+ patches = sliding_window_view(input_data, (self.kernel_shape[2], self.kernel_shape[3]), axis=(1, 2))
62
+ self.output = np.einsum('jyxkl,ijkl->iyx', patches, self.kernels) + self.biases
63
+ return self.output
64
+
65
+ def backward(self, output_gradient, learning_rate=None):
66
+ from numpy.lib.stride_tricks import sliding_window_view
67
+ patches = sliding_window_view(self.input, (self.kernel_shape[2], self.kernel_shape[3]), axis=(1, 2))
68
+
69
+ self.dkernels = np.einsum('iyx,jyxkl->ijkl', output_gradient, patches)
70
+ self.dbiases = np.sum(output_gradient, axis=(1, 2), keepdims=True)
71
+
72
+ input_gradient = np.zeros(self.input_shape)
73
+ for y in range(self.output_shape[1]):
74
+ for x in range(self.output_shape[2]):
75
+ input_gradient[:, y : y + self.kernel_shape[2], x : x + self.kernel_shape[3]] += np.tensordot(
76
+ output_gradient[:, y, x], self.kernels, axes=(0, 0)
77
+ )
78
+
79
+ if learning_rate is not None:
80
+ self.kernels -= learning_rate * self.dkernels
81
+ self.biases -= learning_rate * self.dbiases
82
+
83
+ return input_gradient
84
+
85
+
86
+ class MaxPool:
87
+ def __init__(self, pool_size=2, stride=2):
88
+ self.pool_size = pool_size
89
+ self.stride = stride
90
+
91
+ def forward(self, input_data):
92
+ self.input = input_data
93
+
94
+ depth, height, width = input_data.shape
95
+
96
+ out_height = (height - self.pool_size) // self.stride + 1
97
+ out_width = (width - self.pool_size) // self.stride + 1
98
+
99
+ self.output_shape = (depth, out_height, out_width)
100
+
101
+ from numpy.lib.stride_tricks import sliding_window_view
102
+ patches = sliding_window_view(input_data, (self.pool_size, self.pool_size), axis=(1, 2))
103
+ patches = patches[:, ::self.stride, ::self.stride]
104
+
105
+ return np.max(patches, axis=(3, 4))
106
+
107
+ def backward(self, output_gradient):
108
+ input_gradient = np.zeros_like(self.input)
109
+
110
+ depth, out_height, out_width = self.output_shape
111
+
112
+ for row in range(out_height):
113
+ for col in range(out_width):
114
+ start_y = row * self.stride
115
+ start_x = col * self.stride
116
+
117
+ patch = self.input[:, start_y : start_y + self.pool_size, start_x : start_x + self.pool_size]
118
+ max_val = np.max(patch, axis=(1, 2), keepdims=True)
119
+ mask = (patch == max_val)
120
+
121
+ input_gradient[:, start_y : start_y + self.pool_size, start_x : start_x + self.pool_size] += (
122
+ output_gradient[:, row, col][:, np.newaxis, np.newaxis] * mask
123
+ )
124
+
125
+ return input_gradient
126
+
127
+
128
+ class Flatten:
129
+ def __init__(self):
130
+ self.input_shape = None
131
+ self.batch_size = 0
132
+
133
+ def forward(self, x):
134
+ self.input_shape = x.shape
135
+ self.batch_size = x.shape[0]
136
+ return x.reshape(self.batch_size, -1)
137
+
138
+ def backward(self, grad_input):
139
+ return grad_input.reshape(self.input_shape)
model_weights.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9b53ca1c9c6958b961c854da485d3b925f89c071b31c6ae10defdf18ed4c2da9
3
+ size 135812
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ numpy>=2.0.0
2
+ pillow>=10.0.0