TensorFlow学习_note2

来源:互联网 发布:管碧玲 知乎 编辑:程序博客网 时间:2024/06/11 05:59

本文是tensorflow学习的第二篇笔记,内容接上一篇笔记

6.pyplot——python作图工具

本例中使用matplotlib的交互模式进行动态更新图片,显示数据变化情况。

  • pyplot.figure():见代码

  • pyplot.figure().add_subplot():见代码

  • pyplot.ion():开启matplotlib的交互模式。此时python解释器解释完所有命令后出张图,但不会结束会话,如果你继续往代码中加入语句,run之后,你会实时看到图形的改变。当绘图语句中加入plt.ioff()时或不添加plt.ion()时,表示关了交互模式。此时要加入plt.show()才能显示图片。python解释器解释完所有命令后出张图,同时结束会话。如果你继续往代码中加入语句,再不会起作用。

  • plt.pause():绘制完暂停指定的时间。参数为暂停的秒数,接受float型。
import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt  #python绘图工具包def add_layer(A_prev,n_prev,n,activation_function = None):    #initialize parameters    W = tf.Variable(tf.random_normal([n,n_prev]))    b = tf.Variable(tf.zeros([n,1])+0.1)    #forward propagation     Z = tf.matmul(W,A_prev) + b    if activation_function == None:        A = Z    else:        A = activation_function(Z)    return A#create data#X.shape=Y.shape=Noise.shape=(1,300)X = np.linspace(-1,1,300)[np.newaxis,:]Noise = np.random.normal(0,0.05,X.shape)Y = X**2-0.5+Noise#placeholderXs = tf.placeholder(tf.float32,[1,None])Ys = tf.placeholder(tf.float32,[1,None])#propagationlayer1_out = add_layer(Xs,1,10,tf.nn.relu)prediction = add_layer(layer1_out,10,1)loss = tf.reduce_mean((Ys-prediction)**2)#train steptrain = tf.train.GradientDescentOptimizer(0.1).minimize(loss)#start optimizesess = tf.Session()init = tf.global_variables_initializer()sess.run(init)#plot settingfig = plt.figure()   #用figure()函数画图ax = fig.add_subplot(1,1,1)   #向fig中添加一张子图,3个参数表示一共有1x1张子图,ax是第1张子图ax.scatter(X,Y)      #先看看数据的分布。根据X,Y绘制散点图plt.ion()            #开启交互模式for i in range(1000):    #训练一次网络    sess.run(train,feed_dict={Xs:X,Ys:Y})    if i % 50 == 0:        #用remove方法抹去刚画的那条lines,保证图像中时刻只有一条线        #由于第一次还没定义lines,所以要做异常处理        try:            ax.lines.remove(lines[0])        except Exception:            pass        #获取预测值        prediction_value = sess.run(prediction,feed_dict={Xs:X})        #根据X和预测值绘制连续曲线lines,红色,宽度=5        lines = ax.plot(X.reshape(300), prediction_value.reshape(300), 'r-', lw=5)        plt.pause(0.2)  #暂停0.2s

结果类似下图:

图1

7.tensorboard——神经网络可视化

tensorflow提供一个可视化工具——tensorboard。通过使用这个工具我们可以很直观的看到整个神经网络的结构、框架和一些变量的变化情况。

(1)网络结构可视化

tf.name_scope()对各个层次、变量进行名字域封装,方便tensorboard构建网络框架图。

在之前双层神经网络的基础上做以下修改:

  • 定义各个层的name scope

  • 使用 tf.summary.FileWriter("log/",sess.graph) 将之前的绘图收集并保存到指定目录log/

  • 打开terminal进入log的父目录,输入tensorboard --logdir=logs/

    运行后结果:

    图2

  • copy上面的地址到浏览器打开查看结果(见下方)

