I have try to tied weights in tensorflow 2.0 keras, with below code. but it shows this errors? does anyone know how to write tied weights dense layer ?
JavaScript
x
27
27
1
tf.random.set_seed(0)
2
with tf.device('/cpu:0'):
3
# This returns a tensor
4
inputs = Input(shape=(784,))
5
6
# a layer instance is callable on a tensor, and returns a tensor
7
layer_1 = Dense(64, activation='relu')
8
layer_1_output = layer_1(inputs)
9
layer_2 = Dense(64, activation='relu')
10
layer_2_output = layer_2(layer_1_output)
11
weights = tf.transpose(layer_1.weights[0]).numpy()
12
print(weights.shape)
13
transpose_layer = Dense(
14
784, activation='relu')
15
transpose_layer_output = transpose_layer(layer_2_output)
16
transpose_layer.set_weights(weights)
17
predictions = Dense(10, activation='softmax')(transpose_layer)
18
19
# This creates a model that includes
20
# the Input layer and three Dense layers
21
model = Model(inputs=inputs, outputs=predictions)
22
model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
23
loss='categorical_crossentropy',
24
metrics=['accuracy'])
25
# print(model.weights)
26
model.summary()
27
Errors
JavaScript
1
10
10
1
Traceback (most recent call last):
2
File "practice_2.py", line 62, in <module>
3
transpose_layer.set_weights(weights)
4
File "/Users/cheesiang_leow/.virtualenvs/tensorflow-2.0/lib/python3.6/site-
5
packages/tensorflow/python/keras/engine/base_layer.py", line 934, in set_weights
6
str(weights)[:50] + '...')
7
ValueError: You called `set_weights(weights)` on layer "dense_2" with a weight
8
list of length 64, but the layer was expecting 2 weights. Provided weights:
9
[[-0.03499636 0.0214913 0.04076344 -0.06531
10
Advertisement
Answer
It took much of my time to figure out, but I think this is the way of Tied Weights by subclassing Keras Dense layer.
JavaScript
1
121
121
1
class TiedLayer(Dense):
2
def __init__(self, layer_sizes, l2_normalize=False, dropout=0.0, *args, **kwargs):
3
self.layer_sizes = layer_sizes
4
self.l2_normalize = l2_normalize
5
self.dropout = dropout
6
self.kernels = []
7
self.biases = []
8
self.biases2 = []
9
self.uses_learning_phase = True
10
self.activation = kwargs['activation']
11
if self.activation == "leaky_relu":
12
self.activation = kwargs.pop('activation')
13
self.activation = LeakyReLU()
14
print(self.activation)
15
super().__init__(units=1, *args, **kwargs) # 'units' not used
16
17
def compute_output_shape(self, input_shape):
18
return input_shape
19
20
def build(self, input_shape):
21
assert len(input_shape) >= 2
22
input_dim = int(input_shape[-1])
23
24
self.input_spec = InputSpec(min_ndim=2, axes={-1: input_dim})
25
# print(input_dim)
26
for i in range(len(self.layer_sizes)):
27
28
self.kernels.append(
29
self.add_weight(
30
shape=(
31
input_dim,
32
self.layer_sizes[i]),
33
initializer=self.kernel_initializer,
34
name='ae_kernel_{}'.format(i),
35
regularizer=self.kernel_regularizer,
36
constraint=self.kernel_constraint))
37
38
if self.use_bias:
39
self.biases.append(
40
self.add_weight(
41
shape=(
42
self.layer_sizes[i],
43
),
44
initializer=self.bias_initializer,
45
name='ae_bias_{}'.format(i),
46
regularizer=self.bias_regularizer,
47
constraint=self.bias_constraint))
48
input_dim = self.layer_sizes[i]
49
50
if self.use_bias:
51
for n, i in enumerate(range(len(self.layer_sizes)-2, -1, -1)):
52
self.biases2.append(
53
self.add_weight(
54
shape=(
55
self.layer_sizes[i],
56
),
57
initializer=self.bias_initializer,
58
name='ae_bias2_{}'.format(n),
59
regularizer=self.bias_regularizer,
60
constraint=self.bias_constraint))
61
self.biases2.append(self.add_weight(
62
shape=(
63
int(input_shape[-1]),
64
),
65
initializer=self.bias_initializer,
66
name='ae_bias2_{}'.format(len(self.layer_sizes)),
67
regularizer=self.bias_regularizer,
68
constraint=self.bias_constraint))
69
70
self.built = True
71
72
def call(self, inputs):
73
return self.decode(self.encode(inputs))
74
75
def _apply_dropout(self, inputs):
76
dropped = K.backend.dropout(inputs, self.dropout)
77
return K.backend.in_train_phase(dropped, inputs)
78
79
def encode(self, inputs):
80
latent = inputs
81
for i in range(len(self.layer_sizes)):
82
if self.dropout > 0:
83
latent = self._apply_dropout(latent)
84
print(self.kernels[i])
85
latent = K.backend.dot(latent, self.kernels[i])
86
if self.use_bias:
87
print(self.biases[i])
88
latent = K.backend.bias_add(latent, self.biases[i])
89
if self.activation is not None:
90
latent = self.activation(latent)
91
if self.l2_normalize:
92
latent = latent / K.backend.l2_normalize(latent, axis=-1)
93
return latent
94
95
def decode(self, latent):
96
recon = latent
97
for i in range(len(self.layer_sizes)):
98
if self.dropout > 0:
99
recon = self._apply_dropout(recon)
100
print(self.kernels[len(self.layer_sizes) - i - 1])
101
recon = K.backend.dot(recon, K.backend.transpose(
102
self.kernels[len(self.layer_sizes) - i - 1]))
103
if self.use_bias:
104
print(self.biases2[i])
105
recon = K.backend.bias_add(recon, self.biases2[i])
106
if self.activation is not None:
107
recon = self.activation(recon)
108
return recon
109
110
def get_config(self):
111
config = {
112
'layer_sizes': self.layer_sizes
113
}
114
base_config = super().get_config()
115
base_config.pop('units', None)
116
return dict(list(base_config.items()) + list(config.items()))
117
118
@classmethod
119
def from_config(cls, config):
120
return cls(**config)
121
Hope it can help someone else.