-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathAE.py
172 lines (151 loc) · 6.85 KB
/
AE.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
"""
Implementation of the Deep Embedded Self-Organizing Map model
Autoencoder helper functions
@author Florent Forest
@version 2.0
"""
from keras.models import Model
from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D, Flatten, Reshape, BatchNormalization
import numpy as np
def mlp_autoencoder(encoder_dims,
act='relu',
init='glorot_uniform',
batchnorm=False):
"""Fully connected symmetric autoencoder model.
Parameters
----------
encoder_dims : list
number of units in each layer of encoder. encoder_dims[0] is the input dim, encoder_dims[-1] is the
size of the hidden layer (latent dim). The autoencoder is symmetric, so the total number of layers
is 2*len(encoder_dims) - 1
act : str (default='relu')
activation of AE intermediate layers, not applied to Input, Hidden and Output layers
init : str (default='glorot_uniform')
initialization of AE layers
batchnorm : bool (default=False)
use batch normalization
Returns
-------
ae_model, encoder_model, decoder_model : tuple
autoencoder, encoder and decoder models
"""
n_stacks = len(encoder_dims) - 1
# Input
x = Input(shape=(encoder_dims[0],), name='input')
# Internal layers in encoder
encoded = x
for i in range(n_stacks-1):
encoded = Dense(encoder_dims[i + 1], activation=act, kernel_initializer=init, name='encoder_%d' % i)(encoded)
if batchnorm:
encoded = BatchNormalization()(encoded)
# Hidden layer (latent space)
encoded = Dense(encoder_dims[-1], activation='linear', kernel_initializer=init,
name='encoder_%d' % (n_stacks - 1))(encoded) # latent representation is extracted from here
# Internal layers in decoder
decoded = encoded
for i in range(n_stacks-1, 0, -1):
decoded = Dense(encoder_dims[i], activation=act, kernel_initializer=init, name='decoder_%d' % i)(decoded)
if batchnorm:
decoded = BatchNormalization()(decoded)
# Output
decoded = Dense(encoder_dims[0], activation='linear', kernel_initializer=init, name='decoder_0')(decoded)
# AE model
autoencoder = Model(inputs=x, outputs=decoded, name='AE')
# Encoder model
encoder = Model(inputs=x, outputs=encoded, name='encoder')
# Create input for decoder model
encoded_input = Input(shape=(encoder_dims[-1],))
# Internal layers in decoder
decoded = encoded_input
for i in range(n_stacks-1, -1, -1):
decoded = autoencoder.get_layer('decoder_%d' % i)(decoded)
# Decoder model
decoder = Model(inputs=encoded_input, outputs=decoded, name='decoder')
return autoencoder, encoder, decoder
def conv2d_autoencoder(input_shape,
latent_dim,
encoder_filters,
filter_size,
pooling_size,
act='relu',
init='glorot_uniform',
batchnorm=False):
"""2D convolutional autoencoder model.
Parameters
----------
input_shape : tuple
input shape given as (height, width, channels) tuple
latent_dim : int
dimension of latent code (units in hidden dense layer)
encoder_filters : list
number of filters in each layer of encoder. The autoencoder is symmetric,
so the total number of layers is 2*len(encoder_filters) - 1
filter_size : int
size of conv filters
pooling_size : int
size of maxpool filters
act : str (default='relu')
activation of AE intermediate layers, not applied to Input, Hidden and Output layers
init : str (default='glorot_uniform')
initialization of AE layers
batchnorm : boolean (default=False)
use batch normalization
Returns
-------
ae_model, encoder_model, decoder_model : tuple
autoencoder, encoder and decoder models
"""
n_stacks = len(encoder_filters)
# Infer code shape (assuming "same" padding, conv stride equal to 1 and max pooling stride equal to pooling_size)
code_shape = list(input_shape)
for _ in range(n_stacks):
code_shape[0] = int(np.ceil(code_shape[0] / pooling_size))
code_shape[1] = int(np.ceil(code_shape[1] / pooling_size))
code_shape[2] = encoder_filters[-1]
# Input
x = Input(shape=input_shape, name='input')
# Internal layers in encoder
encoded = x
for i in range(n_stacks):
encoded = Conv2D(encoder_filters[i], filter_size, activation=act, padding='same', name='encoder_conv_%d'
% i)(encoded)
if batchnorm:
encoded = BatchNormalization()(encoded)
encoded = MaxPooling2D(pooling_size, padding='same', name='encoder_maxpool_%d' % i)(encoded)
# Flatten
flattened = Flatten(name='flatten')(encoded)
# Project using dense layer
code = Dense(latent_dim, name='dense1')(flattened) # latent representation is extracted from here
# Project back to last feature map dimension
reshaped = Dense(code_shape[0] * code_shape[1] * code_shape[2], name='dense2')(code)
# Reshape
reshaped = Reshape(code_shape, name='reshape')(reshaped)
# Internal layers in decoder
decoded = reshaped
for i in range(n_stacks-1, -1, -1):
if i > 0:
decoded = Conv2D(encoder_filters[i], filter_size, activation=act, padding='same', name='decoder_conv_%d'
% i)(decoded)
else:
decoded = Conv2D(encoder_filters[i], filter_size, activation=act, padding='valid', name='decoder_conv_%d'
% i)(decoded)
if batchnorm:
decoded = BatchNormalization()(decoded)
decoded = UpSampling2D(pooling_size, name='decoder_upsample_%d' % i)(decoded)
# Output
decoded = Conv2D(1, filter_size, activation='linear', padding='same', name='decoder_0')(decoded)
# AE model
autoencoder = Model(inputs=x, outputs=decoded, name='AE')
# Encoder model (flattened output)
encoder = Model(inputs=x, outputs=code, name='encoder')
# Decoder model
latent_input = Input(shape=(latent_dim,))
flat_encoded_input = autoencoder.get_layer('dense2')(latent_input)
encoded_input = autoencoder.get_layer('reshape')(flat_encoded_input)
decoded = encoded_input
for i in range(n_stacks-1, -1, -1):
decoded = autoencoder.get_layer('decoder_conv_%d' % i)(decoded)
decoded = autoencoder.get_layer('decoder_upsample_%d' % i)(decoded)
decoded = autoencoder.get_layer('decoder_0')(decoded)
decoder = Model(inputs=latent_input, outputs=decoded, name='decoder')
return autoencoder, encoder, decoder