TensorFlow

TensorFlow

1、Basic

TensorFlow是以圖做爲核心,數據的流動構成一張圖,對圖進行相應的計算。html

Graph:

matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
product = tf.matmul(matrix1 , matrix2)

這樣,建立了三個結點,兩個constant op,一個mutmul op。python

Session:

Graph須要載入Session中才能夠運行。數組

sess = tf.Session()
sess.run(product)
sess.close()

在計算結束後,須要關閉session以釋放資源。或者使用with 子句,在結束後會自動釋放:瀏覽器

with tf.Session() as sess:
    sess.run(product)

指定設備:

"/cpu:0" :計算機的 CPU ;
"/gpu:0" :計算機的第一個 GPU ,若是可用;
"/gpu:1" :計算機的第二個 GPU ,以此類推。網絡

with tf.Session() as sess:
    with tf.device("/gpu:1"):
        sess.run(product)

ConfigProto

在配置Session時,能夠設置config,常見配置項以下:session

  • log_device_placement
  • allow_soft_placement
  • gpu_options.allow_growth: 是否採用增加的方式分配顯存。若是這個值爲True,那麼分配器不會預分配整個指定的GPU顯存空間,而是開始分配一小部分顯存,而後隨着須要而增長。

詳細配置項:https://www.jianshu.com/p/b9a442bcfd2e數據結構

例子:
log_device_placement=True打印使用相關的設備信息:app

config=tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)

Tensor:

你能夠把 TensorFlow 的張量看做是一個 n 維的數組或列表 . 一個 tensor
包含一個靜態類型 rank, 和一個 shape.dom

Variable:

變量維持了圖執行過程當中的狀態信息。機器學習

state = tf.Variable(0, name="counter")
one = tf.constant(1)
new_value = tf.add(state, one)
update_value = tf.assign(state, new_value)
init_op = tf.initialize_all_variables()
with tf.Session() as sess:
    with tf.device("/gpu:0"):
        sess.run(init_op)
        for _ in range(3):
            sess.run(update_value)

變量初始化:

# random_normal
weights = tf.Variable(tf.random_normal(shape=[784, 200], stddev=0.35), name="weights")

# zeros
biases = tf.Variable(tf.zeros(shape=[200]), name="biases")

# 使用其它變量
weigths2 = tf.Variable(weights.initialized_value(), name='weights2')

# 手動初始化
weights3 = tf.Variable([1.0, 2.0, 5.0, 3.5], name='weights3')

note: tf函數的shape都是以列表爲參數[3, 4], 如tf.zeros([3, 4]);而numpy中函數的shape參數多數以元組形式(3, 4),如np.zeros((3, 4));

2、Function

tf.group

建立一個op組合多個操做,sess.run(group)時能夠執行group中全部的操做,當全部操做都完成,op輸出結果爲None。

b = tf.random_uniform([2,3], minval = 10, maxval = 11)
w = tf.random_uniform([2,3], minval = 10, maxval = 11)
mul = tf.multiply(w, 2)
add = tf.add(w, 2)
group = tf.group(mul, add)
print sess.run(group)
#輸出:None

tf.train.ExponentialMovingAverage

tf.train.ExponentialMovingAverage(decay, steps)
tf.train.ExponentialMovingAverage這個函數用於更新參數,就是採用滑動平均的方法更新參數。這個函數初始化須要提供一個衰減速率(decay),用於控制模型的更新速度。這個函數還會維護一個影子變量(也就是更新參數後的參數值),這個影子變量的初始值就是這個變量的初始值,影子變量值的更新方式以下:
shadow_variable = decay * shadow_variable + (1-decay) * variable
shadow_variable是影子變量,variable表示待更新的變量,也就是變量被賦予的值,decay爲衰減速率。decay通常設爲接近於1的數(0.99,0.999)。decay越大模型越穩定,由於decay越大,參數更新的速度就越慢,趨於穩定。
tf.train.ExponentialMovingAverage這個函數還提供了本身更新decay的計算方式:
decay= min(decay,(1+steps)/(10+steps))
steps是迭代的次數,能夠本身設定或者默認。

