gpt4 book ai didi

python - 在 TensorFlow 中使用 make_template()

转载 作者:行者123 更新时间:2023-12-02 11:31:05 25 4
gpt4 key购买 nike

我试图使用 make_template() 来避免在整个模型中传递重用标志。但在 python 类内部使用 make_template() 时,它似乎无法正常工作。我粘贴了]我的模型代码和下面出现的错误。这是一个在 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)

最佳答案

这里的代码存在多个问题,例如trainaccuracypredict 方法中的 model 引用。我认为这是由于将代码从其自然栖息地中删除了。

您提到的TypeError的原因,

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

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

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 模板现在都只有一个参数,即要创建的变量的形状。

关于python - 在 TensorFlow 中使用 make_template(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40367923/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com