tensorflow一文完全解答

這篇文章是針對有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'):

2)卷積:

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)

3,反向傳播端

#正則化

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)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

推薦閱讀更多精彩內容