self.ema = tf.train.ExponentialMovingAverage(decay=0.9999)
self.averages_op = self.ema.apply(tf.trainable_variables())
with tf.control_dependencies([self.optimizer]):
    self.train_op = tf.group(self.averages_op)

tf.control_dependencies

在有些機器學習程序中咱們想要指定某些操做執行的依賴關係,這時咱們可使用tf.control_dependencies()來實現。
control_dependencies(control_inputs)返回一個控制依賴的上下文管理器,使用with關鍵字可讓在這個上下文環境中的操做都在control_inputs 執行。

with g.control_dependencies([a, b, c]):
# `d` and `e` 在 `a`, `b`, and `c` 執行完後運行
d = ...
e = ...

tf.trainable_variables

tf.trainable_variables返回的是須要訓練的變量列表
tf.all_variables返回的是全部變量的列表

import tensorflow as tf;    
import numpy as np;    
import matplotlib.pyplot as plt;    
  
v = tf.Variable(tf.constant(0.0, shape=[1], dtype=tf.float32), name='v')  
v1 = tf.Variable(tf.constant(5, shape=[1], dtype=tf.float32), name='v1')  
 # trainable = False
global_step = tf.Variable(tf.constant(5, shape=[1], dtype=tf.float32), name='global_step', trainable=False)  
ema = tf.train.ExponentialMovingAverage(0.99, global_step)  
  
for ele1 in tf.trainable_variables():  
    print ele1.name  
for ele2 in tf.all_variables():  
    print ele2.name

輸出:
v:0
v1:0

v:0
v1:0
global_step:0

分析:
上面獲得兩個變量,後面的一個獲得上三個變量,由於global_step在聲明的時候說明不是訓練變量,用來關鍵字trainable=False。

placeholder, feed
二者結合使用,先用placeholder定義佔位符,以後使用feed傳入真實的數據。

# define hld, None means batch_size
x_hld = tf.placeholder(tf.float, [None, 320, 240, 3], name='x_hld')
y_hld = tf.placeholder(tf.int64, [None, nb_classes], name='y_hld')

sess.run([train_op], feed_dict={x_hld: X, y_hld: y})

tf.Graph.finalize
做用:結束(Finalizes)這個圖,使其只讀(read-only).調用這個函數以後,就沒有操做可以添加到這個圖裏面去了。這個方法是確保當這個圖被多個線程共享的時候,沒有操做可以添加進去。

tf.pad()

#t=[[2,3,4],[5,6,7]], paddings=[[1,2],[2,3]],mode="CONSTANT"
sess.run(tf.pad(t,paddings,"CONSTANT"))

[[1, 2], [2, 3]]表示上面pad 1, 下面pad 2, 左面pad 2, 右面pad 3,最後造成:

result

result

