我试图使用 make_template() 来避免在整个模型中传递重用标志。但在 python 类内部使用 make_template() 时,它似乎无法正常工作。我粘贴了]我的模型代码和下面出现的错误。这是一个在 MNIST 数据集上训练的简单 MLP。
由于代码有点长,这里的主要部分是 _weights() 函数。我尝试使用 make_template() 包装它,然后在其中使用 get_variables() 在整个模型中创建和重用权重。_weights() 由 _create_dense_layer() 使用,而 _create_model() 又使用它来创建图形。train() 函数接受我从数据读取器获得的张量。
模型
MLP 类(对象):
def __init__(self, 隐藏=[], 偏差=False, 激活=tf.nn.relu):
self.graph = tf.get_default_graph()
self.hidden = 隐藏
自我激活=激活
自我偏见 = 偏见
self.n_features = 784
self.n_classes = 10
self.bsize = 100
自身.l2 = 0.1
def _real_weights(自身,形状):
初始化器=tf.truncated_normal_initializer(stddev=0.1)
权重 = tf.get_variable('权重', 形状, 初始化器=初始化器)
返回权重
# 使用 make_template 使变量重用透明
_weights = tf.make_template('_weights', _real_weights)
def _real_biases(自我,形状):
初始化器=tf.constant_initializer(0.0)
返回 tf.get_variable('偏差', 形状, 初始化器 = 初始化器)
# 使用 make_template 使变量重用透明
_biases = tf.make_template('_biases', _real_biases)
def _create_dense_layer(自身,名称,输入,n_in,n_out,激活= True):
与 tf.variable_scope(name):
权重 = self._weights([n_in, n_out])
层= tf.matmul(输入,权重)
如果自我偏见:
偏差 = self._biases([n_out])
层 = 层 + 偏差
如果激活:
层 = self.activation(层)
返回层
def _create_model(自我,输入):
n_in = self.n_features
对于范围内的 i(len(self.hidden)):
n_out = self.hidden[i]
名称 = '隐藏%d' % (i)
输入= self._create_dense_layer(名称,输入,n_in,n_out)
n_输入 = n_输出
输出 = self._create_dense_layer('输出', 输入, n_in, self.n_classes, 激活=False)
返回输出
def _create_loss_op(自我,logits,标签):
cent = tf.nn.softmax_cross_entropy_with_logits(logits, 标签)
权重 = self.graph.get_collection('权重')
l2 = (self.l2 / self.bsize) * tf.reduce_sum([tf.reduce_sum(tf.square(w)) for w inweights])
返回 tf.reduce_mean(cent, name='loss') + l2
def _create_train_op(自我,损失):
优化器 = tf.train.AdamOptimizer()
返回优化器.最小化(损失)
def _create_accuracy_op(自我,logits,标签):
预测 = tf.nn.softmax(logits)
错误 = tf.equal(tf.argmax(预测, 1), tf.argmax(标签, 1))
返回 tf.reduce_mean(tf.cast(错误, tf.float32))
def 火车(自身、图像、标签):
logits = model._create_model(图像)
损失 = model._create_loss_op(logits, labels)
返回 model._create_train_op(loss)
def 准确率(自身、图像、标签):
logits = model._create_model(图像)
返回 model._create_accuracy_op(logits, labels)
def 预测(自身,图像):
返回 model._create_model(图像)
错误:
-------------------------------------------------- ------------------------
类型错误回溯(最近一次调用最后一次)
在 ()
25 模型 = MLP(隐藏=[128])
26 # 定义操作
---> 27 train = model.train(图像, 标签)
28 准确度 = model.accuracy(eval_images, eval_labels)
29 # 加载测试数据并创建预测操作
在火车上(自我、图像、标签)
60
61 def 训练(自身、图像、标签):
---> 62 logits = model._create_model(images)
63 损失 = model._create_loss_op(logits, labels)
64 返回 model._create_train_op(loss)
在 _create_model(自我,输入)
39 n_out = self.隐藏[i]
40 名称 = '隐藏%d' % (i)
---> 41 个输入 = self._create_dense_layer(名称, 输入, n_in, n_out)
42 n_输入=n_输出
43 输出 = self._create_dense_layer('输出', 输入, n_in, self.n_classes, 激活=False)
在 _create_dense_layer(自身、名称、输入、n_in、n_out、激活)
25 def _create_dense_layer(自身,名称,输入,n_in,n_out,激活= True):
26 与 tf.variable_scope(name):
---> 27 个权重 = self._weights([n_in, n_out])
28层= tf.matmul(输入,权重)
29如果自我偏见:
/usr/local/lib/python3.5/site-packages/tensorflow/python/ops/template.py 在 __call__(self, *args, **kwargs)
[第 265 章]
第266章
--> 267 返回 self._call_func(args, kwargs, check_for_new_variables=False)
268
第269章
/usr/local/lib/python3.5/site-packages/tensorflow/python/ops/template.py 在 _call_func(self, args, kwargs, check_for_new_variables)
206 ops.get_collection(ops.GraphKeys.TRAINABLE_VARIABLES))
207
--> 208 结果 = self._func(*args, **kwargs)
209 if check_for_new_variables:
第210章
类型错误:_real_weights() 缺少 1 个必需的位置参数:“形状”
最初定义于:
文件“”,第 1 行,位于
MLP 类(对象):
MLP 中的文件“”,第 17 行
_weights = tf.make_template('_weights', _real_weights)
此处的代码存在多个问题,例如、和方法model中的引用。我认为这是由于将代码从其自然栖息地中删除了。trainaccuracypredict
至于你提到的原因TypeError,
TypeError: _real_weights() missing 1 required positional argument: 'shape'
Run Code Online (Sandbox Code Playgroud)
最有可能的原因是_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
Run Code Online (Sandbox Code Playgroud)
请注意,即使您不使用该参数,在这种情况下仍然需要它。因此,当使用创建函数模板时
tf.make_template('_weights', self._real_weights)
Run Code Online (Sandbox Code Playgroud)
您基本上声明_weights您创建的模板应该采用两个位置参数:self和weights(与方法一样_real_weights)。因此,当您调用从模板创建的函数时
weights = self._weights([n_in, n_out])
Run Code Online (Sandbox Code Playgroud)
您将数组传递给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.
Run Code Online (Sandbox Code Playgroud)
这可能不是您想要的,因为您已经为模型创建了一个类 - 或者您可以显式地将其设为该类的静态方法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
Run Code Online (Sandbox Code Playgroud)
由于根据定义,静态方法不对类实例进行操作,因此您可以(并且必须)省略引用self。
然后您将创建模板为
tf.make_template('_weights', _real_weights)
Run Code Online (Sandbox Code Playgroud)
在第一种情况下和
tf.make_template('_weights', MLP._real_weights)
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,显式指定类MLP作为静态方法的名称范围。无论哪种方式,_real_weights函数/方法和_weights模板现在都只有一个参数,即要创建的变量的形状。
| 归档时间: |
|
| 查看次数: |
3425 次 |
| 最近记录: |