日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Tensorflow-Estimator-自定义估算器

發布時間:2025/3/19 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Tensorflow-Estimator-自定义估算器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自定義Custom Estimator和預制Pre-made Estimator

在上面iris的案例中我們使用了tensorflow里面自帶的深度神經網絡分類器tf.estimator.DNNClassifie。這些tensorflow自帶的estimator稱為預制估算器Pre-made Estimator(預創建的Estimator)。

classifier = tf.estimator.DNNClassifier(feature_columns=feature_columns,hidden_units=[10, 10],n_classes=3,model_dir=models_path,config=ckpt_config) #

Tensorflow允許我們自己創建更加靈活的Custom Estimator。自定義Estimator是tf.estimator.Estimator()方法生成,能夠像預制Estimator一樣使用。

?


結構概覽

從表面看,我們的Estimator應該具有DNNClassifier一樣的功能

  • 創建的時候接收一些參數,如feature_columns、hidden_units、n_classes等
  • 具有train()、evaluate()、predict()三個方法用來訓練、評價、預測

如上所說,我們使用 tf.estimator.Estimator()方法來生成自定義Estimator,它的語法格式是

tf.estimator.Estimator(model_fn, #模型函數model_dir=None, #存儲目錄config=None, #設置參數對象params=None, #超參數,將傳遞給model_fn使用warm_start_from=None #熱啟動目錄路徑 )

模型函數model_fn是唯一沒有默認值的參數,它也是自定義Estimator最關鍵的部分,包含了最核心的算法。model_fn需要一個能夠進行運算的函數,它的樣子應該長成這樣

my_model(features, #輸入的特征數據labels, #輸入的標簽數據mode, #train、evaluate或predictparams #超參數,對應上面Estimator傳來的參數 )

神經網絡層Layers

model_fn應該怎么運作?下圖展示了iris案例的情況

?

?

從這個圖中我沒看到的結構:

  • 輸入層Input Layer,數據從這里進入
  • 隱藏層Hidden Layer,2個,每層包含多個節點,數據流經這里,被推測規律
  • 輸出層Output Layer,將推測的結果整理顯示出來

我們并不需要手工實現隱藏層的算法和工作原理,Tensorflow已經為我們設計好。我們需要的只是創建這些神經網絡層,并確保它們按照正常的順序連接起來,至于其中如何推算演繹的魔法就完全交給tensorflow就可以了。

mode_fn需要完成的就是創建和組織這些神經層。


編寫model_fn

對應我們創建Estimator時候的參數

classifier = tf.estimator.DNNClassifier(feature_columns=feature_columns,hidden_units=[10, 10],n_classes=3,model_dir=models_path,config=ckpt_config)

這些參數都會被Estimator打包放在params超參數中,傳遞給model_fn,所以我們用下面的代碼在model_fn內創建網絡層

import tensorflow as tf#自定義模型函數 def my_model_fn(features,labels,mode,params):#輸入層,feature_columns對應Classifier(feature_columns=...)net = tf.feature_column.input_layer(features, params['feature_columns'])#隱藏層,hidden_units對應Classifier(unit=[10,10]),2個各含10節點的隱藏層for units in params['hidden_units']:net = tf.layers.dense(net, units=units, activation=tf.nn.relu)#輸出層,n_classes對應3種鳶尾花logits = tf.layers.dense(net, params['n_classes'], activation=None)

輸入層Input Layer

在上面代碼中,我們使用這行代碼創建輸入層

net = tf.feature_column.input_layer(features, params['feature_columns'])

如下圖所示,Input Layer把輸入的數據features填充到特征列params['feature_column']里面,稍后它會被繼續傳遞到隱藏層hidden layer:

?

輸入層Input Layer


隱藏層Hidden Layer

我們使用循環為hidden_unit列表([10,10])創建了2個隱藏圖層,每個圖層的神經元節點unit都等于10.

for units in params['hidden_units']:net = tf.layers.dense(net, units=units, activation=tf.nn.relu)

我們注意到上面的輸入層叫做net(暫時叫net0),for循環里的隱藏層也叫net(暫叫net1)而且參數里還有net(net2),示意代碼如下

#僅供示意 net0 = tf.feature_column.input_layer... for units ...net1 = tf.layers.dense(net2, ...)

實際運行到隱藏層第一層(for循環第一次)的時候,我們創建隱藏層net1,并把net0作為參數輸入到net1的,也就是隱藏第一層中關聯了輸入層:

input_net0=...#創建輸入層 hidden_net1=tf.layers.dense(input_net0,...) #創建隱藏層1

然后for第二次循環的時候我們又關聯了第一個隱藏層hidden_net1:

hidden_net2=tf.layers.dense(hidden_net1,...) #創建隱藏層2

這樣逐層傳遞就形成了鏈條,數據沿著鏈條進行流動Flow和處理

intputLayer - hiddenLayer1 - hiddenLayer2 - ...

隱藏層Hidden layer


輸出層Output Layer

我們使用了這行代碼創建輸出層,請注意net!

logits = tf.layers.dense(net, params['n_classes'], activation=None)

仍然是鏈條的延續!
但是activation這里改為了None,不再激活后續的部分,所以輸出層就是鏈條的終點。

?

輸出層Output Layer

請注意這里的[-1.3,2.6,-0.9]表示了某朵花的測量數據分別屬于三種分類的可能性,但是這里的數字很奇怪,甚至還有負數...稍后我們會對它們進行轉化。


訓練train、評價evaluate和預測predict

前面我們知道,自定義的估算分類器必須能夠用來執行my_classifier.train()、my_classifier.evaluate()、my_classifier.predict()三個方法。

但實際上,它們都是model_fn這一個函數的分身!

上面出現的model_fn語法:

my_model(features, #輸入的特征數據labels, #輸入的標簽數據mode, #train、evaluate或predictparams #超參數,對應上面Estimator傳來的參數 )

注意第三個參數mode,如果它等于"TRAIN"我們就執行訓練:

#示意代碼 my_model(..,..,"TRAIN",...)

如果是“EVAL”就執行評價,“PREDICT”就執行預測。

我們修改my_model代碼來實現這三個功能:

def my_model_fn(features,labels,mode,params):#輸入層,feature_columns對應Classifier(feature_columns=...)net = tf.feature_column.input_layer(features, params['feature_columns'])#隱藏層,hidden_units對應Classifier(unit=[10,10]),2個各含10節點的隱藏層for units in params['hidden_units']:net = tf.layers.dense(net, units=units, activation=tf.nn.relu)#輸出層,n_classes對應3種鳶尾花logits = tf.layers.dense(net, params['n_classes'], activation=None)#預測predicted_classes = tf.argmax(logits, 1) #預測的結果中最大值即種類if mode == tf.estimator.ModeKeys.PREDICT:predictions = {'class_ids': predicted_classes[:, tf.newaxis], #拼成列表[[3],[2]]格式'probabilities': tf.nn.softmax(logits), #把[-1.3,2.6,-0.9]規則化到0~1范圍,表示可能性'logits': logits,#[-1.3,2.6,-0.9]}return tf.estimator.EstimatorSpec(mode, predictions=predictions)#損失函數loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)#訓練if mode == tf.estimator.ModeKeys.TRAIN:optimizer = tf.train.AdagradOptimizer(learning_rate=0.1) #用它優化損失函數,達到損失最少精度最高train_op = optimizer.minimize(loss, global_step=tf.train.get_global_step()) #執行優化!return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op) #評價accuracy = tf.metrics.accuracy(labels=labels,predictions=predicted_classes,name='acc_op') #計算精度metrics = {'accuracy': accuracy} #返回格式tf.summary.scalar('accuracy', accuracy[1]) #僅為了后面圖表統計使用if mode == tf.estimator.ModeKeys.EVAL:return tf.estimator.EstimatorSpec(mode, loss=loss, eval_metric_ops=metrics)

如上面所示,請將預測Predict需要放在最先編寫,否則可以引發后續錯誤。

下面我們分別詳解三個方法的代碼


預測Predict

因為預測最后我們需要返回花的種類label,還希望知道這個預測有多精確,所以在預測部分的代碼里面,首先取到三種花可能性最大的一個predicted_classes即[-1.3,2.6,-0.9]中的2.6;然后把它轉成列表格式[[2.6]];同時把logit得到的[-1.3,2.6,-0.9]轉化為表示0~1可能性的小數[0.01926995 0.95198274 0.02874739]

predicted_classes = tf.argmax(logits, 1) #預測的結果中最大值即種類if mode == tf.estimator.ModeKeys.PREDICT:predictions = {'class_ids': predicted_classes[:, tf.newaxis], #拼成列表[[3],[2]]格式'probabilities': tf.nn.softmax(logits), #把[-1.3,2.6,-0.9]規則化到0~1范圍,表示可能性'logits': logits,#[-1.3,2.6,-0.9]}return tf.estimator.EstimatorSpec(mode, predictions=predictions)

注意最后一句,我們返回return的是一個EstimatorSpec對象,下面的訓練predict和評價evaluate也都返回EstimatorSpec形式的對象,但是參數不同,請留意。

我們可以使用以下代碼在單獨文件測試tf.newaxis和tf.nn.softmax對數據轉化的作用

import tensorflow as tfa=tf.constant([2.6],name='a') b=a[:,tf.newaxis]a2=tf.constant([-1.3,2.6,-0.9],name='a') b2= tf.nn.softmax(a2)with tf.Session() as session: session.run(tf.global_variables_initializer())session.run(tf.tables_initializer())print(session.run(b))print(session.run(b2))

輸出

[[2.6]] [0.01926995 0.95198274 0.02874739]

損失函數Loss

損失函數是Tensorflow中神經網絡的重要概念,簡單說,它能夠計算出我們模型的偏差程度,結果越大,我們的模型就偏差越大、離正確也遠、也越不準確、越糟糕。

為了降低損失,我們可以使用更多更好的數據,還可以設計更好的優化方法,來優化改進模型,讓損失變為最小。

訓練神經網絡模型的目標就是把偏差損失降為最小,機器學習就是一批一批數據反復分析計算反復嘗試,不斷的利用優化方法,想盡辦法把Loss的值降到最小的過程。

優化方法設計的越好好,損失也就越少,精度也就越高。

loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

這里我們使用了tensorflow提供的稀疏柔性最大交叉熵sparse_softmax_cross_entropy來計算損失程度,它對于分類問題很有效,DNNClassifier也使用了這個方法。


訓練Train

我們在訓練部分代碼中,創建了優化器optimizer,然后使用它嘗試將我們的損失函數loss變為最小minimize:

if mode == tf.estimator.ModeKeys.TRAIN:optimizer = tf.train.AdagradOptimizer(learning_rate=0.1) #用它優化損失函數,達到損失最少精度最高train_op = optimizer.minimize(loss, global_step=tf.train.get_global_step()) #執行優化!return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)

評價Evaluate

我們使用下面的代碼來評價預測結果prediction和test數據中植物學家標記的數據是否足夠吻合:

accuracy = tf.metrics.accuracy(labels=labels,predictions=predicted_classes,name='acc_op') #計算精度metrics = {'accuracy': accuracy} #返回格式tf.summary.scalar('accuracy', accuracy[1]) #僅為了后面圖表統計使用if mode == tf.estimator.ModeKeys.EVAL:return tf.estimator.EstimatorSpec(mode, loss=loss, eval_metric_ops=metrics)

因為我們希望能夠評價后知道模型的精度,所以首先使用tf.metrics.accuracy方法對比植物學家的標記labels和批量預測結果predicted_classes([[-1.3,2.6,-0.9],...]),


導入數據

相關文件可以從百度云這里下載 密碼:y3id

經過上面的過程,我們創建了估算分類器的核心部分model_fn,接下來我們繼續添加以下代碼,導入數據備用。具體解釋請參照鳶尾花iris案例

import os import pandas as pdFUTURES = ['SepalLength', 'SepalWidth','PetalLength', 'PetalWidth', 'Species'] SPECIES = ['Setosa', 'Versicolor', 'Virginica']dir_path = os.path.dirname(os.path.realpath(__file__)) train_path=os.path.join(dir_path,'iris_training.csv') test_path=os.path.join(dir_path,'iris_test.csv')train = pd.read_csv(train_path, names=FUTURES, header=0) train_x, train_y = train, train.pop('Species')test = pd.read_csv(test_path, names=FUTURES, header=0) test_x, test_y = test, test.pop('Species')

創建分類器

繼續添加代碼,使用model_fn來生成自定義分類器(請注意最后幾行):

feature_columns = [] for key in train_x.keys():feature_columns.append(tf.feature_column.numeric_column(key=key))#創建自定義分類器 classifier = tf.estimator.Estimator(model_fn=my_model, #注意這里!params={'feature_columns': feature_columns,'hidden_units': [10, 10],'n_classes': 3,})

訓練模型

添加下面代碼開始訓練模型

#針對訓練的喂食函數 batch_size=100 def train_input_fn(features, labels, batch_size):dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))dataset = dataset.shuffle(1000).repeat().batch(batch_size) #每次隨機調整數據順序return dataset.make_one_shot_iterator().get_next()#開始訓練 classifier.train(input_fn=lambda:train_input_fn(train_x, train_y, 100),steps=1000)

評價模型

添加下面的代碼可以對模型進行評價并打印出精度

#針對測試的喂食函數 def eval_input_fn(features, labels, batch_size):features=dict(features)inputs=(features,labels)dataset = tf.data.Dataset.from_tensor_slices(inputs)dataset = dataset.batch(batch_size) # return datasetreturn dataset.make_one_shot_iterator().get_next()#評估我們訓練出來的模型質量 eval_result = classifier.evaluate(input_fn=lambda:eval_input_fn(test_x, test_y,batch_size))print(eval_result)

進行預測

添加以下代碼讓用我們的模型可以進行交互預測

#支持100次循環對新數據進行分類預測 for i in range(0,100):print('\nPlease enter features: SepalLength,SepalWidth,PetalLength,PetalWidth')a,b,c,d = map(float, input().split(',')) #捕獲用戶輸入的數字predict_x = {'SepalLength': [a],'SepalWidth': [b],'PetalLength': [c],'PetalWidth': [d],}#進行預測predictions = classifier.predict(input_fn=lambda:eval_input_fn(predict_x,labels=[0,],batch_size=batch_size)) #預測結果是數組,盡管實際我們只有一個for pred_dict in predictions:class_id = pred_dict['class_ids'][0]probability = pred_dict['probabilities'][class_id]print(SPECIES[class_id],100 * probability)

模型的恢復與保存設置

修改創建估算分類器的代碼設置model_dir模型保存與自動恢復,并設定日志打印

tf.logging.set_verbosity(tf.logging.INFO) models_path=os.path.join(dir_path,'mymodels/')#創建自定義分類器 classifier = tf.estimator.Estimator(model_fn=my_model_fn,model_dir=models_path,params={'feature_columns': feature_columns,'hidden_units': [10, 10],'n_classes': 3,})

TensorBoard信息板

打開新的命令行工具窗口,使用下面的命令啟動信息板:

tensorboard --logdir=~/desktop/iris/mymodels

這里的~/desktop/iris/models應該和上面配置的model_dir=models_path完全一致,正常情況會輸出很多信息,并在最后顯示類似下面的提示

TensorBoard 1.6.0 at http://xxx-xxx-xxx.local:6006 (Press CTRL+C to quit)

把這段http://xxx-xxx-xxx.local:6006復制到瀏覽器窗口,或者復制http://localhost:6006/就可以打開TensorBoard信息板,這里包含了很多關于模型的性能質量等方面的圖表:

關于TensorBoard更多內容可以點右上角的問號打開Github上的項目詳細說明。


上面的代碼和相關文件可以從百度云這里下載 密碼:y3id


探索人工智能的新邊界

如果您發現文章錯誤,請不吝留言指正;
如果您覺得有用,請點喜歡;
如果您覺得很有用,感謝轉發~



作者:zhyuzh3d
鏈接:https://www.jianshu.com/p/5495f87107e7
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。

總結

以上是生活随笔為你收集整理的Tensorflow-Estimator-自定义估算器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。