TensorFlow学习笔记:入门

来源:互联网 发布:c语言合法标识符有哪些 编辑:程序博客网 时间:2024/05/21 22:56

本文同时参考了吴恩达课程的编程作业与TensorFlow的官方入门指南。

基本

下载安装啥的就略过了:

import tensorflow as tf

常量

考虑以下代码:

a = tf.constant(2)b = tf.constant(10)c = tf.multiply(a,b)print(a,b,c)

输出为:

TensorFlow中的核心数据单元为tensor(上述代码中的a,b,c),一个tensor中包含了一系列被格式化为任意维度矩阵的数值(上述代码中没有指定shape参数)。

可以把TensorFlow核心编程看成两部分:

  • 构建computational graph

  • 运行computational graph

computational graph是一系列节点之间的操作,每个节点操作都接受零个或多个tensor作为参数,然后输出一个tensor。constant就是一种节点,它不接受输入,只输出其内部存储的值。

可以看到上述代码并没有输出预期值20,这是因为节点没有被赋值。为了给节点赋值,需要在一个session中运行computational graph。具体看下面代码:

sess = tf.Session()print(sess.run([a,b,c]))sess.close()

输出:

回想一下UE4中的蓝图系统,可以把a,b,c均看成是蓝图中的节点,其中a,b是输出固定值的变量节点,c是一个乘法节点,它接受两个参数并输出两者之积。下图是官方入门指南中给出的TensorBoard加法器截图:

变量

placeholder

TensorFlow中能够接受外部输入的图被称为placeholder,一个placeholder允许稍后赋值。

a = tf.placeholder(tf.float32)b = tf.placeholder(tf.float32)adder_node = a + b

如果需要对placeholder进行赋值,需要在sess.run()里的feed_dict字段赋值:

sess=tf.Session()print(sess.run(adder_node, {a: 3, b: 4.5}))print(sess.run(adder_node, {a: [1, 3], b: [2, 4]}))sess.close()

输出:

其在TensorBoard中的图如下图所示:

Variable

Variable是具有指定格式与初始值的变量,常被用于指代图的训练参数权重W与偏差b。考虑以下代码:

W = tf.Variable([.3], dtype=tf.float32)b = tf.Variable([-.3], dtype=tf.float32)x = tf.placeholder(tf.float32)linear_model = W * x + b

与placeholder一样,Variable在声明阶段并不会被初始化,要对Variable赋初值,需要执行tf.global_variables_initializer()方法:

init=tf.global_variables_initializer()sess=tf.Session()sess.run(init)print(sess.run([W,b]))sess.close()

需要注意,此处的init也是TensorFlow中的一个图,再调用sess.run(init)之前Variable是不会被赋初值的。

既然x是一个placeholder,给定一系列x值就能计算线性模型的输出了:

init=tf.global_variables_initializer()sess=tf.Session()sess.run(init)print(sess.run(linear_model,{x:[1,2,3,4]}))sess.close()

placeholder与Variable的区别

Variable能够存储变量值;
placeholder只能在运行Session时进行赋值,而Variable能够通过调用tf.assign()方法进行重赋值;
可以看出placeholder更像是函数所接受的参数,而可以把Variable看成是普通变量。


简单模型

为了评估线性模型,还需要一组标签值来计算模型相对于标签的损失:

W = tf.Variable([.3], dtype=tf.float32)b = tf.Variable([-.3], dtype=tf.float32)x = tf.placeholder(tf.float32)linear_model = W * x + by=tf.placeholder(tf.float32)squared_deltas=tf.square(linear_model-y)loss=tf.reduce_sum(squared_deltas)init=tf.global_variables_initializer()sess=tf.Session()sess.run(init)print(sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))sess.close()

为了使模型表现更好,很容易观察到这个简单模型的一组最优参数为W=-1,b=1。手动对参数进行重赋值使得模型损失最小,加入以下代码:

...fixW = tf.assign(W, [-1.])fixb = tf.assign(b, [1.])...sess.run([fixW, fixb])...

tf.train API

对于机器学习,最简单的优化算法就是梯度下降,TensorFlow中提供了能够改变每个参数以缓慢降低损失的optimizers

import tensorflow as tfW = tf.Variable([.3], dtype=tf.float32)b = tf.Variable([-.3], dtype=tf.float32)x = tf.placeholder(tf.float32)linear_model = W * x + by=tf.placeholder(tf.float32)loss=tf.reduce_sum(tf.square(linear_model-y))optimizer=tf.train.GradientDescentOptimizer(0.01)train=optimizer.minimize(loss)x_train=[1,2,3,4]y_train=[0,-1,-2,-3]init=tf.global_variables_initializer()sess=tf.Session()sess.run(init)for i in range(1000):    sess.run(train,{x:x_train,y:y_train})cur_W,cur_b,cur_loss=sess.run([W,b,loss],{x:x_train,y:y_train})print("W:{}\tb:{}\tloss:{}".format(cur_W,cur_b,cur_loss))sess.close()


可以看到优化器在1000次迭代之后计算得到的值已非常接近最优解了。

