-
Notifications
You must be signed in to change notification settings - Fork 8
/
auto_encoder.py
149 lines (119 loc) · 5.19 KB
/
auto_encoder.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
import tensorflow as tf
from utilsnn import xavier_init
class AutoEncoder(object):
def __init__(
self,
input_size,
layer_sizes,
layer_names,
symmetric_weights=False,
optimizer=tf.train.AdamOptimizer(),
transfer_function=tf.nn.sigmoid,
):
self.layer_names = layer_names
self.tied_weights = symmetric_weights
# Build the encoding layers
self.x = tf.placeholder(tf.float32, [None, input_size])
next_layer_input = self.x
assert len(layer_sizes) == len(layer_names)
self.encoding_matrices = []
self.encoding_biases = []
for i in range(len(layer_sizes)):
dim = layer_sizes[i]
input_dim = int(next_layer_input.get_shape()[1])
# Initialize W using xavier initialization
W = tf.get_variable(
layer_names[i][0],
[input_dim, dim],
initializer=tf.contrib.layers.xavier_initializer(),
)
# Initialize b to zero
b = tf.Variable(tf.zeros([dim]), name=layer_names[i][1])
# We are going to use tied-weights so store the W matrix for later reference.
self.encoding_matrices.append(W)
self.encoding_biases.append(b)
output = transfer_function(tf.matmul(next_layer_input, W) + b)
# the input into the next layer is the output of this layer
next_layer_input = output
# The fully encoded x value is now stored in the next_layer_input
self.encoded_x = next_layer_input
# build the reconstruction layers by reversing the reductions
layer_sizes.reverse()
self.encoding_matrices.reverse()
self.decoding_matrices = []
self.decoding_biases = []
for i, dim in enumerate(layer_sizes[1:] + [int(self.x.get_shape()[1])]):
W = None
# if we are using tied weights, so just lookup the encoding matrix for this step and transpose it
if symmetric_weights:
W = tf.identity(tf.transpose(self.encoding_matrices[i]))
else:
W = tf.Variable(
xavier_init(
self.encoding_matrices[i].get_shape()[1].value,
self.encoding_matrices[i].get_shape()[0].value,
transfer_function,
)
)
b = tf.Variable(tf.zeros([dim]))
self.decoding_matrices.append(W)
self.decoding_biases.append(b)
output = transfer_function(tf.matmul(next_layer_input, W) + b)
next_layer_input = output
# i need to reverse the encoding matrices back for loading weights
self.encoding_matrices.reverse()
self.decoding_matrices.reverse()
# the fully encoded and reconstructed value of x is here:
self.reconstructed_x = next_layer_input
# compute cost
self.cost = tf.sqrt(tf.reduce_mean(tf.square(self.x - self.reconstructed_x)))
self.optimizer = optimizer.minimize(self.cost)
# initalize variables
init = tf.global_variables_initializer()
self.sess = tf.Session()
self.sess.run(init)
def transform(self, X):
return self.sess.run(self.encoded_x, {self.x: X})
def reconstruct(self, X):
return self.sess.run(self.reconstructed_x, feed_dict={self.x: X})
def load_rbm_weights(self, path, layer_names, layer):
saver = tf.train.Saver(
{layer_names[0]: self.encoding_matrices[layer]},
{layer_names[1]: self.encoding_biases[layer]},
)
saver.restore(self.sess, path)
if not self.tied_weights:
self.sess.run(
self.decoding_matrices[layer].assign(
tf.transpose(self.encoding_matrices[layer])
)
)
def print_weights(self):
print("Matrices")
for i in range(len(self.encoding_matrices)):
print("Matrice", i)
print(self.encoding_matrices[i].eval(self.sess).shape)
print(self.encoding_matrices[i].eval(self.sess))
if not self.tied_weights:
print(self.decoding_matrices[i].eval(self.sess).shape)
print(self.decoding_matrices[i].eval(self.sess))
def load_weights(self, path):
dict_w = self.get_dict_layer_names()
saver = tf.train.Saver(dict_w)
saver.restore(self.sess, path)
def save_weights(self, path):
dict_w = self.get_dict_layer_names()
saver = tf.train.Saver(dict_w)
save_path = saver.save(self.sess, path)
def get_dict_layer_names(self):
dict_w = {}
for i in range(len(self.layer_names)):
dict_w[self.layer_names[i][0]] = self.encoding_matrices[i]
dict_w[self.layer_names[i][1]] = self.encoding_biases[i]
if not self.tied_weights:
dict_w[self.layer_names[i][0] + "d"] = self.decoding_matrices[i]
dict_w[self.layer_names[i][1] + "d"] = self.decoding_biases[i]
return dict_w
def partial_fit(self, X):
cost, opt = self.sess.run((self.cost, self.optimizer), feed_dict={self.x: X})
return cost