-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmodel_tf.py
152 lines (115 loc) · 5.2 KB
/
model_tf.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
148
149
150
151
152
import numpy as np
import tensorflow as tf
from tqdm import *
from sklearn.model_selection import KFold
import logging
class LinearModel(object):
def __init__(self, shape, optimizer='seq', lr=0.01, clip_min=0, clip_max=1081, is_round=True):
'''
param shape: phi_x shape
'''
self.optimizer = optimizer
self.lr = lr
self.shape = shape
# x is NxM matrix
self.x = tf.placeholder(tf.float32, shape=(None,) + shape)
# t is Nx1 column vector
self.t = tf.placeholder(tf.float32, shape=(None,) + (1,))
# w is Mx1 column vector
self.w_assign = tf.placeholder(tf.float32, shape=shape + (1,))
self.w = tf.Variable(self._init_weight(shape + (1,)), dtype=tf.float32)
self.w_assign_op = tf.assign(self.w, self.w_assign)
# y is Nx1 column vector
self.y = tf.matmul(self.x, self.w)
# MSE evaluation
self.loss = tf.reduce_mean(tf.pow(self.y - self.t, 2)) / 2.0
# Setup model
self._setup_model()
# Setup optimizer (vary from models)
self._setup_optimizer()
def get_weight(self, sess):
return sess.run(self.w)
def set_weight(self, sess, w):
sess.run(self.w_assign_op, feed_dict={self.w_assign: w})
def save(sess):
self.w_save = self.get_weight(sess)
def save_to_file(self, sess, filename):
np.save(filename, self.get_weight(sess))
def load(sess):
self.set_weight(sess, self.w_save)
def load_from_file(self, sess, filename):
w = np.load(filename)
self.set_weight(sess, w)
def fit(self, sess, x_, t_, epoch=10, batch_size=1):
if self.optimizer == 'seq':
batch_indices = range(len(x_))
for epoch in xrange(epoch):
np.random.shuffle(batch_indices)
for i in tqdm(range(0, len(x_), batch_size)):
i_ = min(i + batch_size, len(x_))
self._optimize(sess, x_[batch_indices[i:i_]], t_[batch_indices[i:i_]])
loss = self.eval(sess, x_, t_)
if epoch % 1 == 0:
logging.info('Epoch %d: training loss = %f' % (epoch, loss))
else:
self._optimize(sess, x_, t_)
def eval(self, sess, x_, t_):
return sess.run(self.loss, feed_dict={self.x: x_,
self.t: t_})
def test(self, sess, x_):
return sess.run(self.y, feed_dict={self.x: x_})
def reset(self, sess):
self.set_weight(sess, self._init_weight(self.shape + (1,)),)
def _init_weight(self, shape):
return np.zeros(shape)
def _setup_model(self):
'''
Linear model doesn't need extra setup
'''
def _setup_optimizer(self):
if self.optimizer == 'seq':
self.optimize_op = tf.train.GradientDescentOptimizer(self.lr).minimize(self.loss)
else:
# W_ml is calculated with solving normal equation
xt = tf.transpose(self.x)
x_xt = tf.matmul(xt, self.x)
x_xt_inv = tf.matrix_inverse(x_xt)
x_xt_inv_xt = tf.matmul(x_xt_inv, xt)
self.w_ml = tf.matmul(x_xt_inv_xt, self.t)
self.optimize_op = tf.assign(self.w, self.w_ml)
def _optimize(self, sess, x_, t_):
sess.run(self.optimize_op, feed_dict={self.x: x_,
self.t: t_})
class RidgeLinearModel(LinearModel):
def __init__(self, shape, optimizer='seq', alpha=0.01, mean=0.0, var=0.8, lr=0.01, clip_min=0, clip_max=1081, is_round=True):
self.alpha = alpha
self.mean = mean
self.var = var
super(RidgeLinearModel, self).__init__(shape, optimizer, lr, clip_min, clip_max, is_round)
def _init_weight(self, shape):
return np.random.normal(self.mean, self.var, shape)
def _setup_optimizer(self):
self.ridge_loss = tf.reduce_mean(tf.pow(self.y - self.t, 2) + self.alpha * tf.reduce_sum(tf.square(self.w))) / 2.0
self.optimize_op = tf.train.AdamOptimizer(self.lr).minimize(self.ridge_loss)
class BayesianLinearModel(LinearModel):
def __init__(self, shape, m0, s0, beta, optimizer='ls', clip_min=0, clip_max=1081, is_round=True):
# Setup mean vector
if np.isscalar(m0):
self.m0 = tf.ones(shape + (1,), dtype=tf.float32) * m0
else:
self.m0 = m0
# Setup covariance matrix
if np.isscalar(s0):
self.s0 = 1.0 / s0 * tf.identity(np.identity(shape[0], dtype=np.float32))
else:
self.s0 = s0
# Setup variance of noise gaussian distribution
self.beta = beta
super(BayesianLinearModel, self).__init__(shape, optimizer, 0.0, clip_min, clip_max, is_round)
def _setup_model(self):
# Setup mn, sn
xt = tf.transpose(self.x)
self.sn = tf.matrix_inverse(tf.matrix_inverse(self.s0) + (self.beta * tf.matmul(xt, self.x)))
self.mn = tf.matmul(self.sn, tf.matmul(tf.matrix_inverse(self.s0), self.m0) + self.beta * tf.matmul(xt, self.t))
def _setup_optimizer(self):
self.optimize_op = tf.assign(self.w, self.mn)