-
Notifications
You must be signed in to change notification settings - Fork 0
/
autoencoder.py
88 lines (73 loc) · 2.87 KB
/
autoencoder.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
from tensorflow.keras import Model
from tensorflow.keras.layers import Input, Conv2D, ReLU, BatchNormalization, Flatten
class Autoencoder():
"""
Autoencoder represents a Deep Convolutional autoencoder architecture
with mirrored encoder and decoder components
"""
def __init__(self,
input_shape,
conv_filters,
conv_kernels,
conv_strides,
latent_space_dim):
self.input_shape = input_shape # [28, 28, 1]
self.conv_filters = conv_filters # [2, 4, 8]
self.conv_kernels = conv_kernels # [3, 5, 3]
self.conv_strides = conv_strides # [1, 2, 2]
self.latent_space_dim = latent_space_dim # 2
self.encoder = None
self.decoder = None
self.model = None
self._num_conv_layers = len(conv_filters)
self._build()
def summary(self):
self.encoder_summary()
def _build(self):
self._build_encoder()
#self._build_decoder()
#self._build_autoencoder()
def _build_encoder(self):
encoder_input = self._add_encoder_input()
conv_layers = self._add_conv_layers(encoder_input)
bottleneck = self._add_bottleneck(conv_layers)
self.encoder = Model(encoder_input, bottleneck, name="encoder")
def _add_encoder_input(self):
return Input(shape=self.input_shape, name="encoder_input")
def _add_conv_layers(self, encoder_input):
""" Create all convolutionals blocks in encoder."""
x = encoder_input
for layer_index in range(self._num_conv_layers):
x = self._add_conv_layers(layer_index, x)
return x
def _add_conv_layers(self, layer_index, x):
"""Adds a convolutional block to a graph of layers, consisting of
conv 2d + ReLU + batch normalization.
"""
layer_number = layer_index + 1
conv_layer = Conv2D(
filters = self.conv_filters[layer_index],
kernel_size = self.conv_kernels[layer_index],
strides= self.conv_strides[layer_index],
padding = "same",
name=f"encoder_conv_layer_{layer_number}"
)
x = conv_layer(x)
x = ReLU(name=f"encoder_relu_{layer_number}")(x)
x = BatchNormalization(name=f"encoder_bn_{layer_number}")(x)
return x
def _add_bottleneck(self, x):
"""Flatten data and add bottleneck (Dense layer)."""
self._shape_before_bottleneck = K.int_shape(x)[1:] # [2, 7, 7, 32]
x = Flatten()(x)
x = Dense(self.latent_space_dim, name="encoder_output")(x)
return x
if __name__ == "__main__":
autoencoder = Autoencoder(
input_shape=(28,28,1),
conv_filters=(32, 64, 64, 64),
conv_kernels=(3, 3, 3, 3),
conv_strides=(1, 2, 2, 1),
latent_space_dim=2
)
autoencoder.summary()