-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_grad.py
104 lines (87 loc) · 4.05 KB
/
test_grad.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import torch
import NeuralNetwork
def try_gpu(i=0): #@save
"""Return gpu(i) if exists, otherwise return cpu().
https://d2l.ai/chapter_deep-learning-computation/use-gpu.html
"""
if torch.cuda.device_count() >= i + 1:
return torch.device(f'cuda:{i}')
return torch.device('cpu')
DEVICE=try_gpu()
DTYPE = torch.float64
def test_one_layer_grad(verbose = False):
x = torch.tensor([[1], [3], [2]], device=DEVICE, dtype=DTYPE)
w1 = torch.tensor([[-1, 1, .5], [-1, 1, -1], [-2, 2, 1]], device=DEVICE, dtype=DTYPE)
b1 = torch.tensor([[-2], [0], [-5.5]], device=DEVICE, dtype=DTYPE)
actual = torch.tensor([[-4], [12], [1]], device=DEVICE, dtype=DTYPE)
nntest = NeuralNetwork.Network(3, 3, DEVICE)
lin1 = nntest.add_linear(w1, b1)
out = nntest.forward(x, actual)
nntest.backward()
x_b = torch.tensor([[1], [3], [2]], device=DEVICE, dtype=DTYPE)
w1_b = torch.tensor([[-1, 1, .5], [-1, 1, -1], [-2, 2, 1]], device=DEVICE, dtype=DTYPE, requires_grad=True)
b1_b = torch.tensor([[-2], [0], [-5.5]], device=DEVICE, dtype=DTYPE, requires_grad=True)
actual_b = torch.tensor([[-4], [12], [1]], device=DEVICE, dtype=DTYPE)
l2_b = (((torch.matmul(w1_b, x_b) + b1_b) - actual_b) ** 2)
l2_b.retain_grad()
loss_b = l2_b.sum()
#print(loss_b)
loss_b.backward()
#print(l2_b.grad)
if verbose:
print("Grad from network:")
print("Weight:", lin1.W.gradient)
print("Bias:", lin1.b.gradient)
print("Grad from backwrd():")
print("Weight:", w1_b.grad)
print("Bias:", b1_b.grad)
assert torch.all(lin1.W.gradient == w1_b.grad), "Not expected gradient"
assert torch.all(lin1.b.gradient == b1_b.grad), "Not expected gradient"
assert loss_b ==nntest.loss, "Not expected gradient"
def test_backward_doesnt_work():
x = torch.tensor([[1], [3], [2]], device=DEVICE, dtype=DTYPE)
w1 = torch.tensor([[-1, 1, .5], [-1, 1, -1], [-2, 2, 1]], device=DEVICE, dtype=DTYPE)
b1 = torch.tensor([[-2], [0], [-5.5]], device=DEVICE, dtype=DTYPE)
actual = torch.tensor([[-4], [12], [1]], device=DEVICE, dtype=DTYPE)
nntest = NeuralNetwork.Network(3, 3, DEVICE)
lin1 = nntest.add_linear(w1, b1)
assert nntest.backward() is False
out = nntest.forward(x, actual)
assert nntest.backward() is True
assert nntest.backward() is False
nntest.inference(x)
assert nntest.backward() is False
def test_one_layer_grad_with_reg(verbose = False):
reg_fact = 0.1
x = torch.tensor([[1], [3], [2]], device=DEVICE, dtype=DTYPE)
w1 = torch.tensor([[-1, 1, .5], [-1, 1, -1], [-2, 2, 1]], device=DEVICE, dtype=DTYPE)
b1 = torch.tensor([[-2], [0], [-5.5]], device=DEVICE, dtype=DTYPE)
actual = torch.tensor([[-4], [12], [1]], device=DEVICE, dtype=DTYPE)
# NO EFFECT from regularization
nntest = NeuralNetwork.Network(3, 3, DEVICE, regularization_factor=reg_fact)
lin1 = nntest.add_linear(w1, b1, regularization=True)
out = nntest.forward(x, actual)
nntest.backward()
x_b = torch.tensor([[1], [3], [2]], device=DEVICE, dtype=DTYPE)
w1_b = torch.tensor([[-1, 1, .5], [-1, 1, -1], [-2, 2, 1]], device=DEVICE, dtype=DTYPE, requires_grad=True)
b1_b = torch.tensor([[-2], [0], [-5.5]], device=DEVICE, dtype=DTYPE, requires_grad=True)
actual_b = torch.tensor([[-4], [12], [1]], device=DEVICE, dtype=DTYPE)
l2_b = (((torch.matmul(w1_b, x_b) + b1_b) - actual_b) ** 2)
loss_b = l2_b.sum()
reg = (reg_fact * ((w1_b ** 2).sum()))
n = loss_b + reg
n.backward()
if verbose:
print("Grad from network:")
print("Weight:", lin1.W.gradient)
print("Bias:", lin1.b.gradient)
print("Grad from backwrd():")
print("Weight:", w1_b.grad)
print("Bias:", b1_b.grad)
assert torch.all(lin1.W.gradient == w1_b.grad), "Not expected gradient"
assert torch.all(lin1.b.gradient == b1_b.grad), "Not expected gradient"
assert loss_b == nntest.loss, "Not expected gradient"
if __name__ == '__main__':
test_backward_doesnt_work()
test_one_layer_grad()
test_one_layer_grad_with_reg()