(tensorflow)——tf.estimator自定義估算器使用方法
文章結構
- 1.簡介
- 2.自定義Estimator與pre-made Estimator
- 3.使用Pre-made Estimator
- 4.入門 Custom Estimator
- 4.1 Write an Input function
- 4.2 Create feature columns
- 4.3 Write a model function
- 4.3.1 Define the model
- Define the input layer
- Hidden Layers
- Output Layer
- 4.3.2 Implement training, evaluation, and prediction
- Predict
- Calculate the loss
- Evaluate
- Train
- 4.3.1 Define the model
- 5 實戰 Custom Estimator
- step 1: 初始化一個tf.estimator.Estimator例項
- step 2: 寫model_fn
- step 3: Define the model
- step 4: Implement training, evaluation, and prediction
- step 5: 開始訓練
1 簡介
在TensorFlow的UG中,他們強烈的建議在寫Tensorflow程式時使用estimator的API,使用後發現的確好用!在github上一些開源程式也已經開始使用estimator,比如
官方原話:
We strongly recommend writing TensorFlow programs with the following APIs:
· Estimators, which represent a complete model. The Estimator API provides methods to train the model, to judge the model’s accuracy, and to generate predictions.
· Datasets for Estimators
TensorFlow官方文件對Estimator的定義是:High level tools for working with models.
它已經包含了一些內建的機器學習或者深度學習演算法模型(Premade Estimators),比如:
BaselineClassifier
BaselineRegressor
BestExporter
BoostedTreesClassifier
BoostedTreesRegressor
DNNClassifier
DNNLinearCombinedClassifier
DNNLinearCombinedRegressor
DNNRegressor
我們可以直接使用上面的模型進行深度學習演算法的驗證和實現。
2 自定義Estimator與pre-made Estimator
pre-made Estimator是別人寫好的模型(model_fn);自定義estimator需要自己設計模型
首先我們要對pre-made Estimator和custom Estimator的關係有一個清晰的理解:
3 使用Pre-made Estimator
我很少會用到pre-made Estimator,這裡就不做介紹了,感興趣可以參考官方UG
4 入門 Custom Estimator
我的另一篇部落格中介紹了DeeplabV3+,原始碼中就是使用了Custom Estimator,這份原始碼是一個不錯的例項。
此處我們首先另起爐灶,舉一個更加簡單的例子。之後再談論DeeplabV3+這個程式。
4.1 Write an Input function
def train_input_fn(features, labels, batch_size):
"""An input function for training"""
# Convert the inputs to a Dataset.
dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))
# Shuffle, repeat, and batch the examples.
dataset = dataset.shuffle(1000).repeat().batch(batch_size)
# Return the read end of the pipeline.
return dataset.make_one_shot_iterator().get_next()
這個輸入函式建立了一個input pipline,每次提取batch大小的(features, labels)
4.2 Create feature columns
我們必須定義模型的feature columns來明確我們的模型應該如何使用各個feature
# Feature columns describe how to use the input.
my_feature_columns = []
for key in train_x.keys():
my_feature_columns.append(tf.feature_column.numeric_column(key=key))
4.3 Write a model function
Custom Estimator應該和DNNClassifier等Pre-made Estimator具有相同的介面:
tf.estimator.Estimator(
model_fn, #模型函式
model_dir=None, #儲存目錄,訓練和驗證產生的檔案都會儲存在這個目錄下
config=None, #設定引數物件,主要針對執行環境的一些設定
params=None, #超引數,將傳遞給model_fn使用
warm_start_from=None #熱啟動目錄路徑
)
其中最重要的就是model_fn了,它應該具有以下形式:
my_model(
features, #This is batch_features from input_fn
labels, #This is batch_labels from input_fn
mode, #An instance of tf.estimator.ModeKeys, train、evaluate或predict
params #超引數,對應上面Estimator傳來的引數
)
4.3.1 Define the model
上面的4.3只是寫了一個函式介面,我們還要進一步詳細的定義模型。
- An input layer
- One or more hidden layers
- An output layer
4.3.1.1 Define the input layer
model_fn的第一行就應該呼叫 tf.feature_column.input_layer ,把feature dictionary和feature_columes匯入模型中:
# Use `input_layer` to apply the feature columns.
net = tf.feature_column.input_layer(features, params['feature_columns'])
這句話建立了模型input layer並完成了feature columns中定義的轉換
4.3.1.2 Hidden Layers
hidden layers不用多說,建立之後網路呈現如下結構
4.3.1.3 Output Layer
注意,activation=None;
units = params[‘n_classes’],這個實在構造estimator時就已經設定好了
我們把outlayer中的logits傳入softmax,就可以輸出概率分佈。
# Compute logits (1 per class).
logits = tf.layers.dense(net, params['n_classes'], activation=None)
4.3.2 Implement training, evaluation, and prediction
到此為止,模型已經定義好了,我們要著手實現模型的training,evaluation,prediction等功能。
4.3.2.1 Predict
# Compute predictions.
predicted_classes = tf.argmax(logits, 1)
if mode == tf.estimator.ModeKeys.PREDICT:
predictions = {
'class_ids': predicted_classes[:, tf.newaxis],
'probabilities': tf.nn.softmax(logits),
'logits': logits,
}
return tf.estimator.EstimatorSpec(mode, predictions=predictions)
4.3.2.2 Calculate the loss
this is the object that will be optimized !!!
train和evaluate都需要使用它
# Compute loss.
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
4.3.2.3 Evaluate
tensorflow提供API去評價一個model的效能,比如tf.metrics
# Compute evaluation metrics.
accuracy = tf.metrics.accuracy(labels=labels,
predictions=predicted_classes,
name='acc_op')
如果我們還需要看其他的評價指標,比如roi等,可以把roi加入metrics字典中去。以下為完整寫法。
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)
4.3.2.4 Train
- 首先制定優化器
optimizer = tf.train.AdagradOptimizer(learning_rate=0.1)
- 然後確定train_op
train_op = optimizer.minimize(loss, global_step=tf.train.get_global_step())
- 最後返回
return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
5 實戰 Custom Estimator
step 1: 初始化一個tf.estimator.Estimator例項
# Set up a RunConfig to only save checkpoints once per training cycle.
run_config = tf.estimator.RunConfig().replace(save_checkpoints_secs=1e9)
model = tf.estimator.Estimator(
model_fn=deeplab_model.deeplabv3_plus_model_fn,
model_dir=FLAGS.model_dir,
config=run_config,
params={
'output_stride': FLAGS.output_stride,
'batch_size': FLAGS.batch_size,
'base_architecture': FLAGS.base_architecture,
'pre_trained_model': FLAGS.pre_trained_model,
'batch_norm_decay': _BATCH_NORM_DECAY,
'num_classes': _NUM_CLASSES,
'tensorboard_images_max_outputs': FLAGS.tensorboard_images_max_outputs,
'weight_decay': FLAGS.weight_decay,
'learning_rate_policy': FLAGS.learning_rate_policy,
'num_train': _NUM_IMAGES['train'],
'initial_learning_rate': FLAGS.initial_learning_rate,
'max_iter': FLAGS.max_iter,
'end_learning_rate': FLAGS.end_learning_rate,
'power': _POWER,
'momentum': _MOMENTUM,
'freeze_batch_norm': FLAGS.freeze_batch_norm,
'initial_global_step': FLAGS.initial_global_step
})
step 2: 寫model_fn
從上面estimator的初始化中:
model_fn=deeplab_model.deeplabv3_plus_model_fn
在deeplab_model.py中定義了該函式,可以看出該函式保持了model_fn應該有的介面
def deeplabv3_plus_model_fn(features, labels, mode, params):
"""Model function for PASCAL VOC."""
# features 是傳進來用於訓練網路的影象
if isinstance(features, dict):
features = features['feature']
#對影象的各通道進行減去平均值,屬於預處理的一部分
images = tf.cast(
tf.map_fn(preprocessing.mean_image_addition, features),
tf.uint8)
step3 Define the model
定義模型同樣在model_fn中
#使用generator函式生成網路
network = deeplab_v3_plus_generator(params['num_classes'],
params['output_stride'],
params['base_architecture'],
params['pre_trained_model'],
params['batch_norm_decay'])
#mode == tf.estimator.ModeKeys.TRAIN
#在train模式下網路的輸出
logits = network(features, mode == tf.estimator.ModeKeys.TRAIN)
#根據logits得出各畫素點屬於的類別
pred_classes = tf.expand_dims(tf.argmax(logits, axis=3, output_type=tf.int32), axis=3)
network使用deeplab_v3_plus_generator函式生成
def deeplab_v3_plus_generator(num_classes,
output_stride,
base_architecture,
pre_trained_model,
batch_norm_decay,
data_format='channels_last'):
"""Generator for DeepLab v3 plus models.
Args:
num_classes: The number of possible classes for image classification.
output_stride: The ResNet unit's stride. Determines the rates for atrous convolution.
the rates are (6, 12, 18) when the stride is 16, and doubled when 8.
base_architecture: The architecture of base Resnet building block.
pre_trained_model: The path to the directory that contains pre-trained models.
batch_norm_decay: The moving average decay when estimating layer activation
statistics in batch normalization.
data_format: The input format ('channels_last', 'channels_first', or None).
If set to None, the format is dependent on whether a GPU is available.
Only 'channels_last' is supported currently.
Returns:
The model function that takes in `inputs` and `is_training` and
returns the output tensor of the DeepLab v3 model.
"""
if data_format is None:
# data_format = (
# 'channels_first' if tf.test.is_built_with_cuda() else 'channels_last')
pass
if batch_norm_decay is None:
batch_norm_decay = _BATCH_NORM_DECAY
if base_architecture not in ['resnet_v2_50', 'resnet_v2_101']:
raise ValueError("'base_architrecture' must be either 'resnet_v2_50' or 'resnet_v2_101'.")
#確定模型的主體網路是resnet50還是resnet101,這裡使用的是 from tensorflow.contrib.slim.nets import resnet_v2
#原始碼檢視網址:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/slim/python/slim/nets/resnet_v2.py
if base_architecture == 'resnet_v2_50':
base_model = resnet_v2.resnet_v2_50
else:
base_model = resnet_v2.resnet_v2_101
def model(inputs, is_training):
"""Constructs the ResNet model given the inputs."""
if data_format == 'channels_first':
# Convert the inputs from channels_last (NHWC) to channels_first (NCHW).
# This provides a large performance boost on GPU. See
# https://www.tensorflow.org/performance/performance_guide#data_formats
inputs = tf.transpose(inputs, [0, 3, 1, 2])
# tf.logging.info('net shape: {}'.format(inputs.shape))
# encoder
with tf.contrib.slim.arg_scope(resnet_v2.resnet_arg_scope(batch_norm_decay=batch_norm_decay)):
#resnet_v2的返回值是net, end_points
#其中net是 A rank-4 tensor of size [batch, height_out, width_out, channels_out].
#end_points中記錄了網路中不同功能的元件,以字典形式
#對於deeplabv3+,這裡的logits也就是net,是不需要的,因為我們還需要對這個網路進行變形,得到正確的輸出
logits, end_points = base_model(inputs,
num_classes=None,
is_training=is_training,
global_pool=False,
output_stride=output_stride)
if is_training:
#實際上我們不需要base_model的logits節點,所以這部分設定為不恢復
#可以參考部落格《使用slim從ckpt裡匯出指定層的引數》:https://www.jianshu.com/p/160620fb2580
exclude = [base_architecture + '/logits', 'global_step']
variables_to_restore = tf.contrib.slim.get_variables_to_restore(exclude=exclude)
#pre_trained_model是存放預訓練模型的路徑,引數用來fine-tune
tf.train.init_from_checkpoint(pre_trained_model,
{v.name.split(':')[0]: v for v in variables_to_restore})
inputs_size = tf.shape(inputs)[1:3]
#去除resnet的block4的輸出,也就是最後一個卷積層的輸出
net = end_points[base_architecture + '/block4']
#使用 空洞空間金字塔池化
encoder_output = atrous_spatial_pyramid_pooling(net, output_stride, batch_norm_decay, is_training)
#設計 decoder解碼器
with tf.variable_scope("decoder"):
with tf.contrib.slim.arg_scope(resnet_v2.resnet_arg_scope(batch_norm_decay=batch_norm_decay)):
with arg_scope([layers.batch_norm], is_training=is_training):
with tf.variable_scope("low_level_features"):
low_level_features = end_points[base_architecture + '/block1/unit_3/bottleneck_v2/conv1']
low_level_features = layers_lib.conv2d(low_level_features, 48,
[1, 1], stride=1, scope='conv_1x1')
low_level_features_size = tf.shape(low_level_features)[1:3]
with tf.variable_scope("upsampling_logits"):
net = tf.image.resize_bilinear(encoder_output, low_level_features_size, name='upsample_1')
net = tf.concat([net, low_level_features], axis=3, name='concat')
net = layers_lib.conv2d(net, 256, [3, 3], stride=1, scope='conv_3x3_1')
net = layers_lib.conv2d(net, 256, [3, 3], stride=1, scope='conv_3x3_2')
net = layers_lib.conv2d(net, num_classes, [1, 1], activation_fn=None, normalizer_fn=None, scope='conv_1x1')
logits = tf.image.resize_bilinear(net, inputs_size, name='upsample_2')
return logits
return model
最後返回的是logits,至此網路就設計好了。
step4 Implement training, evaluation, and prediction
重新回到model_fn函式中,我們還需要實現training, evaluation, prediction功能
- For mode == ModeKeys.TRAIN: required fields are loss and train_op.
- For mode == ModeKeys.EVAL: required field is loss.
- For mode == ModeKeys.PREDICT: required fields are predictions.
*1、Prediction
#解碼預測得到的labels,即pred_classes
#得到RGB影象,每個類別不同顏色
pred_decoded_labels = tf.py_func(preprocessing.decode_labels,
[pred_classes, params['batch_size'], params['num_classes']],
tf.uint8)
# 首先 定義predictions供predict模式使用
predictions = {
'classes': pred_classes,
'probabilities': tf.nn.softmax(logits, name='softmax_tensor'),
'decoded_labels': pred_decoded_labels
}
if mode == tf.estimator.ModeKeys.PREDICT:
# Delete 'decoded_labels' from predictions because custom functions produce error when used with saved_model
predictions_without_decoded_labels = predictions.copy()
del predictions_without_decoded_labels['decoded_labels']
return tf.estimator.EstimatorSpec(
mode=mode,
predictions=predictions,
export_outputs={
'preds': tf.estimator.export.PredictOutput(
predictions_without_decoded_labels)
})
2、training
gt_decoded_labels = tf.py_func(preprocessing.decode_labels,
[labels, params['batch_size'], params['num_classes']], tf.uint8)
labels = tf.squeeze(labels, axis=3) # reduce the channel dimension.
logits_by_num_classes = tf.reshape(logits, [-1, params['num_classes']])
labels_flat = tf.reshape(labels, [-1, ])
valid_indices = tf.to_int32(labels_flat <= params['num_classes'] - 1)
valid_logits = tf.dynamic_partition(logits_by_num_classes, valid_indices, num_partitions=2)[1]
valid_labels = tf.dynamic_partition(labels_flat, valid_indices, num_partitions=2)[1]
preds_flat = tf.reshape(pred_classes, [-1, ])
valid_preds = tf.dynamic_partition(preds_flat, valid_indices, num_partitions=2)[1]
confusion_matrix = tf.confusion_matrix(valid_labels, valid_preds, num_classes=params['num_classes'])
predictions['valid_preds'] = valid_preds
predictions['valid_labels'] = valid_labels
predictions['confusion_matrix'] = confusion_matrix
cross_entropy = tf.losses.sparse_softmax_cross_entropy(
logits=valid_logits, labels=valid_labels)
# Create a tensor named cross_entropy for logging purposes.
tf.identity(cross_entropy, name='cross_entropy')
tf.summary.scalar('cross_entropy', cross_entropy)
if not params['freeze_batch_norm']:
train_var_list = [v for v in tf.trainable_variables()]
else:
train_var_list = [v for v in tf.trainable_variables()
if 'beta' not in v.name and 'gamma' not in v.name]
# Add weight decay to the loss.
with tf.variable_scope("total_loss"):
loss = cross_entropy + params.get('weight_decay', _WEIGHT_DECAY) * tf.add_n(
[tf.nn.l2_loss(v) for v in train_var_list])
# loss = tf.losses.get_total_loss() # obtain the regularization losses as well
if mode == tf.estimator.ModeKeys.TRAIN:
tf.summary.image('images',
tf.concat(axis=2, values=[images, gt_decoded_labels, pred_decoded_labels]),
max_outputs=params['tensorboard_images_max_outputs']) # Concatenate row-wise.
global_step = tf.train.get_or_create_global_step()
if params['learning_rate_policy'] == 'piecewise':
# Scale the learning rate linearly with the batch size. When the batch size
# is 128, the learning rate should be 0.1.
initial_learning_rate = 0.1 * params['batch_size'] / 128
batches_per_epoch = params['num_train'] / params['batch_size']
# Multiply the learning rate by 0.1 at 100, 150, and 200 epochs.
boundaries = [int(batches_per_epoch * epoch) for epoch in [100, 150, 200]]
values = [initial_learning_rate * decay for decay in [1, 0.1, 0.01, 0.001]]
learning_rate = tf.train.piecewise_constant(
tf.cast(global_step, tf.int32), boundaries, values)
elif params['learning_rate_policy'] == 'poly':
learning_rate = tf.train.polynomial_decay(
params['initial_learning_rate'],
tf.cast(global_step, tf.int32) - params['initial_global_step'],
params[
相關推薦
(tensorflow)——tf.estimator自定義估算器使用方法
文章結構
1.簡介
2.自定義Estimator與pre-made Estimator
3.使用Pre-made Estimator
4.入門 Custom Estimator
4.1 Write an Input function
4.2 Create
在struts2中配置自定義攔截器放行多個方法
return med ttr limit ring req tac cat invoke 源碼:
自定義的攔截器類:
//自定義攔截器類:LoginInterceptor ;
package com.java.action.interceptor;
import j
9.12 URL控制器之path方法--內建轉換器,自定義轉換器
兩個用法一致:
django 1.0 : url
django2.0 : re_path
基於以下2個需求,django2.0 又加了path方法:
一、使用內建轉換器
內建轉換器有:
二、自定義轉換器:
1.
SpringMVC同時使用<mvc:resources … />和裝配自定義轉換器Converter時出現問題的解決方法
一、問題由來
在學習SpringMVC的過程中,對於URL的攔截,使用了RESTful形式,因為使用了RESTful所以,在將Servlet作為Controller中的時候,web.xml中配置攔截的url-pattern就寫成了 / ,如下所示:
<servlet>
<
利用List的sort方法,自定義比較器對類屬性進行排序
JDK1.8之後,List新增了sort方法,使用Comparator作為引數,呼叫者可自定義比較規則。
User user1 = new User(12, "張三");
User use
tensorflow中RNNcell原始碼分析以及自定義RNNCell的方法
我們在模擬一些論文的時候經常會遇到一些模型,對RNN或者LSTM進行了少許的修改,或者自己定義了一種RNN的結構等情況,比如前面介紹的幾篇memory networks的論文,往往都需要按照自己定義的方法來構造RNN網路。所以本篇部落格就主要總結一下RNNcel
Django入門學習(7)——自定義管理器和模型類的建立方法
自定義管理器的目的1:更改查詢集# -*- coding:utf-8 -*-
from django.db import models
class BookInfoManager(models.Manager):
def get_queryset(self):
Java中的equals方法和自定義比較器
class Student
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public S
淺談JavaScript--Array陣列sort()排序方法與自定義比較器的使用
陣列的排序的重要性不必多說,到處可見,現在來說說sort()方法的使用與自定義比較器
sort()方法:預設將陣列中的所有元素轉為字串後再排列(預設是升序),用來排列字串型別的元素
比如一個數組:
kindeditor編輯器新增自定義外掛的方法
KindEditor是一套開源的HTML視覺化編輯器,主要用於讓使用者在網站上獲得所見即所得編輯效果。說實話在使用這個編輯器以前,我也使用過別的編輯器,最後不是因為使用麻煩,就是因為程式太臃腫,而放棄使用,可是KindEditor不同,不僅結構小巧,而且功能強大,最主要的是
struts2自定義攔截器註解配置方法
自定義攔截器:
package com.penjing.interceptor;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONObject;
import
自定義攔截器 includeMethods和excludeMethods無效 解決方法
首先, includeMethods和excludeMethods都是需要自定義攔截器類繼承MethodFilterInterceptor,因為只有繼承這個類的自定義攔截器才有 setIncludeMethods和setExcludeMethods方法,這個我是網上找到的,但
Collections之sort的兩個方法(自然排序和自定義比較器排序)
Collections是個服務於Collection的工具類(靜態的),它裡面定義了一些集合可以用到的方法。
本文演示了Collections類裡sort()的兩個方法。第一種只需傳入被排序的集合,便會為它自然排序。但有時我們需要自定義排序的方式,這是我們就得定義一個比較器
vivado設定自定義編輯器與notepad++設定高亮方法
vivado2015.03下tools->option->general->text editor -> 選擇custom editor, 右邊的 ... 瀏覽按鈕,如下圖
SpringMVC 自定義轉換器
del 轉化 string sna 問題 print request package type 實踐SpringMVC轉化器是遇到的問題:表單提交沒有經過自定義轉換器(解決:表單用post方式提交)
自定義轉化器代碼
package cn.liangqinghai.
JAVAEE——struts2_04:自定義攔截器、struts2標簽、登陸功能和校驗登陸攔截器的實現
strac htm logs transacti 標識 area 返回 ftw jsp 一、自定義攔截器
1.架構
2.攔截器創建
//攔截器:第一種創建方式
//攔截器生命周期:隨項目的啟動而創建,隨項目關閉而銷毀
public class MyInt
struts2學習(6)自定義攔截器-登錄驗證攔截器
back tps class res urn fff .com space war 需求:對登錄進行驗證,用戶名cy 密碼123456才能登錄進去;
登錄進去後,將用戶存在session中;
其他鏈接要來訪問(除了登錄鏈接),首先驗證
手機影音第六天 自定義播放器頁面的實現(按鈕暫時未監聽)
手機影音第六天 自定義播放器布局以及橫豎屏切換播放器時的問題解決 目前進度的項目源代碼托管在裏碼雲上,地址如下: https://git.oschina.net/joy_yuan/MobilePlayer 感興趣的可以去下載看看,多多支持
自定義攔截器判斷用戶是否有權限訪問
indexof mon com source ora extend ide isa att 1、關於權限系統,對於用戶是否有權限對系統進行訪問,設置自定義攔截器,來攔截用戶的請求
1 package org.slsale.interceptor;
2
3 impo
Swift 自定義打印方法
orm rom -m http mat cti nbsp 使用 span Swift 自定義打印方法
#代碼如下
// MARK:- 自定義打印方法
func MLLog<T>(_ message : T, file : String = #file, fun