美文网首页深度学习
tensorflow一文完全解答(改)

tensorflow一文完全解答(改)

作者: horsetif | 来源:发表于2018-06-30 20:15 被阅读0次

    这篇文章是针对有tensorflow基础但是记不住复杂变量函数的读者,文章列举了从输入变量到前向传播,反向优化,数据增强保存,GPU并行计算等常用的指令,希望通过这一篇来完成整体网络的参考实现。

    最后建议写一个模板化的训练流程,以后改网络就可以只修改其中一小部分。-horsetif

    1,输入端:

    get_variable 和 Variable

    #初始化 1,get_variable,必须指定变量名称参数
    
    tf.get_variable(name,shape=[1],initializer=xxx)
    
    #初始化 2,Variable,不必要指定变量名称参数
    
    tf.Variable(tf.xxx(a,shape=[]),name)
    
    tf.Variable(0,dtype=tf.float32,name)
    
    #变量后缀
    
    constant,random_normal,truncated_normal,random_uniform,zeros,ones.
    

    命名空间

    ##############定义命名空间#####################这样对调试很有用
    
    with tf.variable_scope('foo'):
    
        a=tf.get_variable('bar',[1])#受到命名空间影响
    
    with tf.name_scope('a'):
    
        a=tf.Variable([1])#受到命名空间影响
    
        b=tf.get_variable('b',[1])#不受命名空间影响
    

    计算图

    #graph###############################################
    
    #不同的计算图上的张量和运算都不会共享
    
    g1=tf.Graph()
    
    with g1.as_default():
    
        v=tf.get_variable('v',...)
    
    with tf.Session(graph=g1) as sess:
    
        with tf.variable_scope('',reuse=Ture):
    
            sess.run(tf.get_variable('v'))
    

    张量使用

    #张量的使用
    
    a=tf.constant([1.0,2.0],name='a')
    

    session使用

    会话session########################################
    1,sess=tf.Session()  
    sess.run()  
    sess.close()
    2,with tf.Session() as sess:
    3,sess=tf.Session()with sess.as_default():    
    print(result.eval())
    完全等同于:
    result.eval(session=sess)
    4,sess=tf.InteractiveSession()
    result.eval()
    sess.close()
    

    config

    #################################config##################
    
    config=tf.ConfigProto(allow_soft_placement=True,log_device_placement=True)
    

    Variable初始化赋值

    w2=tf.Variable(weight.initialized_value()) 这里的值是完全相同的
    
    trainable,shape,name,type
    
    tf.assign(w1,w2,validate_shape=False)
    
    tf.assign(v1,10)
    

    placeholder 输入端动态赋值

    placeholder(tf.float32,shape=(1,2),name='input')
    

    2,前向传播端:

    tf.add_to_collection('losses',regularizer(weights))
    
    with tf.variable_scope('layer1'):
    

    卷积

    filter_weight=tf.get_variable('weights',[5,5,32,16],initializer=tf.truncated_normal_initializer(stddev=0.1))
    
    [卷积核大小,输入大小,输出大小]
    
    bias=tf.get_variable('bias',[16j],tf.constant_initializer(0.1))
    
    conv=tf.nn.conv2d(input,filter_weight,strides=[1,1,1,1],padding='SAME'/'VALID')
    
    strides:步长的第一和第四都要为1。
    
    bias=tf.nn.bias_add(conv,bias)
    
    actived_conv=tf.nn.relu(bias)
    
    #############池化############################
    
    pool=tf.nn.max_pool(actived_conv,ksize=[1,3,3,1],strides=[1,2,2,1],padding='SAME')
    
    ksize--过滤器尺寸,1和4维度必须为1.strides--步长,1和4维度必须为1.
    
    #############pooling 层 转全连接层#########################
    
    pool_shape=pool2.get_shape().as_list()
    
    nodes=pool_shape[1]*pool_shape[2]*pool_shape[3]
    
    reshaped=tf.reshape(pool2,[pool_shape[0],nodes])
    
    ###############tensorflow-slim工具#########################
    
    net=slim.conv2d(input,32,[3,3],scope='..')      #深度,核数
    
    #######################链接不同卷积###########################
    
    net=tf.concat(3,[a,b,c,..e]) 这里的三指的是第三维度,
    
    #############################drop out 层########################
    
    hidden1_drop=tf.nn.dropout(hidden1,keep_prob)
    
    #一般dropout都是放在softmax层的前面一层
    

    反向传播端

    #正则化
    
    tf.contrib.layers.l1_regularizer(.5)(weights)
    
    利用tf.add_to_collection('loss',...) tf.get_collection('loss')
    
    #学习率衰减
    
    decayed_learning_rate=learning_rate*decay_rate^(global_step/decay_steps)
    
    learning_rate=tf.train.exponential_decay(basic_learning_rate,global_step,training_step,learning_rate_decay,staircase=True)
    
    training_step:过完所有训练所需要的训练次数
    
    #滑动平均模型
    
    ema=tf.train.ExponentialMovingAverage(0.99,step)#定义好模型
    
    maintain_average_op=ema.apply([v1])#注册输入
    variables_averages_op=ema.apply(tfe.trainable_variables())
    
    sess.run(maintain_average_op)#开始优化
    
    sess.run([v1,ema.average(v1)])#查看输出
    
    #计算结果loss
    
    tf.nn.sparse_softmax_cross_entropy_with_logits(y,tf.argmax(y_1,1))
    
    cross_entropy_mean=tf.reduce_mean(cross_entropy)
    
    loss=cross_entropy_mean+tf.add_n(tf.get_collection('loss'))
    
    loss=-tf.reduce_mean(y_*tf.log(tf.clip_by_value(y,1e-10,1.0)))
    
    mse=tf.reduce_mean(tf.square(y_-y))
    
    tf.select(tf.greater(v1,v2),v1,v2)
    
    #反向传播优化函数
    
    train_step=tf.train.AdamOptimizer(learning_rate).minimize(loss,global_step=global_step)
    
    有时候使用GradientDescentOptimizer反而好一些
    
    #优化函数和滑动平均同时进行
    
    with tf.control_dependencies([train_step,variables_averages_op]):
    
                train_op=tf.no_op(name='train')
    
    or: train_op=tf.group(train_step,variables_average_op)
    
    #dropout 一般只在全连接层而不是卷积层
    
    fc1=tf.nn.dropout(fc1,0.5)
    

    4,输出端

    save and restore

    saver=tf.train.Saver()
    
    saver.save(sess,'path/model.ckpt',global_step=global_step)
    
    #checkpoint 文件列表
    
    #model.ckpt.data 变量取值
    
    #model.ckpt.meta 计算图结构
    
    saver.restore(sess,'./model/model.ckpt')
    
    #这里初始定义以及其他所有的操作都是需要的,唯一不需要的就是初始化的操作,因为初始化操作我们是在restore中读取的。经过测试,必须要在同一个sess中使用。
    
    #如果我们不希望重复定义图上的运算,我们可以直接加载已经持久化的图。
    
    saver=tf.train.import_meta_graph('./model/model.ckpt.meta')
    
    with tf.Session() as sess:
    
            saver.restore(sess,'./model/model.ckpt')        
            print(sess.run(tf.get_default_graph().get_tensor_by_name('add:0')))
    
    #只读取部分参数
    
    saver=tf.train.Saver([v1]) #这里只会读取v1参数,不会读取其他任何参数
    
    saver2=tf.train.Saver({'v1':v1})#变量重命名
    
    v1=tf.Variable(tf.constant(1,shape=[1]),name='v_other1')
    
    saver2=tf.train.Saver({'v1':v1})
    
    #由于滑动平均模型有隐藏变量,所以我们把这些变量对应映射的到真实变量上
    
    saver=tf.train.Saver(ema.variables_to_restore())
    
    #全部保存
    
    with tf.Session() as sess:
    
            tf.global_variables_initializer().run()
    
            graph_def=tf.get_default_graph().as_graph_def()        
            output_graph_def=graph_util.convert_variables_to_constants(sess,graph_def,['add'])        
    with tf.gfile.GFile('./model/combined_model.pb','wb') as f:                    
        f.write(output_graph_def.SerializeToString())
    
    #整体读取预测评估:
    
    with tf.Session() as sess:
    
            with gfile.FastGFile('./model/combined_model.pb','rb') as f:
    
                    graph_def=tf.GraphDef()
    
                  graph_def.ParseFromString(f.read())        
                  result=tf.import_graph_def(graph_def,return_elements=['add:0'])#获取这个计算图的变量     
    
                print(sess.run(result))
    
    ######抽取网络中的一部分值
    
        or bootleneck_tensor,image_data=tf.import_graph_def(graph_def,return_elements=['a','b'])
    
        or bottleneck_values=sess.run(bottleneck_tensor,{image_data_tensor:image_data})
    

    5,预测评估端

    #预测真确率
    
    correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(y_,1))    
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
    
    #获取隐含变量
    
      ema=tf.train.ExponentialMovingAverage(0.99)    
    variables_to_restore=ema.variables_to_restore()   
     saver=tf.train.Saver(variables_to_restore)
    
    #利用checkpoint 获取最新值:
    
    ckpt=tf.train.get_checkpoint_state('./model/')
        if ckpt and ckpt.model_checkpoint_path:                                    
            saver.restore(sess,ckpt.model_checkpoint_path)                            
            global_step=ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]                            
         accuracy_score=sess.run(accuracy,feed_dict=valid_feed)
        print('after %s iterations,the valid set acc= %g'%(global_step,accuracy_score))      
        else:
            print('No checkpoint file found!')    return
    
    #如果出现tensor流复用的情况,会报错。这里我们使用:
    
    with tf.Graph().as_default() as g: 这个方法,每次都能更新新的值。
    

    6,数据集处理及其保存读取

    #####################写入TFRecord文件
    
    def _int64_feature(value):
    
        return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
    
    def _bytes_feature(value):
    
        return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
    
    filename='output.tfrecords'
    
    writer=tf.python_io.TFRecordWriter(filename)
    
    for index in range(num_examples):
        image_raw=images[index].tostring()        
        example=tf.train.Example(features=tf.train.Features(feature={'pixels':_int64_feature(pixels),       
     'label':_int64_feature(np.argmax(labels[index])), 'image_raw':_bytes_feature(image_raw)    }))
      writer.write(example.SerializeToString())
    
    writer.close()
    
    ###########################读取TFRecord文件########################
    
    reader=tf.TFRecordReader()filename_queue=tf.train.string_input_producer(['output.tfrecords'])#创建队列维护文件列表
    
    _,serialized_example=reader.read(filename_queue)
    
    features=tf.parse_single_example(    serialized_example,    features={                'image_raw':tf.FixedLenFeature([],tf.string),
    
                    'pixels':tf.FixedLenFeature([],tf.int64),
    
                    'label':tf.FixedLenFeature([],tf.int64),    })
    
    images=tf.decode_raw(features['image_raw'],tf.uint8)labels=tf.cast(features['label'],tf.int32)
    
    pixels=tf.cast(features['pixels'],tf.int32)
    
    sess=tf.Session()
    
    coord=tf.train.Coordinator()#启动多线程
    
    threads=tf.train.start_queue_runners(sess=sess,coord=coord)
    
    for i in range(10):
    
                image,label,pixel=sess.run([images,labels,pixels])
    
    ##########################关于图片的编码和解码#####################
    
    img_data=tf.image.decode_jpeg(image_raw_data)
    
    img_data=tf.image.convert_image_dtype(img_data,dtype=tf.float32)
    
    encoded_image=tf.image.encode_jpeg(img_data)
    
    ############################图像读写##############################
    
    with tf.gfile.GFile('./output','wb') as f:
    
            f.write(encoded_image.eval())
    
    ###############调整图像大小########################3
    
    resized=tf.image.resize_images(image_data,[300,300],method=0)
    
    tf.image.resize_iamge_with_crop_or_pad(image_data,1000,3000)
    
    还有其他各种调整这里先不写了
    
    ############################关于队列#####################3
    
    队列初始化:q=tf.FIFOQueue(2,'int32') or tf.RandomShuffleQueue(2,'int32')
    
    q.dequeue() q.enqueue([y]) q.enqueue_many(([0,10],))
    
    ###########################开启多线程############################
    
    tf.Coordinator()  -->should_stop(查看是否应该停止),request_stop(要求全部停止),join(回收线程)
    
    coord=tf.train.Coordinator()
    
    threads=[threading.Thread(target=MyLoop,args=(coord,i)) for i in range(10)]
    
    for t in threads:    t.start()
    
    coord.join(threads)
    
    def MyLoop(coord,work_id):
    
            while not coord.should_stop():
    
                                if np.random.rand()<0.05:            print('stopping from id: %d\n'%(work_id))            coord.request_stop()
    
                                else:            print('working on id: %d\n'%(work_id)
    
            time.sleep(2)
    
    ###################队列版本的多线程服务###############################
    
    qr=tf.train.QueueRunner(queue,[enqueue_op]*5)(定义队列线程以及操作)
    
    tf.train.add_queue_runner(qr) (注册)
    
    coord=tf.train.Coordinator()    threads=tf.train.start_queue_runners(sess=sess,coord=coord)(把队列和多线程链接)
    
    #下面是sess的正常操作
    
        coord.request_stop()  coord.join(threads)#关闭和回收
    
    ##################################文件多线程操作#####################
    
    files=tf.train.match_filenames_once('./data/data.tfrecords-*')#读取文件名
    
    filename_queue=tf.train.string_input_producer(files,shuffle=False)#加入文件队列
    
    #接下来是正常的读取文件套路
    
    tf.local_variables_initializer().run()#这里一定要初始化这个
    
    coord=tf.train.Coordinator()    threads=tf.train.start_queue_runners(sess=sess,coord=coord)#注册为多线程
    
    #开始读取
    
        coord.request_stop()
    
        coord.join(threads)
    
    ##################################batching ##########################
    
    队列的入队操作是生成单个样本的方法,而每次出队得到的是一个batch的样例。
    
    #前面是正常的文件名读取,加入队列,配置reader队列。
    
    example,label=features['i'],features['j']
    
    example_batch,label_batch=tf.train.batch([example,label],batch_size=batch_size,capacity=capacity)#(batch_size是每一个batch的大小,capacity是队列所能够承载的能力)
    
    ###tf.train.shuffle_batch 是打乱排序的,有一个特有的参数,就是 min_after_dequeue,限制出队时最小元素个数
    
    coord=tf.train.Coordinator()    threads=tf.train.start_queue_runners(sess=sess,coord=coord)
    
    cur_example_batch,cur_label_batch=sess.run([example,label])
    
    #接下来是一样的
    
    #############################最终读取注意点##########################
    
    再从TFRecord中读取之后,得到的照片是byte形式的,这里,我们要解析图像还原为原始尺寸照片。
    
    decoded_image=tf.decode_raw(image,tf.uint8)
    
    decoded_image.set_shape([height,width,channels])
    

    7,tensorboard 可视化调试

    #tensorboard读取log命令
    
    python /home/horsetif/.local/lib/python3.6/site-packages/nsorboard/main.py --logdir='/home/horsetif/Code/TF_HTF/data/flower_photos/log/'(这里是我自己的地址)
    
    ###############保存为日志文件##################################
    
    writer=tf.summary.FileWriter('./log',tf.get_default_graph())
    
    writer.close()
    
    #########################更新节点信息代码############################
    
    if i %1000==0:
    
            run_options=tf.RunOptions(trace_level=tr.RunOptions.FULL_TRACE)        run_metadata=tf.RunMetadata()
    
            sess.run(...,run_metadata=run_metadata)        train_writer.add_run_metadata(run_metadata,'step%03d'%i)
    
    #############################监控指标可视化############################
    
    with tf.name_scope('aa'):#先加这个
    
    tf.scalar_summary(name_path,variable)#标量变化
    
    tf.image_summary#输入图象变化
    
    tf.histogram_summary#张量变化,如weight
    
    merged=tf.merge_all_summaries()
    
    summary_writer=tf.train.SummaryWriter(SUMMARY_DIR,sess.graph)
    
    summary=sess.run(merged,feed_dict={})
    
    summary_writer.add_summary(summary,i)
    

    8,GPU加速

    #如果没有明确地指定运行路径,tensorflow会优先选择GPU。
    
    #改变GPU位置
    
    with device('/gpu:1'):  with device('/cpu:0'):
    
    #如果无法放在GPU上的代码,我们让他们放在cpu上。
    
    sess=tf.Session(config=tf.ConfigProto(allow_soft_placement=True,log_device_placement=True))
    
    #多个GPU并行计算问题,一般使用并行同步模式。所有设备同时读取参数取值,并且反向传播算法完成后同步更新参数的取值。所有设备参数一致,完成反向传播后,计算出不同设备上参数梯度的平均值,最后再根据平均值对参数进行更新。
    
    #主要是利用不同的scope空间来划分区域,然后求和再取平均。
    
    with tf.device('/gpu:%d' %d):
    
        with tf.name_scope('GPU %d'%i) as scope:
    
    tf.get_collection('losses',scope)
    

    相关文章

      网友评论

        本文标题:tensorflow一文完全解答(改)

        本文链接:https://www.haomeiwen.com/subject/kwkxuftx.html