TensorFlow中的模板()

我试图使用make_template()来避免在我的模型中传递重用标志。 但似乎make_template()在python类中使用时无法正确工作。 我粘贴]我的模型代码和我得到的错误。 在MNIST数据集上训练是一个简单的MLP。

由于代码有点长,这里的主要部分是_weights()函数。 我尝试使用make_template()来封装它,然后使用get_variables()在其中创建并重新使用整个模型中的权重。 _weights()由_create_dense_layer()使用,并由_create_model()用来创建图形。 train()函数接受我从数据读取器获得的张量。

模型

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)

错误:

---------------------------------------------------------------------------
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)

此代码存在多个问题,例如trainmodel参考, accuracypredict方法。 我认为这是由于从自然栖息地切割代码。

你提到的TypeError的原因,

TypeError: _real_weights() missing 1 required positional argument: 'shape'

最有可能来自_real_weights本身是MLP类的实例方法,而不是常规函数或静态方法。 因此,函数的第一个参数始终是在调用时指向类实例的self引用(C类语言中this指针的显式版本),如函数声明中所示:

def _real_weights(self, shape):
    initializer=tf.truncated_normal_initializer(stddev=0.1)
    weights = tf.get_variable('weights', shape, initializer=initializer)
    return weights

请注意,即使您不使用参数,在这种情况下仍然需要。 因此在创建函数的模板时使用

tf.make_template('_weights', self._real_weights)

你基本上认为你创建的_weights模板应该有两个位置参数: selfweights (就像_real_weights方法一样)。 因此,当您将从模板创建的函数调用为

weights = self._weights([n_in, n_out])

您将数组传递给self参数,而未指定(必需的) shape参。

从看起来你会在这里有两个选择:你可以让_real_weights成为MLP类之外的常规函数​​,这样

def _real_weights(shape):
    initializer=tf.truncated_normal_initializer(stddev=0.1)
    weights = tf.get_variable('weights', shape, initializer=initializer)
    return weights

class MLP():
    # etc.

这可能不是你想要的,因为你已经为模型创建了一个类 - 或者你可以明确地将它作为MLP类的一个静态方法,这样

class MLP():
    @staticmethod
    def _real_weights(shape):
        initializer=tf.truncated_normal_initializer(stddev=0.1)
        weights = tf.get_variable('weights', shape, initializer=initializer)
        return weights

由于定义的静态方法不能对类实例进行操作,因此可以(并且必须)省略self引用。

然后,您将创建模板

tf.make_template('_weights', _real_weights)

在第一种情况下

tf.make_template('_weights', MLP._real_weights)

在第二种情况下,显式指定类MLP作为静态方法的名称范围。 无论哪种方式, _real_weights函数/方法和_weights模板现在都只有一个参数,即要创建的变量的形状。

链接地址: http://www.djcxy.com/p/32057.html

上一篇: template() in TensorFlow

下一篇: loaded data in TensorFlow