-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample.py
148 lines (125 loc) · 4.96 KB
/
example.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import torch
import logging
import copy
from torch.nn import functional as F
from gradients.gradients import Gradient
log = logging.getLogger(__name__)
torch.set_default_dtype(torch.float64)
torch.manual_seed(0)
class Model(torch.nn.Module):
def __init__(self,D_in, D_out):
super(Model,self).__init__()
# Create random Tensors for weights.
self.w1 = torch.nn.Parameter(torch.randn(D_in, D_out),
requires_grad=True)
# self.relu = torch.nn.ReLU()
self.sig = torch.nn.Sigmoid()
def forward(self,x):
# Forward pass: compute predicted y using operations; we compute
# ReLU using our custom autograd operation.
y_pred = self.sig(x.mm(self.w1))
return y_pred
class MyReLU(torch.autograd.Function):
"""
We can implement our own custom autograd Functions by subclassing
torch.autograd.Function and implementing the forward and backward passes
which operate on Tensors.
"""
@staticmethod
def forward(ctx, input):
"""
In the forward pass we receive a Tensor containing the input and return
a Tensor containing the output. ctx is a context object that can be used
to stash information for backward computation. You can cache arbitrary
objects for use in the backward pass using the ctx.save_for_backward method.
"""
ctx.save_for_backward(input)
return input.clamp(min=0)
@staticmethod
def backward(ctx, grad_output):
"""
In the backward pass we receive a Tensor containing the gradient of the loss
with respect to the output, and we need to compute the gradient of the loss
with respect to the input.
"""
input, = ctx.saved_tensors
grad_input = grad_output.clone()
grad_input[input < 0] = 0.
return grad_input
# To apply our Function, we use Function.apply method. We alias this as 'relu'.
myrelu = MyReLU.apply
class MySigmoid(torch.autograd.Function):
"""
We can implement our own custom autograd Functions by subclassing
torch.autograd.Function and implementing the forward and backward passes
which operate on Tensors.
"""
@staticmethod
def forward(ctx, input):
"""
In the forward pass we receive a Tensor containing the input and return
a Tensor containing the output. ctx is a context object that can be used
to stash information for backward computation. You can cache arbitrary
objects for use in the backward pass using the ctx.save_for_backward method.
"""
output = 1/(1+torch.exp(-input))
ctx.save_for_backward(output)
return output
@staticmethod
def backward(ctx, grad_output):
"""
In the backward pass we receive a Tensor containing the gradient of the loss
with respect to the output, and we need to compute the gradient of the loss
with respect to the input.
"""
input, = ctx.saved_tensors
return grad_output*input*(1-input)
# To apply our Function, we use Function.apply method. We alias this as 'relu'.
mysigmoid = MySigmoid.apply
# Activation function with learnable parameter
class LearnedSwish(torch.nn.Module):
"""This function use the pytorch autograd to compute gradient"""
def __init__(self, slope = 1):
super().__init__()
self.slope = slope * torch.nn.Parameter(torch.ones(1))
def forward(self, x):
return self.slope * x * torch.sigmoid(x)
# Reference: http://pytorch.org/docs/master/_modules/torch/optim/sgd.html#SGD
class SGD(torch.optim.Optimizer):
def __init__(self, params, lr=1e-3):
defaults = dict(lr=lr)
super(SGD,self).__init__(params,defaults)
def __setstate__(self, state):
super(SGD, self).__setstate__(state)
def step(self, closure=None):
loss = None
if closure is not None:
loss = closure()
for group in self.param_groups:
for p in group['params']:
if p.grad is None:
continue
d_p = p.grad.data
p.data.add_(-group['lr'], d_p)
return loss
class MSELoss(torch.autograd.Function):
@staticmethod
def forward(ctx, y_pred, y):
ctx.save_for_backward(y_pred, y)
return ((y_pred-y)**2).sum()/y_pred.shape[0]
@staticmethod
def backward(ctx, grad_output):
y_pred, y = ctx.saved_tensors
grad_input = 2 * (y_pred-y)/y_pred.shape[0]
return grad_input, None
mycriterion = MSELoss.apply
class MyModel(torch.nn.Module):
def __init__(self,D_in, D_out):
super(MyModel,self).__init__()
# Create random Tensors for weights.
self.w1 = torch.nn.Parameter(torch.randn(D_in, D_out), requires_grad=True)
def forward(self,x):
# Forward pass: compute predicted y using operations; we compute
# ReLU using our custom autograd operation.
y_pred = mysigmoid(x.mm(self.w1))
return y_pred