I am trying to use make_template() to avoid passing reuse flag throughout my model. But it seems that make_template() doesn't work correctly when it is used inside of a python class. I pasted ]my model code and the error I am getting below. It is a simple MLP to train on the MNIST dataset.
Since the code is kinda long, the main part here is the _weights() function. I try to wrap it using make_template() and then use get_variables() inside it to create and reuse weights throughout my model. _weights() is used by _create_dense_layer() and that in turn is used by _create_model() to create the graph. The train() function accepts tensors that I get from a data reader.
Model
class MLP(object):
def __init__(self, hidden=[], biases=False, activation=tf.nn.relu):
self.graph = tf.get_default_graph()
self.hidden = hidden
self.activation = activation
self.biases = biases
self.n_features = 784
self.n_classes = 10
self.bsize = 100
self.l2 = 0.1
def _real_weights(self, shape):
initializer=tf.truncated_normal_initializer(stddev=0.1)
weights = tf.get_variable('weights', shape, initializer=initializer)
return weights
# use make_template to make variable reuse transparent
_weights = tf.make_template('_weights', _real_weights)
def _real_biases(self, shape):
initializer=tf.constant_initializer(0.0)
return tf.get_variable('biases', shape, initializer=initializer)
# use make_template to make variable reuse transparent
_biases = tf.make_template('_biases', _real_biases)
def _create_dense_layer(self, name, inputs, n_in, n_out, activation=True):
with tf.variable_scope(name):
weights = self._weights([n_in, n_out])
layer = tf.matmul(inputs, weights)
if self.biases:
biases = self._biases([n_out])
layer = layer + biases
if activation:
layer = self.activation(layer)
return layer
def _create_model(self, inputs):
n_in = self.n_features
for i in range(len(self.hidden)):
n_out = self.hidden[i]
name = 'hidden%d' % (i)
inputs = self._create_dense_layer(name, inputs, n_in, n_out)
n_in = n_out
output = self._create_dense_layer('output', inputs, n_in, self.n_classes, activation=False)
return output
def _create_loss_op(self, logits, labels):
cent = tf.nn.softmax_cross_entropy_with_logits(logits, labels)
weights = self.graph.get_collection('weights')
l2 = (self.l2 / self.bsize) * tf.reduce_sum([tf.reduce_sum(tf.square(w)) for w in weights])
return tf.reduce_mean(cent, name='loss') + l2
def _create_train_op(self, loss):
optimizer = tf.train.AdamOptimizer()
return optimizer.minimize(loss)
def _create_accuracy_op(self, logits, labels):
predictions = tf.nn.softmax(logits)
errors = tf.equal(tf.argmax(predictions, 1), tf.argmax(labels, 1))
return tf.reduce_mean(tf.cast(errors, tf.float32))
def train(self, images, labels):
logits = model._create_model(images)
loss = model._create_loss_op(logits, labels)
return model._create_train_op(loss)
def accuracy(self, images, labels):
logits = model._create_model(images)
return model._create_accuracy_op(logits, labels)
def predict(self, images):
return model._create_model(images)
The error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
25 model = MLP(hidden=[128])
26 # define ops
---> 27 train = model.train(images, labels)
28 accuracy = model.accuracy(eval_images, eval_labels)
29 # load test data and create a prediction op
in train(self, images, labels)
60
61 def train(self, images, labels):
---> 62 logits = model._create_model(images)
63 loss = model._create_loss_op(logits, labels)
64 return model._create_train_op(loss)
in _create_model(self, inputs)
39 n_out = self.hidden[i]
40 name = 'hidden%d' % (i)
---> 41 inputs = self._create_dense_layer(name, inputs, n_in, n_out)
42 n_in = n_out
43 output = self._create_dense_layer('output', inputs, n_in, self.n_classes, activation=False)
in _create_dense_layer(self, name, inputs, n_in, n_out, activation)
25 def _create_dense_layer(self, name, inputs, n_in, n_out, activation=True):
26 with tf.variable_scope(name):
---> 27 weights = self._weights([n_in, n_out])
28 layer = tf.matmul(inputs, weights)
29 if self.biases:
/usr/local/lib/python3.5/site-packages/tensorflow/python/ops/template.py in __call__(self, *args, **kwargs)
265 self._unique_name, self._name) as vs:
266 self._var_scope = vs
--> 267 return self._call_func(args, kwargs, check_for_new_variables=False)
268
269 @property
/usr/local/lib/python3.5/site-packages/tensorflow/python/ops/template.py in _call_func(self, args, kwargs, check_for_new_variables)
206 ops.get_collection(ops.GraphKeys.TRAINABLE_VARIABLES))
207
--> 208 result = self._func(*args, **kwargs)
209 if check_for_new_variables:
210 trainable_variables = ops.get_collection(
TypeError: _real_weights() missing 1 required positional argument: 'shape'
originally defined at:
File "", line 1, in
class MLP(object):
File "", line 17, in MLP
_weights = tf.make_template('_weights', _real_weights)