CONSTANT表示pad的數是0, 還有REFLECT和SYMMETRIC方式,詳情見(http://blog.csdn.net/zhang_bei_qing/article/details/75090203)。

optimizer

optimizer = tf.train.GradientDescentOptimizer(learning_rate)
train_op = optimizer.minimize(loss)
sess.run([train_op], feed_dict={x_batch: x[i\*batch_size:(i+1)*batch_size], y_batch: y[i\*batch_size:(i+1)\*batch_size]})

常見優化器以下:

GradientDescentOptimizer
AdagradOptimizer
AdagradDAOptimizer
MomentumOptimizer
AdamOptimizer
FtrlOptimizer
RMSPropOptimizer

arg_scope:

tf.contrib.framework.arg_scope(list_ops_or_scope, **kwargs)
#或者
tf.contrib.slim.arg_scope(list_ops_or_scope, **kwargs)

# 爲給定的 list_ops_or_scope 存儲默認的參數

如:

with slim.arg_scope([slim.conv2d, slim.fully_connected],
	activation_fn=leaky_relu(alpha),
	weights_initializer=tf.truncated_normal_initializer(0.0, 0.01),
	weights_regularizer=slim.l2_regularizer(0.0005)):

對conv2d,fully_connected層分別加上activation_fn, weights_initializer, weights_regularizer等默認屬性。

accuracy計算:

acc = tf.equal(pred.argmax(), y.argmax())
acc_f = tf.cast(acc, tf.float32)
acc_op = tf.reduce_sum(acc_f)

reduce_sum:

在哪一個維度上操做,哪一個維度的大小就變爲1.
(2, 3) reduce_sum(arr, 0, keep_dim=True) => (1, 3)
(2, 3) reduce_sum(arr, 1, keep_dim=True) => (2, 1) #使用keep_dim,不然會變成(1, 2)

reduce_sum若是不加維度的話,默認是在全部維度上進行,加上維度就只在特定給定上執行求和操做:

reduce_sum(arr, 0)  # 對第0維操做,即對0維求和
reduce_mean(arr, 1) #對第1維操做,即對1維求平均

concat:
和reduce_sum類型,在哪一個維度上操做,哪一個維度的大小就變

# t1 with shape [2, 3], t2 with shape [2, 3]
tf.shape(tf.concat([t1, t2], 0))  # => [4, 3]
tf.shape(tf.concat([t1, t2], 1))  # => [2, 6]

以下, t1, t2沒法使用concta鏈接第二維,由於對應的shape只有一個維度,固然不能在第二維上連了,雖然實際中兩個向量能夠在行上連,可是放在程序裏是會報錯的。須要使用expand_dim來擴展出第二維

t1=tf.constant([1,2,3])  
t2=tf.constant([4,5,6])  
# tf.concat([t1, t2], 1)

t1 = tf.expand_dims(tf.constant([1, 2 ,3]), 1)
t2 = tf.expand_dims(tf.constant([4, 5, 6]), 1)
tf.concat([t1, t2], 1) # [[1]]

expand_dims:

有時,2維的矩陣想變成3維的矩陣,如(2, 3)的矩陣想變爲(2, 3, 1)就須要使用expand_dim,固然使用tf.reshape也能夠進行變換,但tf.reshape對於tf.placeholder變量會報錯,這個時候仍是要使用tf.expand_dims。

# 假設value維度爲(2, 3)

tf.expand_dims(value, 0)  # (2, 3) => (1, 2, 3)
tf.expand_dims(value, 1)  # (2, 3) => (2, 1, 3)
tf.expand_dims(value, 2)  # (2, 3) => (2, 3, 1)
tf.expand_dims(value, -1)  #-1表示在擴展最後一維 (2, 3) => (2, 3, 1)

tf.shape:
返回張量的形狀,而且shape返回的也是張量,在tensorflow中須要sess.run才能看到值:

slim.losses:

若是不使用tf提供的loss函數,而本身實現loss計算時,又想使用tensorflow的loss管理機制,可使用slim.losses.add_loss()來添加loss,並使用slim.losses.get_total_loss()來獲得最後的loss。

exponential_decay:

tf.train.exponential_decay主要用來對學習率進行動態調整,前期可使用較大的學習率,後期能夠調小學習率。

lr = tf.train.exponential_decay(initial_learning_rate, glob_step, decay_steps, decay_rate)

例子:

initial_learning_rate: 初始學習率,如 0.001
glob_step: 當前迭代數,如 0, 1, 2, 3...
decay_steps: 衰減一次decay_rate須要的迭代次數, 如 3000,就是須要3000次縮減到decay_rate倍
decay_rate: 衰減的係數, 如0.1

那麼初始學習率爲0.001,以下兩個迭代時的學習率計算方式:

glob_step=0, 那麼有: lr = 0.001 * 0.1 ^ (0 / 3000) = 0.001
glob_step=3000, 那麼有: lr = 0.001 * 0.1 ^ (3000 / 3000) = 0.0001

可見,越到後面學習率越小。

另外一種思路,設置stair_case=True,能夠調小decay_steps,調大decay_rate,這樣能夠在decay_steps的整數倍迭代時,乘以一個decay_rate。

lr = tf.train.exponential_decay(initial_learning_rate=0.001, glob_step=i, decay_steps = 100, decay_rate=0.96, stair_case=True)

iter 0: lr = 0.001 * 0.96 ^ (0 / 100) = 0.001
iter 99: lr = 0.001 * 0.96 ^ (99 / 100) = 0.001
iter 100: lr = 0.001 * 0.96 ^ (100 / 100) = 0.0096
iter 200: lr = 0.001 * 0.96 ^ (100 / 100) = 0.009216

也就是對(glob_step / decay_steps)取整數,每decay_steps迭代乘以0.96。

若是staircase=True, decay_rate=0.1, decay_steps=10000,那麼學習率每10000次縮小10倍。

batch normalization:

實現:

# convolution with batch norm
net = slim.conv2d(net, 32, 5, padding='SAME', activation_fn=tf.nn.relu, normalizer_fn=slim.batch_norm, scope='conv1')

#dependency
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) 
with tf.control_dependencies(update_ops): 
    train_step = tf.train.GradientDescentOptimizer(0.01).minimize(total_loss)