(2)变量可视化

  • tf.histogram_summary() 方法记录tensorflow变量信息
  • tf.summary.scalar() 方法记录loss
  • 合并打包:tf.summary.merge_all() 方法将所有的 summaries合并到一起
  • 以上这些仅仅可以记录很绘制出训练的图表, 但是不会记录训练的数据。训练过程中使用writer.add_summary() 记录训练过程中每个参数的变化(filewriter定义见上)
  • 同上打开terminal输入命令,打开浏览器查看结果
import tensorflow as tfimport numpy as npdef add_layer(A_prev,n_prev,n,n_layer,activation_function = None):    #initialize parameters    layer_name = 'layer%s'%n_layer  #第几层    with tf.name_scope('layer'):  #定义隐层的name scope        with tf.name_scope('weights'):   #定义W的name scope            W = tf.Variable(tf.random_normal([n,n_prev]),name = 'W')            #用histogram()函数添加要记录的变量            #histogram()函数第一个参数是图表的名称, 第二个参数是图表要记录的变量            tf.summary.histogram(layer_name+'/weights',W)        with tf.name_scope('biases'):            b = tf.Variable(tf.zeros([n,1])+0.1,name = 'b')            #同上            tf.summary.histogram(layer_name+'/biases',b)        #forward propagation        with tf.name_scope('Z'):            Z = tf.matmul(W,A_prev) + b        if activation_function == None:            A = Z        else:            A = activation_function(Z)        #同上,记录A的值        tf.summary.histogram(layer_name+'/A',A)        return A#create data#X.shape=Y.shape=Noise.shape=(1,300)X = np.linspace(-1,1,300)[np.newaxis,:]Noise = np.random.normal(0,0.05,X.shape)Y = X**2-0.5+Noise#placeholder'''使用with tf.name_scope('inputs')可以将Xs和Ys包含进来,形成一个大的图层,图层的名字就是 with tf.name_scope()方法里的参数'''with tf.name_scope('inputs'):    #这里指定的name将来会在可视化的图层inputs中显示出来    Xs = tf.placeholder(tf.float32,[1,None],name = 'x_input')    Ys = tf.placeholder(tf.float32,[1,None],name = 'y_input')#propagationlayer1_out = add_layer(Xs,1,10,1,tf.nn.relu)prediction = add_layer(layer1_out,10,1,2)with tf.name_scope('loss'):   #loss作同样处理    loss = tf.reduce_mean((Ys-prediction)**2)    #scalar方法记录loss    tf.summary.scalar('loss',loss)#train stepwith tf.name_scope('train'):   #train作同样处理    train = tf.train.GradientDescentOptimizer(0.1).minimize(loss)#start optimizesess = tf.Session()merged = tf.summary.merge_all() #合并所有summarywriter = tf.summary.FileWriter("log/",sess.graph)  #定义writer,这一步要定义在session开启后init = tf.global_variables_initializer()sess.run(init)for i in range(1000):    sess.run(train,feed_dict={Xs:X,Ys:Y})    if i%50 == 0:        #merge需要run才有效,run时需喂入相关data        result = sess.run(merged,feed_dict={Xs:X,Ys:Y})        writer.add_summary(result,i)#记录训练后变量的结果

图3

图4

8.softmax——多分类预测激活函数

多分类问题的输出不是一个值,而是一个向量。softmax激活函数可以将输入映射为一个概率向量(属于每个分类的可能性)。例子中使用MNIST手写图片集作为训练样本。网络结构是这样的:

图6