tf.estimator

tf.estimator是TensorFlow中的高级库,它能够简化很多机器学习中的机制:

  • 训练迭代

  • 测试迭代

  • 管理数据集

tf.estimator中还定义了许多常见模型。

基本用法

官方指南给出了一份线性回归模型的代码示例:

import tensorflow as tf# NumPy is often used to load, manipulate and preprocess data.import numpy as np# Declare list of features. We only have one numeric feature. There are many# other types of columns that are more complicated and useful.feature_columns = [tf.feature_column.numeric_column("x", shape=[1])]# An estimator is the front end to invoke training (fitting) and evaluation# (inference). There are many predefined types like linear regression,# linear classification, and many neural network classifiers and regressors.# The following code provides an estimator that does linear regression.estimator = tf.estimator.LinearRegressor(feature_columns=feature_columns)# TensorFlow provides many helper methods to read and set up data sets.# Here we use two data sets: one for training and one for evaluation# We have to tell the function how many batches# of data (num_epochs) we want and how big each batch should be.x_train = np.array([1., 2., 3., 4.])y_train = np.array([0., -1., -2., -3.])x_eval = np.array([2., 5., 8., 1.])y_eval = np.array([-1.01, -4.1, -7, 0.])input_fn = tf.estimator.inputs.numpy_input_fn(    {"x": x_train}, y_train, batch_size=4, num_epochs=None, shuffle=True)train_input_fn = tf.estimator.inputs.numpy_input_fn(    {"x": x_train}, y_train, batch_size=4, num_epochs=1000, shuffle=False)eval_input_fn = tf.estimator.inputs.numpy_input_fn(    {"x": x_eval}, y_eval, batch_size=4, num_epochs=1000, shuffle=False)# We can invoke 1000 training steps by invoking the  method and passing the# training data set.estimator.train(input_fn=input_fn, steps=1000)# Here we evaluate how well our model did.train_metrics = estimator.evaluate(input_fn=train_input_fn)eval_metrics = estimator.evaluate(input_fn=eval_input_fn)print("train metrics: %r"% train_metrics)print("eval metrics: %r"% eval_metrics)

  • epochs指整个训练集对模型训练的次数,它的意义跟iteration不完全一样,iteration指的是迭代次数。回顾前文,当使用mini-batch梯度下降法时,整个训练集被分成了很多个batches,这种情况下iteration是要大于epoch的。

  • 示例代码中的batch_size=m,相当于普通的梯度下降法。

  • 整个训练过程(正向传播/反向传播)均包含在.train()方法中;而模型的评估(损失)包含在.evaluate()方法中。

自定义模型

为了创建自定义模型,需要用到tf.estimator.Estimator,上面的tf.estimator.LinearRegressor实际上是tf.estimator.Estimator的子类,通过给tf.estimator.Estimatormodel_fn参数传值即可:

import numpy as npimport tensorflow as tf# Declare list of features, we only have one real-valued featuredef model_fn(features, labels, mode):  # Build a linear model and predict values  W = tf.get_variable("W", [1], dtype=tf.float64)  b = tf.get_variable("b", [1], dtype=tf.float64)  y = W * features['x'] + b  # Loss sub-graph  loss = tf.reduce_sum(tf.square(y - labels))  # Training sub-graph  global_step = tf.train.get_global_step()  optimizer = tf.train.GradientDescentOptimizer(0.01)  train = tf.group(optimizer.minimize(loss),                   tf.assign_add(global_step, 1))  # EstimatorSpec connects subgraphs we built to the  # appropriate functionality.  return tf.estimator.EstimatorSpec(      mode=mode,      predictions=y,      loss=loss,      train_op=train)estimator = tf.estimator.Estimator(model_fn=model_fn)# define our data setsx_train = np.array([1., 2., 3., 4.])y_train = np.array([0., -1., -2., -3.])x_eval = np.array([2., 5., 8., 1.])y_eval = np.array([-1.01, -4.1, -7, 0.])input_fn = tf.estimator.inputs.numpy_input_fn(    {"x": x_train}, y_train, batch_size=4, num_epochs=None, shuffle=True)train_input_fn = tf.estimator.inputs.numpy_input_fn(    {"x": x_train}, y_train, batch_size=4, num_epochs=1000, shuffle=False)eval_input_fn = tf.estimator.inputs.numpy_input_fn(    {"x": x_eval}, y_eval, batch_size=4, num_epochs=1000, shuffle=False)# trainestimator.train(input_fn=input_fn, steps=1000)# Here we evaluate how well our model did.train_metrics = estimator.evaluate(input_fn=train_input_fn)eval_metrics = estimator.evaluate(input_fn=eval_input_fn)print("train metrics: %r"% train_metrics)print("eval metrics: %r"% eval_metrics)

  • .get_variable().Variable()的区别:.Variable()方法一定会创建一个新对象,若对象名已存在则自动重命名;.get_variable()创建对象前会判断是否存在同名对象,一般用于变量共享。建议使用.get_variable()
原创粉丝点击