使用batch normaliztion:
那BN究竟是什麼原理呢?說到底仍是爲了防止「梯度彌散」。在神經網絡訓練時遇到收斂速度很慢,或梯度爆炸等沒法訓練的情況時能夠嘗試BN來解決。另外,在通常使用狀況下也能夠加入BN來加快訓練速度,提升模型精度。

下面是分別沒有使用BN和使用BN的結果,能夠看到使用BN在相同迭代次數下BN結果更優。

not using BN

not using BN

using BN

using BN

Random:

random_normal: 是使生成的數據服從正態分佈

truncated_normal: 若是數據大於(mean +/- 2 * std)範圍就從新取值

random_uniform: 產生於low和high之間,產生的值是均勻分佈的。

tf.random_shuffle(value, seed=None, name=None): 打亂Tensor的第0維,即行

a1 = [[1, 2], [3, 4], [5, 6]]
a2 = tf.randem_shuffle(a1) #=> 以行隨機,可能結果[[3, 4], [1, 2], [5, 6]]

casting:

tf.to_double([1, 2])
tf.to_float([1, 2])
tf.to_int32()
tf.to_int64()
tf.cast([1, 2], dtype=int32)
tf.cast([1, 2], dtype=float32)

注意: 這裏,使用tf.to_float,但使用tf.cast(1, dtype=tf.float32)必須使用float32,不然會報錯。

rank:

求Tensor是幾維張量。

tf.rank(a1)
tf.shape(a1)
tf.size(a1)
tf.reshape(a1, [1, 2])

tfrecoder:

tensorflow中可使用tfrecoder進行數據的讀寫。tensorflow中提供tf.train.Example,其是使用protobuf進行定義的,以下:

message Example {
 Features features = 1;
};

message Features{
 map<string,Feature> featrue = 1;
};

message Feature{
    oneof kind{
        BytesList bytes_list = 1;
        FloatList float_list = 2;
        Int64List int64_list = 3;
    }
};

能夠看到Example中包括一個features成員,而features又是一個字符串與Feature類型的map,這樣咱們就能夠存儲"label", "img"這樣的數據了,一個Example就是一個數據樣例。

利用以下方法將數據存儲到tfrecode文件中:

def test_write_to_tfrecords(filename):
    writer = tf.python_io.TFRecordWriter(filename)

    #循環將每一個數據寫入
    for i in range(100):
        img_raw = np.random.random_integers(0,255,size=(7,30)) # 建立7*30,取值在0-255之間隨機數組
        img_raw = img_raw.tostring()
        example = tf.train.Example(features=tf.train.Features(
                feature={
                'label': tf.train.Feature(int64_list = tf.train.Int64List(value=[i])),     
                'img_raw':tf.train.Feature(bytes_list = tf.train.BytesList(value=[img_raw]))
                }))
        writer.write(example.SerializeToString()) #將數據序列化寫入

    writer.close()

文件的讀取須要使用tf.train.string_input_producer生成一個解析隊列,再調用tf.TFRecordReader的tf.parse_single_example解析器進行解析。