import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_data #数据集#read in datamnist = input_data.read_data_sets("MNIST_data/", one_hot=True) #one_hot参数表示如果还没下载数据先下载def add_layer(A_prev,n_prev,n,activation_function = None):    #initialize parameters    W = tf.Variable(tf.random_normal([n,n_prev]))    b = tf.Variable(tf.zeros([n,1])+0.1)    #forward propagation     Z = tf.matmul(W,A_prev) + b    if activation_function == None:        A = Z    else:        #这里有个问题,Z必须先转置才能作为softmax的参数        #因为tf.nnsoftmax处理的矩阵是这样的shape=(样本数,每个样本特征长度)        A = activation_function(tf.transpose(Z))        A = tf.transpose(A)    return A#计算准确率的函数def compute_accuracy(X_test,Y_test):    #要声明prediction为全局变量,因为是外部定义的    global prediction    pre = prediction  #获取prediction    #预测准确分布    #tf.argmax(X,axis)就是求X矩阵在axis维度最大值的index    #tf.equal(A,B)求A,B矩阵每个元素是否相等,等于的位置取ture,否则取false    correct_pre = tf.equal(tf.argmax(pre,0),tf.argmax(Y_test,0))    #统计准确率    #tf.cast()表示将矩阵映射为某一dtype    accuracy = tf.reduce_mean(tf.cast(correct_pre,tf.float32))    result = sess.run(accuracy,feed_dict={Xs:X_test})    return result#placeholderXs = tf.placeholder(tf.float32,[784,None])Ys = tf.placeholder(tf.float32,[10,None])#add output layer#使用softmax进行多分类预测prediction = add_layer(Xs,784,10,tf.nn.softmax)#loss定义为prediction和labels的交叉熵loss = tf.reduce_mean(-tf.reduce_sum(Ys*tf.log(prediction),0))#train steptrain = tf.train.GradientDescentOptimizer(0.5).minimize(loss)#start sessionsess = tf.Session()sess.run(tf.global_variables_initializer())#trainfor i in range(1000):    batch_X,batch_Y = mnist.train.next_batch(100) #每次取100个训练集    sess.run(train,feed_dict={Xs:batch_X.T,Ys:batch_Y.T})      if i%100 == 0:        #每100step输出准确率        print(compute_accuracy(mnist.test.images.T,mnist.test.labels.T))

图5

可以看到准确率不断提升

9.dropot——解决overfitting的问题

  • step1:define keep_prob placeholder
  • step2:train step时引入keep_prob参数(feed_dict的方式)
  • step3:具体的dropout是Z =
    tf.nn.dropout(Z,keep_prob)
    这一步,意思是随机保留keep_prob的结果(其余置0)
import tensorflow as tf#从sklearn库import数据集from sklearn.datasets import load_digits #data setfrom sklearn.model_selection import train_test_split #切割数据集为训练集和测试集from sklearn.preprocessing import LabelBinarizerdef add_layer(A_prev,n_prev,n,layer_name,activation_function = None):    #initialize parameters    W = tf.Variable(tf.random_normal([n,n_prev]))    b = tf.Variable(tf.zeros([n,1])+0.1)    #forward propagation     Z = tf.matmul(W,A_prev) + b    #dropout step    #保留keep_prob的结果    Z = tf.nn.dropout(Z,keep_prob)    if activation_function == None:        A = Z    else:        A = activation_function(tf.transpose(Z))        A = tf.transpose(A)    tf.summary.histogram(layer_name+'/outputs',A)    return A#import data#这个数据集是手写数字集,样本labels是0-9这10个数字digits = load_digits()X = digits.data  #X=特征数据y = digits.target  #y=样本标签y = LabelBinarizer().fit_transform(y) #标签二值化,每个标签值转化成0/1表示的向量#split data set into train and test#test set占0.3的比例X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.3)#placeholderXs = tf.placeholder(tf.float32,[64,None]) #输入特征维度64Ys = tf.placeholder(tf.float32,[10,None]) #输出维度10#define placeholder for dropout keep_prob = tf.placeholder(tf.float32)#propagationlayer1_out = add_layer(Xs,64,50,'L1',tf.nn.tanh)prediction = add_layer(layer1_out,50,10,'L2',tf.nn.softmax)#define lossloss = tf.reduce_mean(-tf.reduce_sum(Ys*tf.log(prediction),reduction_indices=[0]))#记录losstf.summary.scalar('loss',loss)#train steptrain = tf.train.GradientDescentOptimizer(0.6).minimize(loss)#start Sessionsess = tf.Session()#summary writer goes in heremerged = tf.summary.merge_all()#record results of train set and test set#使用两个writer记录训练集和测试集的losstrain_writer = tf.summary.FileWriter("log/train",sess.graph)test_writer = tf.summary.FileWriter("log/test",sess.graph)#initialize variablesinit = tf.global_variables_initializer()sess.run(init)#train and recordfor i in range(500):    #train with train set data    #置信度keep_prob为0.5    sess.run(train,feed_dict={Xs:X_train.T,Ys:y_train.T,keep_prob:0.5})    #record every 50 steps    if i % 50 == 0:        #记录 train set的loss        train_result = sess.run(merged,feed_dict={Xs:X_train.T,Ys:y_train.T,keep_prob:1})        #记录 test set的loss        test_result = sess.run(merged,feed_dict={Xs:X_test.T,Ys:y_test.T,keep_prob:1})        train_writer.add_summary(train_result,i)        test_writer.add_summary(test_result,i)

