-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
parameters.py
91 lines (73 loc) · 2.77 KB
/
parameters.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
# coding:utf-8
import numpy as np
from mla.neuralnet.initializations import get_initializer
class Parameters(object):
def __init__(self, init="glorot_uniform", scale=0.5, bias=1.0, regularizers=None, constraints=None):
"""A container for layer's parameters.
Parameters
----------
init : str, default 'glorot_uniform'.
The name of the weight initialization function.
scale : float, default 0.5
bias : float, default 1.0
Initial values for bias.
regularizers : dict
Weight regularizers.
>>> {'W' : L2()}
constraints : dict
Weight constraints.
>>> {'b' : MaxNorm()}
"""
if constraints is None:
self.constraints = {}
else:
self.constraints = constraints
if regularizers is None:
self.regularizers = {}
else:
self.regularizers = regularizers
self.initial_bias = bias
self.scale = scale
self.init = get_initializer(init)
self._params = {}
self._grads = {}
def setup_weights(self, W_shape, b_shape=None):
if "W" not in self._params:
self._params["W"] = self.init(shape=W_shape, scale=self.scale)
if b_shape is None:
self._params["b"] = np.full(W_shape[1], self.initial_bias)
else:
self._params["b"] = np.full(b_shape, self.initial_bias)
self.init_grad()
def init_grad(self):
"""Init gradient arrays corresponding to each weight array."""
for key in self._params.keys():
if key not in self._grads:
self._grads[key] = np.zeros_like(self._params[key])
def step(self, name, step):
"""Increase specific weight by amount of the step parameter."""
self._params[name] += step
if name in self.constraints:
self._params[name] = self.constraints[name].clip(self._params[name])
def update_grad(self, name, value):
"""Update gradient values."""
self._grads[name] = value
if name in self.regularizers:
self._grads[name] += self.regularizers[name](self._params[name])
@property
def n_params(self):
"""Count the number of parameters in this layer."""
return sum([np.prod(self._params[x].shape) for x in self._params.keys()])
def keys(self):
return self._params.keys()
@property
def grad(self):
return self._grads
# Allow access to the fields using dict syntax, e.g. parameters['W']
def __getitem__(self, item):
if item in self._params:
return self._params[item]
else:
raise ValueError
def __setitem__(self, key, value):
self._params[key] = value