tfrecords_filename = "train.tfrecords"
    test_write_to_tfrecords(tfrecords_filename)
    filename_queue = tf.train.string_input_producer([tfrecords_filename],) #讀入流中
    reader = tf.TFRecordReader()
    _, serialized_example = reader.read(filename_queue)   #返回文件名和文件
    features = tf.parse_single_example(serialized_example,
                                       features={
                                           'label': tf.FixedLenFeature([], tf.int64),
                                           'img_raw' : tf.FixedLenFeature([], tf.string),
                                       })  #取出包含image和label的feature對象
    image = tf.decode_raw(features['img_raw'], tf.int64)
    image = tf.reshape(image, [7,30])
    label = tf.cast(features['label'], tf.int64)
    with tf.Session() as sess: #開始一個會話
        init_op = tf.initialize_all_variables()
        sess.run(init_op)
        coord=tf.train.Coordinator()
        threads= tf.train.start_queue_runners(coord=coord)
        for i in range(20):
            example, l = sess.run([image,label])#在會話中取出image和label
            img=Image.fromarray(example, 'RGB')#這裏Image是以前提到的
            img.save('./'+str(i)+'_''Label_'+str(l)+'.jpg')#存下圖片
            print(example, l)

        coord.request_stop()
        coord.join(threads)

注意,在運行任何訓練步驟以前,須要調用tf.train.start_queue_runners函數,不然tensorflow將一直掛起。

coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)

取出數據時,也要使用sess.run才能真正取出:

example, l = sess.run([image,label])

上面代碼讀取的是單個的image和label,而在tensorflow訓練時,通常是採起batch的方式去讀入數據。tensorflow提供了兩種方式,一種是shuffle_batch(tf.train.shuffle_batch),這種主要是用在訓練中,隨機選取樣本組成batch。另一種就是按照數據在tfrecord中的前後順序生成batch(tf.train.batch)。
這裏採用tf.train.shuffle_batch方式, capacity是可載入的樣本數;min_after_dequeue是在出隊列操做後最少生關死劫的樣本數,小於這個數就須要讀入新的樣本;batch_size一次取出的樣本數;num_threads線程數:

img_batch, label_batch = tf.train.shuffle_batch([img,label], batch_size=18, capacity=2000, min_after_dequeue=100, num_threads=2)

總體代碼以下:

import tensorflow as tf   
import scipy.misc as misc
import os

def write_binary():  
    cwd = os.getcwd()

# all_files = os.listdir(cwd)

    classes=['a','b','c']
    writer = tf.python_io.TFRecordWriter('data.tfrecord')  
    for index, name in enumerate(classes):
        class_path = os.path.join(cwd,name)
# if tf.gfile.Exists(class_path):
# tf.gfile.DeleteRecursively(class_path)
# tf.gfile.MakeDirs(class_path)
        for img_name in os.listdir(class_path):
            img_path = os.path.join(class_path , img_name)
            img = misc.imread(img_path)
            img1 = misc.imresize(img,[250,250,3])
            img_raw = img1.tobytes()              #將圖片轉化爲原生bytes
            example = tf.train.Example(features=tf.train.Features(feature={
                    'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])),
                "label": tf.train.Feature(int64_list=tf.train.Int64List(value=[index]))}
                ))  # 將數據整理成 TFRecord 須要的數據結構 

    #序列化 
            serialized = example.SerializeToString()  
    #寫入文件 
            writer.write(serialized)  
    writer.close()  

def read_and_decode(filename):  
    #建立文件隊列,不限讀取的數量 
    filename_queue = tf.train.string_input_producer([filename],shuffle=False)  
    # create a reader from file queue 
    reader = tf.TFRecordReader()  
    #reader從 TFRecord 讀取內容並保存到 serialized_example 中 
    _, serialized_example = reader.read(filename_queue)  

    features = tf.parse_single_example(     # 讀取 serialized_example 的格式 
        serialized_example,  
        features={  
            'label': tf.FixedLenFeature([], tf.int64),  
            'img_raw': tf.FixedLenFeature([], tf.string)      
        }  
    )  # 解析從 serialized_example 讀取到的內容 
    img=tf.decode_raw(features['img_raw'],tf.uint8)
    img = tf.reshape(img, [250, 250, 3])
    label = tf.cast(features['label'], tf.int32)
    return img,label  


#write_binary() 

img,label = read_and_decode('data.tfrecord')  

img_batch, label_batch = tf.train.shuffle_batch([img,label], batch_size=18, capacity=2000, min_after_dequeue=100, num_threads=2)  
## 
# sess 
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)  
    coord = tf.train.Coordinator()  #建立一個協調器,管理線程
    #啓動QueueRunner, 此時文件名隊列已經進隊。
    threads=tf.train.start_queue_runners(sess=sess,coord=coord)  

    img, label = sess.run([img_batch, label_batch])  
    #for i in range(18):
    # cv2.imwrite('%d_%d_p.jpg'%(i,label[i]),img[i])
    coord.request_stop()
    coord.join(threads)