未dropout:

图7

dropout后:

图8

可以看到overfitting情况减轻得很明显

10.tf.train.Saver()——保存读取tensorflow变量

tensorflow提供保存变量读取变量的方法,方便重新构建网络时不用再训练,或是将变量给下一层网络使用时调用。

  • Variable初始化时需要指定变量的name
  • tf.train.Saver() :创建一个saver
  • saver.save(sess,"my_net/save_net.ckpt") :将各变量存入指定目录的.ckpt文件中
  • 读取:定义相同的shape和dtype的Variable
  • 同样define一个saver
  • saver.restore(sess,"my_net/save_net.ckpt") :从刚才的文件中读取变量
#tensorflow只能保存变量,下次构建时可以导入使用,神经网络框架需要重新定义import tensorflow as tf#save##########################这部分是save,先去掉注释运行后,再注释掉,运行后面的restore部分代码##W = tf.Variable([[1,2,3],[4,5,6]],dtype=tf.float32,name="weights")##b = tf.Variable([[6,6,6]],dtype=tf.float32,name="biases")#####define saver##saver = tf.train.Saver()##with tf.Session() as sess:##    sess.run(tf.global_variables_initializer())##    #保存路径,保存为后缀为ckpt的文件##    #save()返回值为保存路径##    #第一个参数sess意思是保存当前会话的graph和variables##    save_path = saver.save(sess,"my_net/save_net.ckpt")####    print("Save to path:",save_path)#restore#######################读取数据的时候需要定义相同的shape和dtype的VariableW = tf.Variable(tf.zeros([2,3]),tf.float32,name="weights")b = tf.Variable(tf.zeros([1,3]),tf.float32,name="biases")#这里不需要init variables#也是define一个saversaver = tf.train.Saver()with tf.Session() as sess:    #saver.restore导入变量    saver.restore(sess,"my_net/save_net.ckpt")    print("W:",sess.run(W))    print("b:",sess.run(b))

保存:

图9

读取:

图10

11.LSTM网络分类例子

LSTM(Long Short-term Memory)是一个RNN模型,tensorflow提供了构建lstm的API,可以直接使用。本例对MNIST手写图片集进行分类。

  • 确定网络结构:input==>hidden layer1(in layer)==>LSTM layer==>hidden layer2(out layer)==>output
  • 定义超参数
  • 定义placeholder for input和output
  • 参数初始化:in layer,out layer的W,b
  • 定义RNN结构
  • 定义loss,train step,准确率
  • 训练
