发新帖

TensorFlow 学习 -- 编程人员指南: 低级别 API 简介 (2)

[复制链接]
191 0

快来加入 TensorFlowers 大家庭!

您需要 登录 才可以下载或查看,没有帐号?加入社区

x
本帖最后由 大白白 于 2018-7-6 15:52 编辑

转载自:https://tensorflow.google.cn/programmers_guide/low_level_intro?hl=zh-CN


供 给
目前来讲,这个图不是特别有趣,因为它总是生成一个常量结果。图可以参数化以便接受外部输入,也称为占位符占位符表示承诺在稍后提供值,它就像函数参数。

x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
z = x + y
前面三行有点像函数。我们定义了这个函数的两个输入参数(x 和 y),然后对它们运行指令。我们可以使用 run 方法的 feed_dict 参数来为占位符提供真正的值,从而通过多个输入值来评估这个图:

print(sess.run(z, feed_dict={x: 3, y: 4.5}))
print(sess.run(z, feed_dict={x: [1, 3], y: [2, 4]}))
上述操作的结果是输出以下内容:

7.5
[ 3.  7.]
另请注意,feed_dict 参数可用于覆盖图中的任何张量。占位符和其他 tf.Tensors 的唯一不同之处在于如果没有提供值给它们,那么占位符会显示错误。
数据集
占位符适用于简单的实验,但数据集是将数据流式传输到模型的首选方法。
要从数据集中获取可运行的 tf.Tensor,您必须先将其转换成 tf.data.Iterator,然后调用迭代器 (Iterator) 的 get_next 方法。
创建迭代器的最简单的方式是采用 make_one_shot_iterator 方法。例如,在下面的代码中,next_item 张量将在每次 run 调用时从 my_data 阵列返回一行:

my_data = [
    [0, 1,],
    [2, 3,],
    [4, 5,],
    [6, 7,],
]
slices = tf.data.Dataset.from_tensor_slices(my_data)
next_item = slices.make_one_shot_iterator().get_next()
到达数据流末端时,Dataset 会抛出 OutOfRangeError。例如,下面的代码会一直读取 next_item,直到没有数据可读:

while True:
  try:
    print(sess.run(next_item))
  except tf.errors.OutOfRangeError:
    break
要详细了解数据集和迭代器,请参阅导入数据


可训练的模型必须修改图中的值,以便在输入相同值的情况下获得新的输出值。将可训练参数添加到图中的首选方法是
层将变量和作用于它们的指令打包在一起。例如,密集连接层会对每个输出值对应的所有输入值执行加权和,并应用可选择的激活函数。连接权重和偏差由层对象管理。


创建层
下面的代码会创建一个 Dense 层,该层会接收一批输入矢量,并为每个矢量生成单一的输出值。要将层应用于输入值,请将该层当做函数来调用。例如:

x = tf.placeholder(tf.float32, shape=[None, 3])
linear_model = tf.layers.Dense(units=1)
y = linear_model(x)
层会检查其输入数据,以确定其内部变量的大小。因此,我们必须在这里设置 x 占位符的形状,以便层构建正确大小的权重矩阵。
我们现在已经定义了输出值 y 的计算,在我们运行计算之前,还需要处理一个细节。


初始化层
层包含的变量必须先初始化,然后才能使用。尽管您可以逐一初始化各个变量,但您也可以轻松地初始化一个 TensorFlow 图中的所有变量(如下所示):

init = tf.global_variables_initializer()
sess.run(init)
重要提示:调用 tf.global_variables_initializer 仅会创建并返回一个 TensorFlow 指令的手柄。当我们使用 tf.Session.run 运行该指令时,该指令会初始化所有全局变量。
另请注意,此 global_variables_initializer 仅会初始化创建初始化程序时图中就存在的变量。因此您应该在构建图表的最后一步添加初始化程序。


执行层
我们现在已经完成了层的初始化,可以像处理任何其他张量一样评估 linear_model 的输出张量了。例如,下面的代码:

print(sess.run(y, {x: [[1, 2, 3],[4, 5, 6]]}))
会生成一个两元素输出向量,如下所示:

[[-3.41378999]
[-9.14999008]]

层函数的快捷方式
对于每个层类别(如 tf.layers.Dense),TensorFlow 还提供了一个快捷函数(如 tf.layers.dense)。两者唯一的区别是快捷函数版本是在单次调用中创建和运行层。例如,以下代码等同于较早的版本:

x = tf.placeholder(tf.float32, shape=[None, 3])
y = tf.layers.dense(x, units=1)

init = tf.global_variables_initializer()
sess.run(init)

print(sess.run(y, {x: [[1, 2, 3], [4, 5, 6]]}))
尽管这种方法很方便,但无法访问 tf.layers.Layer 对象。这会让自省和调试变得更加困难,并且无法重复使用相应的层。


特征列
使用特征列进行实验的最简单的方法是使用 tf.feature_column.input_layer 函数。此函数只接受密集列作为输入数据,因此要查看分类列的结果,您必须将其包含在 tf.feature_column.indicator_column。例如:

features = {
    'sales' : [[5], [10], [8], [9]],
    'department': ['sports', 'sports', 'gardening', 'gardening']}

department_column = tf.feature_column.categorical_column_with_vocabulary_list(
        'department', ['sports', 'gardening'])
department_column = tf.feature_column.indicator_column(department_column)

columns = [
    tf.feature_column.numeric_column('sales'),
    department_column
]

inputs = tf.feature_column.input_layer(features, columns)
运行 inputs 张量会将 features 解析为一批向量。
特征列和层一样具有内部状态,因此通常需要将它们初始化。分类列会在内部使用对照表,而这些表需要单独的初始化指令 tf.tables_initializer

var_init = tf.global_variables_initializer()
table_init = tf.tables_initializer()
sess = tf.Session()
sess.run((var_init, table_init))
内部状态初始化完成后,您就可以像运行任何其他 tf.Tensor 一样运行 inputs:

print(sess.run(inputs))
这显示了特征列如何打包输入矢量,在这过程中,独热“部门”被用作第一和第二个索引,“销售”用作第三个。

[[  1.   0.   5.]
[  1.   0.  10.]
[  0.   1.   8.]
[  0.   1.   9.]]


本楼点评(0) 收起
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

快速回复 返回顶部 返回列表