我见过的每个TensorFlow示例都使用占位符将数据提供给图表。但我的应用程序工作正常,没有占位符。根据{{3}},使用占位符是最佳实践",但它们似乎使代码不必要地复杂。
是否有任何场合绝对需要占位符?
答案 0 :(得分:2)
占位符是稍后提供值的承诺。 简单的例子是定义两个占位符a,b,然后对它们进行操作,如下所示。
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b # + provides a shortcut for tf.add(a, b)
a,b
未初始化且不包含数据因为它们被定义为占位符。
执行相同操作的其他方法是定义变量tf.Variable
,在这种情况下,您必须在声明变量时提供初始值。
喜欢:
tf.global_variables_initializer()
或
tf.initialize_all_variables()
这个解决方案有两个缺点
性能明智,您需要在调用时执行一个额外步骤 初始化程序然而这些变量是可更新的。
在某些情况下,您不知道这些变量的初始值 所以你必须将它定义为占位符
结论:
将tf.Variable
用于您的模型的可训练变量,例如权重(W)和偏差(B),或者在需要初始值时使用tf.placeholder
一般
SQLDialect
允许您创建操作并构建计算图,而无需数据。在TensorFlow中
术语,我们然后通过这些将数据输入图表
占位符。
答案 1 :(得分:2)
根据文档,使用占位符是最佳实践"
坚持,这句话是脱离背景的,可能会被误解。在通过$scope.a = {
users: []
};
function getUsers(search) {
var deferred = $q.defer();
var users = [
{ name: 'Adam', email: 'adam@email.com', age: 12, country: 'United States' },
{ name: 'Amalie', email: 'amalie@email.com', age: 12, country: 'Argentina' },
{ name: 'Estefanía', email: 'estefania@email.com', age: 21, country: 'Argentina' },
{ name: 'Adrian', email: 'adrian@email.com', age: 21, country: 'Ecuador' },
{ name: 'Wladimir', email: 'wladimir@email.com', age: 30, country: 'Ecuador' },
{ name: 'Samantha', email: 'samantha@email.com', age: 30, country: 'United States' },
{ name: 'Nicole', email: 'nicole@email.com', age: 43, country: 'Colombia' },
{ name: 'Natasha', email: 'natasha@email.com', age: 54, country: 'Ecuador' },
{ name: 'Michael', email: 'michael@email.com', age: 15, country: 'Colombia' },
{ name: 'Nicolás', email: 'nicole@email.com', age: 43, country: 'Colombia' }
];
$timeout(function() {
deferred.resolve(users.filter(function(user) {
return user.name.indexOf(search) > -1;
}));
}, 2000);
return deferred.promise;
}
$scope.filteredUsers = [];
$scope.refreshUsers = function(search) {
getUsers(search).then(function(response) {
$scope.filteredUsers = response;
});
};
提供数据时,占位符是的最佳做法。
使用占位符可以明确意图:这是一个需要输入的输入节点。 Tensorflow甚至提供不需要提供的feed_dict
- 但同样,这样的节点的意图是明确的。出于所有目的,placeholder_with_default
与placeholder_with_default
做同样的事情 - 您确实可以提供constant
来更改其值,但意图是明确的,这不会令人困惑吗?我对此表示怀疑。
输入数据还有其他方式而不是喂食,而AFAICS都有其用途。
答案 2 :(得分:0)
我真的很喜欢艾哈迈德的回答而且我赞成了它,但我想提供一个可能会或可能不会让事情变得更清晰的替代解释。
Tensorflow的一个重要特性是它的操作图被编译,然后在用于构建它们的原始环境之外执行。这使得Tensorflow可以进行各种技巧和优化,例如分布式,独立于平台的计算,图形互操作性,GPU计算等。但所有这些都是以复杂性为代价的。由于你的图形是在它自己的VM中执行的,你必须有一种特殊的方式从外部向它提供数据,例如你的python程序。
这是占位符的来源。将数据输入模型的一种方法是在执行图形操作时通过提要字典提供数据。并且为了指示图表中的数据应该在哪里,你使用占位符。这样,正如艾哈迈德所说,占位符是对未来提供的数据的一种承诺。它实际上是您稍后将提供的东西的占位符。使用类似于艾哈迈德的例子
# define graph to do matrix muliplication x = tf.placeholder(tf.float32) y = tf.placeholder(tf.float32) # this is the actual operation we want to do, # but since we want to supply x and y at runtime # we will use placeholders model = tf.matmul(x, y) # now lets supply the data and run the graph init = tf.global_variables_initializer() with tf.Session() as session: session.run(init) # generate some data for our graph data_x = np.random.randint(0, 10, size=[5, 5]) data_y = np.random.randint(0, 10, size=[5, 5]) # do the work result = session.run(model, feed_dict={x: data_x, y: data_y}
还有其他方法可以向图表中提供数据,但可以说,占位符和feed_dict是最易理解的方式,它提供了最大的灵活性。
如果要避免使用占位符,其他提供数据的方法是将整个数据集加载到图形构建的常量中,或者使用输入管道移动整个加载过程并将数据预处理到图形中。您可以在TF文档中阅读所有这些内容。