#让RNN从每张图片的第一行像素读到最后一行, 然后再进行分类判断#data流动方向如下#data==>input==>input hidden layer==>lstm cell==>output hidden layer==>outputimport tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_data# 导入数据#MNIST手写图片集mnist = input_data.read_data_sets('MNIST_data', one_hot=True)#define 超参数lr = 0.001  #learning rate要尽量小,避免梯度爆炸问题training_iters = 100000  #训练迭代次数batch_size = 100  #每次取训练样本数n_input = 28  # MNIST data input(img shape:28*28)n_step = 28   # 时序持续长度为28,即每做一次预测,需要先输入28行,也就是一张图片的行数n_hidden_unit = 100  #输入输出隐层单元数n_lstm_hidden_unit = 128  #lstm层单元数n_class = 10  #分类的种类数,MNIST是手写数字集(0-9),有10种类别#placeholder for input,outputX = tf.placeholder(tf.float32,[None,n_step,n_input])Y = tf.placeholder(tf.float32,[None,n_class])#initialize weight bias#in(输入) out(输出)层的参数W = {    #shape(输入维度,隐层单元数)    'in':tf.Variable(tf.random_normal([n_input,n_hidden_unit])),    #shape(lstm隐层单元数,输出类别数)    'out':tf.Variable(tf.zeros([n_lstm_hidden_unit,n_class]))}b = {    #shape(1,隐层单元数)    'in':tf.Variable(tf.zeros([1,n_hidden_unit])),    #shape(1,输出类别数)    'out':tf.Variable(tf.zeros([1,n_class]))}#define function for LSTMdef RNN(X, W, b):    #input layer#######################################################    #shape:(batch_size,n_row,n_col)==>(batch_size*n_row,n_col)    X = tf.reshape(X,[-1,n_input])    #输入的input样本先经过一个linear hidden layer    #X_in.shape=(batch_size*n_row,n_hidden_unit)    X_in = tf.matmul(X,W['in'])+b['in']    #chage shape for lstm cell    X_in = tf.reshape(X_in,[-1,n_step,n_hidden_unit])    #rnn layer##########################################################    #定义一层LSTM_cell只需要说明 hidden_size,它会自动匹配输入的 X 的维度    #这步构建了一个hidden units数目指定的lstm cell    #BasicLSTMCell()有几个默认参数,见官方api    #state_is_tuple:该参数默认为True,此时输入和输出的states为c(cell状态)和h(输出)的二元组    lstm_cell = tf.contrib.rnn.BasicLSTMCell(n_lstm_hidden_unit)    #用全零来初始化lstm cell的state    #init_state.shape=(batch_size*state_size),state_size就是lstm隐层单元数    init_state = lstm_cell.zero_state(batch_size,dtype=tf.float32)    #调用dynamic_rnn()来让我们构建好的网络运行起来    # dynamic_rnn receive Tensor (batch, steps, inputs) or (steps, batch, inputs) as X_in    # outputs就是n_step步里所有的输出,shape=(batch_size, n_step, output_size)    # state是最后一步的隐状态,shape=(batch_size, state_size)    #time_major默认=False,表示X_in的shape是(batch, steps, inputs) 这样的    output,final_state = tf.nn.dynamic_rnn\        (lstm_cell,X_in,initial_state=init_state,time_major=False)    #output layer#######################################################    #final_state[1]即h(输出),shape=(batch_size,output_size)    result = tf.matmul(final_state[1], W['out']) + b['out']    return resultpred = RNN(X,W,b)#tf.nn.softmax_cross_entropy_with_logits()函数:将pred做一个softmax处理,然后与labels求交叉熵loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y,logits=pred))#train step 这里使用AdamOptimizertrain = tf.train.AdamOptimizer(lr).minimize(loss)#准确率correct = tf.equal(tf.argmax(pred,1),tf.argmax(Y,1))accuracy = tf.reduce_mean(tf.cast(correct,tf.float32))sess = tf.Session()sess.run(tf.global_variables_initializer())step = 0while step*batch_size < training_iters:  #训练10W张图片,训练1000次    batch_X, batch_Y = mnist.train.next_batch(batch_size)  #每次训练取100张图片    batch_X = batch_X.reshape([batch_size, n_step, n_input])    sess.run(train,feed_dict={X: batch_X, Y: batch_Y})    if step % 100 == 0:        print(sess.run(accuracy,feed_dict={X:batch_X,Y:batch_Y}))    step += 1

图

原创粉丝点击