http://blog.csdn.net/happyhorizion/article/details/77894055
http://blog.csdn.net/ei1990/article/details/76575935

tf.app.run:
利用tensorflow的FLAGS解析功能。

tf.app.flags.DEFINE_boolean("self_test", False, "True if running a self test.")  
tf.app.flags.DEFINE_boolean('use_fp16', False,  
                            "Use half floats instead of full floats if True.")  
FLAGS = tf.app.flags.FLAGS  

def main():
    # using FLAGS.self_test

if __name__ == '__main__':
    tf.app.run()

tf.app.run源碼定義以下,主要解析參數,並調用main函數:

import sys
from tensorflow.python.platform import flags  
    
def run(main=None):  
  f = flags.FLAGS  
  f._parse_flags()  
  main = main or sys.modules['__main__'].main  
  sys.exit(main(sys.argv))

3、Debug

使用TensorFlow的Debugger並不困難,大體總結起來有這麼幾個流程:
1.import要使用的TensorFlow的調試模塊

from tensorflow.python import debug as tfdbg

2.使用調試模塊的會話對象包裝原有的Session對象

with tf.Session(config=config) as sess: 
	sess = tfdbg.LocalCLIDebugWrapperSession(sess)

3.加入異常值對應的過濾器

sess.add_tensor_filter("has_inf_or_nan", tfdbg.has_nan_or_inf)

4.運行代碼,並在帶過濾器的狀況下運行

r -f has_inf_or_nan

5.跟蹤異常值產生的節點,並找到異常值來源在源碼中的位置(這個比較靈活,有些可能須要回溯幾個節點,有些直接可查)

ni -t Discrim/add_2

官方連接:
https://www.tensorflow.org/programmers_guide/debugger#wrapping_tensorflow_sessions_with_tfdbg

4、TensorBoard

使用tensorboard來可視化訓練過程。

  1. 使用scalar, histogram, image等表示須要記錄的變量:

    tf.summary.scalar("train_loss", loss_op)
     tf.summary.scalar("train_acc", acc_op)
  2. 建立summary_op與summarywriter

    sum_op = tf.summary.merge_all()
     writer = tf.summary.fileWriter('./logs/test_cnn/', flush_secs=60)
  3. 能夠添加Graph:

    writer.add_graph(tf.get_default_graph())
  4. 運行時添加summary

    sum_str, _ = sess.run([sum_op, train_op], feed_dict={...})
     writer.add(sum_str)
  5. 使用tensorboard可視化

    tensorboard --logdir=logs/test_cnn/

會提示訪問的ip地址,瀏覽器中打開能夠看到可視化結果。

由於tensorflow可能生成較多的結點,這樣可視化起來特別複雜。能夠將多個結點放到一個名稱域裏,這樣在可視化的時候,只有最上層的結點展現出來,雙擊能夠打開這個名稱域。

5、保存模型

TensorFlow保存模型使用tf.train.Saver():

saver = tf.train.Saver()
with tf.Session as sess:
    for i in range(100):
        sess.run([], feed_dict=...)
        if i % 10 == 0:
            saver.save(sess, os.path.join(model_dir, model_name), global_step=i)

以前的版本只會生成一個文件.ckpt,如今版本會生成4個文件,分別是.ckpt.meta, .ckpt.data, .ckpt.index, checkpoint。

checkpoint: 記錄了全部checkpoint點保存的模型以及最新的模型
.ckpt.meta: 保存了網絡的Graph圖
.ckpt.data: 保存了網絡的權重參數
.ckpt.index:

在定義Saver時,能夠只保存部分變量:

# 使用字典
saver = tf.train.Saver({'v1': v1, 'v2': v2})
# 使用列表
saver = tf.train.Saver([v1, v2])

# 使用列表初始一個字典
saver = tf.train.Saver({v.op.name: v for v in [v1, v2]})

重載model,使用restore函數,以下:

#使用lastest_checkpoint
model_file = tf.train.latest_checkpoint(model_dir)
saver.restore(sess, model_file)

