2017-03-11 杭州 阴
tensorflow是谷歌发起并开源的一个深度学习 框架,除了搭建神经网络之外还整合了类似scikit-learn的机器学习API。该框架 使用数据流图(data flow graph)来组织神经网络,比较直观,易于上手;并且支 持从云平台到嵌入式设备的多种硬件平台。下面罗列了一些比较重要的特征。
支持windows、linux、mac os 以及android支持python、c++、java等API接口有if while等流程控制tensorboard工具将网络图可视化,绘制训练过程中的loss曲线等
CUDA Toolkit 是NVIDIA的GPU计算平台,大概1G多。下载、安装完成后,在_C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin_下执行nvcc -V,查看版本信息。接着打开_C:\ProgramData\NVIDIA Corporation\CUDA Samples\v8.0\1_Utilities\deviceQuery_下的VS工程,切换到Release模式下,编译, 得到deviceQuery.exe(在C:\ProgramData\NVIDIA Corporation\CUDA Samples\v8.0\bin\win64\Release 目录下)。在控制台下执行deviceQuery.exe,如果结果为pass,那么CUDA Toolkit就算安装成功了。 在CUDA Samples文件夹下还有其他的示例工程,也可以编译完运行看看效果,具体介绍参考 NVIDIA的官方介绍。
cuDNN是NVIDIA的深度神经网络库,其实就是一个很朴实的 API包,下载下来就三个文件.dll、.h和.lib,大小60多M。下载完解压.dll文件所在的目录添加大path环 境变量即可。
安装gpu版,使用下面的命令
pip3 install --upgrade tensorflow-gpu写一个python脚本运行一下
import tensorflow as tf hello = tf.constant('Hello, TensorFlow!') sess = tf.Session() print(sess.run(hello))注意 默认情况下,tensorflow会输出所有的日志信息,可用下面的方法过滤不必要的信息
import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'TF_CPP_MIN_LOG_LEVEL的取值可以是’0’,’1’,’2’,’3’,对应的功能如下 - ‘0’:显示所有的日志信息 - ‘1’:过滤掉’INFO’日志 - ‘2’:过滤掉’WARNING’日志 - ‘3’:过滤掉’ERROR’日志
搭建一个一维的线性回归网络,代码如下
import numpy as np import tensorflow as tf # 一维线性模型y = W*x + b # W初始值为0.3,b的初始值是-0.3 W = tf.Variable([.3], tf.float32) b = tf.Variable([-.3], tf.float32) # 输入训练样本 x = tf.placeholder(tf.float32) y = tf.placeholder(tf.float32) # 搭建模型 linear_model = W * x + b # 定义损失函数 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] # 初始化模型参数,即W和b 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}) # 输出训练结果 curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x:x_train, y:y_train}) print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))tensor是tensorflow组织数据的基本单位,可以看做是多维的数组,一般情况下是二维的矩阵 下面看一下Python中的数组与tensor之间的对应关系
3 # 标量,shape属性是[] [1. ,2., 3.] # 向量,shape属性是[3] [[1., 2., 3.], [4., 5., 6.]] # 矩阵,shape属性是[2, 3] [[[1., 2., 3.]], [[7., 8., 9.]]] # 高维数组,shape属性是[2, 1, 3]是tensor的一种,用于从外部输入数据。使用的格式如下
#待输入的样本,样本是2维的,None表示样本的数量根据输入自行确定 X = tf.placeholder(tf.float32, [None, 2]) #待输入的标签数据,一位的,None表示标签的数量根据输入自行确定 y_true = tf.placeholder(tf.float32, [None])也是一种tensor,用于存储训练过程中的参数,维数是固定的,使用方法如下
#使用的是2行10列的矩阵 hidden_weight = tf.Variable(tf.random_normal([2, 10])) hidden_bias = tf.Variable(tf.random_normal([10]))特别提醒 一定要用随机数初始化Variable,如果全部初始化为0,训练后很可能 得到的都是NaN。
用来运行tensor,并返回tensor的运行结果。在Session运行tensor之前,关于tensor的操作都是定义 网络结构,并没有执行(包括前面定义Variable的random_normal操作)。
sess = tf.Session() sess.run(tf.global_variables_initializer()) los = sess.run(loss, feed_dict={X:X_data, y_true:y_data})有两个地方需要注意;第一,在运行定义好的网络结构之前,要初始化所有的Variable(也就是第二行 代码),没有初始值,网络是无法运行的;第二,网络中有输入值,应当通过feed_dict这个参数传 入。运行网络后,返回运算结果los。
也就是神经网络中的激活函数,定义在tf.nn 模块中,包含了常用的激活函数,比如relu、softmax和sigmoid,用法也很简单。
layer1 = tf.nn.relu(tf.matmul(X, hidden_weight) + hidden_bias)用于求解神经网络,在tf.train模块。一般 使用GradientDescentOptimizer 也就是梯度下降算法。用法如下。
#传入的参数是学习速率 opt = tf.train.GradientDescentOptimizer(0.01) #train传入sess.run,即可得到loss值 train = opt.minimize(loss)tensorboard通过读取tensorflow的日志输出来可视化网络结构和训练过程中的 loss曲线的。运行命令tensorboard.exe –logdir=../temp/tflog,然后打开 浏览器,输入http://localhost:6006/即可查看。
要想看到上图的效果,在代码中还要注意两个地方。
第一,给想要查看的tensor节点添加summary。
loss = tf.reduce_mean(loss_all) #记录loss的输出 tf.summary.scalar('loss', loss) #... #添加的所有summary聚合成一个操作 #便于后面用Sessiong运行 merge_sum = tf.summary.merge_all() #... #指定summary保存的文件夹 train_writer = tf.summary.FileWriter('../temp/tf_log', sess.graph) #... for k in range(100): #运行summay并保存 ms, _, los = sess.run([merge_sum, train, loss], feed_dict={X:X_data, y_true:y_data}) train_writer.add_summary(ms, k)第二,把网络节点组合起来,方便查看网络图。如下面的代码所示, 将相似的操作组合在同一个name scope下,查看网络图的时候,是以name scope的视图观看的,如果想看某个name scope下的具体操作,点击展开即可, 十分方便。
with tf.name_scope('Input'): X = tf.placeholder(tf.float32, [None, nFeature]) y_true = tf.placeholder(tf.float32, [None, nLabel]) with tf.name_scope('Hidden'): hidden_weight = tf.Variable(tf.random_normal([nFeature, nHidden])) hidden_bias = tf.Variable(tf.random_normal([nHidden])) layer1 = tf.nn.relu(tf.matmul(X, hidden_weight) + hidden_bias)目前还没找到连同网络结构一起保存的方法,只能用于保存训练好的参数。 保存的方法很简单,代码如下
saver = tf.train.Saver() #会在temp文件夹下生成nn_model.meta、 #nn_model.index和nn_model.data-00000-of-00001 #三个文件 saver.save(sess, '../temp/nn_model')加载保存下来的参数
saver = tf.train.Saver() #这里就相当于把前面定义的模型的参数 #初始化了 saver.restore(sess, '../temp/nn_model') #注意这里的loss、X和y_true都是前面代码定义好的 #并非从保存的数据中恢复得到。 print(sess.run(loss, feed_dict={X:X_data, y_true:y_data}))下面是一个三层的神经网络,42维特征,14维标签,隐含层有10个神经元。
import tensorflow as tf import pandas as pd import numpy as np import os def load(): feature = pd.read_csv('../temp/test_features.csv', dtype=np.float) label = pd.read_csv('../temp/test_labels.csv', dtype=np.float) return (feature.values, label.values) def main(): nFeature = 42 nLabel = 14 nHidden = 10 X_data, y_data = load() with tf.name_scope('Input'): X = tf.placeholder(tf.float32, [None, nFeature]) y_true = tf.placeholder(tf.float32, [None, nLabel]) with tf.name_scope('Hidden'): hidden_weight = tf.Variable(tf.random_normal([nFeature, nHidden])) hidden_bias = tf.Variable(tf.random_normal([nHidden])) layer1 = tf.nn.relu(tf.matmul(X, hidden_weight) + hidden_bias) with tf.name_scope('Output'): #注意用随机数初始化参数 output_weight = tf.Variable(tf.random_normal([nHidden, nLabel])) output_bias = tf.Variable(tf.random_normal([nLabel])) layer2 = tf.nn.relu(tf.matmul(layer1, output_weight) + output_bias) with tf.name_scope('Loss'): abs_sub = tf.abs(layer2 - y_true) abs_add = tf.abs(layer2 + y_true) loss_nan = tf.truediv(abs_sub, abs_add) #生成和loss_all一样大小的tensor zeros = tf.matmul(X, tf.zeros([nFeature, nLabel])) #因为前面有除法操作,用于去除生成的NaN数据 loss_all = tf.where(tf.is_nan(loss_nan), zeros, loss_nan) loss = tf.reduce_mean(loss_all) tf.summary.scalar('loss', loss) opt = tf.train.GradientDescentOptimizer(0.01) train = opt.minimize(loss) merge_sum = tf.summary.merge_all() with tf.Session() as sess: #训练过程可视化 if os.path.exists('../temp/nn_model.meta'): saver = tf.train.Saver() saver.restore(sess, '../temp/nn_model') print(sess.run(loss, feed_dict={X:X_data, y_true:y_data})) return train_writer = tf.summary.FileWriter('../temp/tf_log', sess.graph) sess.run(tf.global_variables_initializer()) for k in range(100): ms, _, los = sess.run([merge_sum, train, loss], feed_dict={X:X_data, y_true:y_data}) train_writer.add_summary(ms, k) print(los) if los < 0.09: break saver = tf.train.Saver() saver.save(sess, '../temp/nn_model') # if __name__ == '__main__': os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' main()矩阵运算、流程控制等,后续会慢慢添加
转自本人的gitbook书籍里的部分章节。