-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathactivation.py
85 lines (64 loc) · 2.42 KB
/
activation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import numpy as np
from dlf.base import Module
class ReLU(Module):
def forward(self, input):
self.output = np.maximum(input, 0)
return self.output
def backward(self, input, grad_output):
grad_input = np.multiply(grad_output, input > 0)
return grad_input
class LeakyReLU(Module):
def __init__(self, slope=0.01):
super().__init__()
self.slope = slope
def forward(self, input):
self.output = (input > 0)*input + (input <= 0)*self.slope*input
return self.output
def backward(self, input, grad_output):
grad_input = np.multiply(grad_output, (input > 0) + (input <= 0)*self.slope)
return grad_input
class Sigmoid(Module):
def forward(self, input):
self.output = self.__class__._sigmoid(input)
return self.output
def backward(self, input, grad_output):
sigma = self.output
grad_input = np.multiply(grad_output, sigma*(1 - sigma))
return grad_input
@staticmethod
def _sigmoid(x):
return 1/(1 + np.exp(-x))
class Tanh(Module):
def forward(self, input):
self.output = np.tanh(input)
return self.output
def backward(self, input, grad_output):
th = self.output
grad_input = np.multiply(grad_output, (1 - th*th))
return grad_input
class Softmax(Module):
def forward(self, input):
self.output = self.softmax = self._softmax(input)
return self.output
def backward(self, input, grad_output):
p = self.softmax
grad_input = p * ( grad_output - (grad_output * p).sum(axis=1)[:, None] )
return grad_input
def _softmax(self, x):
x = np.subtract(x, x.max(axis=1, keepdims=True))
e_m = np.exp(x)
sum_e = np.repeat(np.sum(e_m, axis=1), x.shape[-1]).reshape(*e_m.shape)
return e_m/sum_e
class LogSoftmax(Softmax):
def forward(self, input):
# чтобы нигде не было взятий логарифма от нуля:
eps = 1e-9
self.softmax = self._softmax(input)
softmax_clamp = np.clip(self.softmax, eps, 1 - eps)
self.output = np.log(softmax_clamp)
return self.output
def backward(self, input, grad_output):
eps = 1e-9
softmax_clamp = np.clip(self.softmax, eps, 1 - eps)
grad_input = super().backward(input, grad_output * 1/softmax_clamp)
return grad_input