#使用save時的文件名
saver.restore(sess, os.path.join(model_dir, model_name))

爲了使用的時候,再也不次定義模型,可使用以下代碼將graph加載進來,而且經過字符串名訪問模型中的變量、hld變量、運算結點:

sess = tf.Session()
 
    # 《《《 加載模型結構 》》》
    saver = tf.train.import_meta_graph('./ckpt/model.ckpt.meta') 
    # 只須要指定目錄就能夠恢復全部變量信息 
   saver.restore(sess, tf.train.latest_checkpoint('./ckpt'))  

    # 直接獲取保存的變量
    print(sess.run('b:0'))

    # 獲取placeholder變量
    input_x = sess.graph.get_tensor_by_name('x:0')
    input_y = sess.graph.get_tensor_by_name('y:0')
    
    # 獲取須要進行計算的operator
    op = sess.graph.get_tensor_by_name('op_to_store:0')

    # 加入新的操做
    add_on_op = tf.multiply(op, 2)

    ret = sess.run(add_on_op, {input_x: 5, input_y: 5})
    print(ret)

參考:
https://zhuanlan.zhihu.com/p/32887066

6、共享變量

爲何要共享變量:

若是一個函數中建立了變量,須要調用屢次,就會產生多個這樣的變量,命令方式如下劃線數字方式遞增,如weight, weight_1, weight_2, weight_3等,因此會產生多個變量,形成沒必要要的浪費。咱們實際想反覆利用weight這個變量就夠了,使用全局變量能夠解決產生屢次的問題,但影響封裝。這時只須要將weight設爲共享變量,那麼就會只初始化一次,反覆使用的都是這個變量。

name_scope:

若是使用tf.Variable定義了相同名字的變量,tf會自動給變量加下劃線區分。

tf中提供name_scope限制變量做用域,能夠將變量放置到不一樣的命名域中管理。

with namescope('conv1'):
    w1 = tf.Variable([1.0, 2.0], name='weights')
    b1 = tf.Variable([1.0, 2.0], name='bias')
    
with namescope('conv2'):
    w2 = tf.Variable([1.0, 2.0], name='weights')
    b2 = tf.Variable([1.0, 2.0], name='bias')

w1的name爲conv1/weights:0, w2的name爲conv2/weights: 0

執行完 with 裏邊的語句以後,這個 conv1/ 和 conv2/ 空間仍是在內存中的。這時候若是再次執行上面的代碼就會再生成其餘命名空間,加了個_1以下:
w1的name爲conv1_1/weights:0, w2的name爲conv2_1/weights: 0

variable_scope, get_variable:

使用variable_scope和get_variable能夠實現共享變量。
首先須要在一個做用域定義一個變量,在另一個同名做用域中設置reuse=True,並使用tf.get_variable()獲取這個共享變量:

# 共享變量必須使用get_variable定義,不能使用tf.Variable
with tf.variable_scope('test'):
    w = tf.get_variable('weights', shape=[5, 3])

# 須要置reuse=True
with tf.variable_scope('test', reuse=True):
    w = tf.get_variable('weights')

設置reuse=True的子塊中,全部使用用到的共享變量必須事先使用tf.get_variable定義好,不然會報變量不存在。

get_variable會在變量不存在時自動建立一個,此時必需要提供shape參數;在設置reuse=True時,使用已經存在的變量。

也能夠在語句中設置scope爲reuse,以下:

# 共享變量必須使用get_variable定義,不能使用tf.Variable
with tf.variable_scope('test'):
    w = tf.get_variable('weights', shape=[5, 3])

with tf.variable_scope('test') as scope:
    scope.reuse_variables()
    w = tf.get_variable('weights')

Others

1. Anaconda

conda create -n tensorflow_1.6 python=2.7
source activate tensorflow_1.6
pip install 
source deactivate

視頻教程

http://www.javashuo.com/article/p-aeximyar-bq.html
http://mooc.study.163.com/smartSpec/detail/1001319001.htm
http://i.youku.com/pythontutorial
http://blog.csdn.net/lqf921205/article/details/78702704
http://open.163.com/special/opencourse/machinelearning.html

Reading

  1. 官方中文教程
相關文章
相關標籤/搜索