Skip to content

Commit bfebc17

Browse files
authored
Create layers.py
1 parent 154530d commit bfebc17

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed

model/layers.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import numpy as np
2+
3+
class Convolution2D:
4+
def __init__(self, inputs_channel, num_filters, kernel_size, padding, stride, learning_rate, name):
5+
self.F = num_filters
6+
self.K = kernel_size
7+
self.C = inputs_channel
8+
self.weights = np.zeros((self.F, self.C, self.K, self.K))
9+
self.bias = np.zeros((self.F, 1))
10+
for i in range(0,self.F):
11+
self.weights[i,:,:,:] = np.random.normal(loc=0, scale=np.sqrt(1./(self.C*self.K*self.K)), size=(self.C, self.K, self.K))
12+
13+
self.p = padding
14+
self.s = stride
15+
self.lr = learning_rate
16+
self.name = name
17+
18+
def zero_padding(self, inputs, size):
19+
w, h = inputs.shape[0], inputs.shape[1]
20+
new_w = 2 * size + w
21+
new_h = 2 * size + h
22+
out = np.zeros((new_w, new_h))
23+
out[size:w+size, size:h+size] = inputs
24+
return out
25+
26+
def forward(self, inputs):
27+
C = inputs.shape[0]
28+
W = inputs.shape[1]+2*self.p
29+
H = inputs.shape[2]+2*self.p
30+
self.inputs = np.zeros((C, W, H))
31+
for c in range(inputs.shape[0]):
32+
self.inputs[c,:,:] = self.zero_padding(inputs[c,:,:], self.p)
33+
WW = (W - self.K)/self.s + 1
34+
HH = (H - self.K)/self.s + 1
35+
feature_maps = np.zeros((self.F, WW, HH))
36+
for f in range(self.F):
37+
for w in range(WW):
38+
for h in range(HH):
39+
feature_maps[f,w,h]=np.sum(self.inputs[:,w:w+self.K,h:h+self.K]*self.weights[f,:,:,:])+self.bias[f]
40+
41+
return feature_maps
42+
43+
def backward(self, dy):
44+
C, W, H = self.inputs.shape
45+
dx = np.zeros(self.inputs.shape)
46+
dw = np.zeros(self.weights.shape)
47+
db = np.zeros(self.bias.shape)
48+
F, W, H = dy.shape
49+
for f in range(F):
50+
for w in range(W):
51+
for h in range(H):
52+
dw[f,:,:,:]+=dy[f,w,h]*self.inputs[:,w:w+self.K,h:h+self.K]
53+
dx[:,w:w+self.K,h:h+self.K]+=dy[f,w,h]*self.weights[f,:,:,:]
54+
for f in range(F):
55+
db[f] = np.sum(dy[f, :, :])
56+
self.weights -= self.lr * dw
57+
self.bias -= self.lr * db
58+
return dx
59+
60+
def extract(self):
61+
return {self.name+'.weights':self.weights, self.name+'.bias':self.bias}
62+
63+
def feed(self, weights, bias):
64+
self.weights = weights
65+
self.bias = bias
66+
67+
class Maxpooling2D:
68+
def __init__(self, pool_size, stride, name):
69+
self.pool = pool_size
70+
self.s = stride
71+
self.name = name
72+
73+
def forward(self, inputs):
74+
self.inputs = inputs
75+
C, W, H = inputs.shape
76+
new_width = (W - self.pool)/self.s + 1
77+
new_height = (H - self.pool)/self.s + 1
78+
out = np.zeros((C, new_width, new_height))
79+
for c in range(C):
80+
for w in range(W/self.s):
81+
for h in range(H/self.s):
82+
out[c, w, h] = np.max(self.inputs[c, w*self.s:w*self.s+self.pool, h*self.s:h*self.s+self.pool])
83+
return out
84+
85+
def backward(self, dy):
86+
C, W, H = self.inputs.shape
87+
dx = np.zeros(self.inputs.shape)
88+
for c in range(C):
89+
for w in range(0, W, self.pool):
90+
for h in range(0, H, self.pool):
91+
st = np.argmax(self.inputs[c,w:w+self.pool,h:h+self.pool])
92+
(idx, idy) = np.unravel_index(st, (self.pool, self.pool))
93+
dx[c, w+idx, h+idy] = dy[c, w/self.pool, h/self.pool]
94+
return dx
95+
96+
def extract(self):
97+
return
98+
99+
class FullyConnected:
100+
def __init__(self, num_inputs, num_outputs, learning_rate, name):
101+
self.weights = 0.01*np.random.rand(num_inputs, num_outputs)
102+
self.bias = np.zeros((num_outputs, 1))
103+
self.lr = learning_rate
104+
self.name = name
105+
106+
def forward(self, inputs):
107+
self.inputs = inputs
108+
return np.dot(self.inputs, self.weights) + self.bias.T
109+
110+
def backward(self, dy):
111+
if dy.shape[0] == self.inputs.shape[0]:
112+
dy = dy.T
113+
dw = dy.dot(self.inputs)
114+
db = np.sum(dy, axis=1, keepdims=True)
115+
dx = np.dot(dy.T, self.weights.T)
116+
self.weights -= self.lr * dw.T
117+
self.bias -= self.lr * db
118+
return dx
119+
120+
def extract(self):
121+
return {self.name+'.weights':self.weights, self.name+'.bias':self.bias}
122+
123+
def feed(self, weights, bias):
124+
self.weights = weights
125+
self.bias = bias
126+
127+
class Flatten:
128+
def __init__(self):
129+
pass
130+
131+
def forward(self, inputs):
132+
self.C, self.W, self.H = inputs.shape
133+
return inputs.reshape(1, self.C*self.W*self.H)
134+
135+
def backward(self, dy):
136+
return dy.reshape(self.C, self.W, self.H)
137+
138+
def extract(self):
139+
return
140+
141+
class ReLu:
142+
def __init__(self):
143+
pass
144+
145+
def forward(self, inputs):
146+
self.inputs = inputs
147+
ret = inputs.copy()
148+
ret[ret < 0] = 0
149+
return ret
150+
151+
def backward(self, dy):
152+
dx = dy.copy()
153+
dx[self.inputs < 0] = 0
154+
return dx
155+
156+
def extract(self):
157+
return
158+
159+
class Softmax:
160+
def __init__(self):
161+
pass
162+
163+
def forward(self, inputs):
164+
exp = np.exp(inputs, dtype=np.float)
165+
self.out = exp/np.sum(exp)
166+
return self.out
167+
168+
def backward(self, dy):
169+
return self.out.T - dy.reshape(dy.shape[0],1)
170+
171+
def extract(self):
172+
return
173+

0 commit comments

Comments
 (0)