tensorflow2.0簡介

tensorflow2.0簡介

1、tensorflow 2.0基礎知識簡介

tensorflow2.0是谷歌在2019年3月份發佈更新的一款到端開源機器學習平臺,其目的在於優化tensorflow1.x版本,使其更靈活和易用性;2.0版本較1.x有較大的更新,具有簡易性、更清晰、擴展性三大特徵,大大簡化1.x 的API,其官方中文文檔鏈接如:https://github.com/geektutu/tensorflow2-docs-zh
它做了如下更新
• 使用 Keras 和 eager execution 輕鬆構建模型
• 在任意平臺上實現穩健的生產環境模型部署。
• 爲研究提供強大的實驗工具。
• 通過清理廢棄的 API 和減少重複來簡化 API,規範API
其架構圖如下

在這裏插入圖片描述

tensorflow2.0版本架構圖
註釋:

  • tf.keras
    Keras 的核心數據結構是 model,一種組織網絡層的方式。最簡單的模型是 Sequential 順序模型,它由多個網絡層線性堆疊。對於更復雜的結構,你應該使用 Keras 函數式 API,它允許構建任意的神經網絡圖
    參考鏈接 https://keras.io/zh/
  • tf.premade Estimators
    Premade Estimators 是類似於keras 一樣,是一種構建、訓練和驗證模型的方式
    實例參考鏈接:https://tensorflow.juejin.im/get_started/premade_estimators.html
    創建一個有兩個隱藏層和每層10個節點的 DNN
    classifier = tf.estimator.DNNClassifier(
    feature_columns=my_feature_columns,

    兩個隱藏層,每層 10 個節點。

    hidden_units=[10, 10],

    模型必須在 3 個類別中作出選擇

    n_classes=3)
  • TensorFlow Hub(需要tensorflow1.7及以上版本提供)
    tensorflow hub 的主要目標是爲模型提供一種簡便的封裝方式,同時可以簡便地複用已封裝的模型,可以說 tf hub 是爲遷移學習而生的。hub module 在使用時還能設定爲參數可訓練或者參數不可訓練,這樣對於不同的任務就能有更靈活的選擇。對於一些訓練樣本較少的情況,可以凍結底層 module 的參數
embedding = "https://tfhub.dev/google/tf2-preview/gnews-swivel-20dim/1"
hub_layer = hub.KerasLayer(embedding, input_shape=[], 
                           dtype=tf.string, trainable=True)
hub_layer(train_examples_batch[:3])
# 該層使用預先訓練的保存模型將句子映射到其嵌入向量。
# 使用的預訓練文本嵌入模型(google/tf2-preview/gnews-swivel-20dim/1)將句子拆分爲標記
# 嵌入每個標記然後組合嵌入。生成的維度爲:(num_examples, embedding_dimension)。
  • TensorFlow Serving
    允許模型通過 HTTP/REST 或 GRPC/協議緩衝區提供服務的 TensorFlow 庫構建。
  • TensorFlow Lite
    TensorFlow 針對移動和嵌入式設備的輕量級解決方案提供了在 Android、iOS 和嵌入式系統上部署模型的能力。
  • tensorflow.js
    支持在 JavaScript 環境中部署模型,例如在 Web 瀏覽器或服務器端通過 Node.js 部署模型。TensorFlow.js 還支持在 JavaScript 中定義模型,並使用類似於 Kera 的 API 直接在 Web 瀏覽器中進行訓練。

2、tensorflow2.0 工作流示例流程

tensorflow 工作流示例流程如下

1. 用 tf.data 加載數據。

用 tf.data 創建的輸入線程讀取訓練數據。使用 tf.feature_column 描述特徵特性,例如分段和特徵交叉。還支持從內存數據(例如 NumPy)中方便地輸入。
如:

# 輸入 Numpy 數據
import numpy as np
train_x = np.random.random((1000, 72))
train_y = np.random.random((1000, 10))
val_x = np.random.random((200, 72))
val_y = np.random.random((200, 10))
model.fit(train_x, train_y, epochs=10, batch_size=100,
validation_data=(val_x, val_y))
# tf.data 輸入數據
dataset = tf.data.Dataset.from_tensor_slices((train_x, train_y))
dataset = dataset.batch(32)
dataset = dataset.repeat()
val_dataset = tf.data.Dataset.from_tensor_slices((val_x, val_y))
val_dataset = val_dataset.batch(32)
val_dataset = val_dataset.repeat()
model.fit(dataset, epochs=10, steps_per_epoch=30,
          validation_data=val_dataset, validation_steps=3

2. 使用 tf.keras、Premade Estimators 構建、訓練和驗證模型。

Keras 與 TensorFlow 的其餘部分緊密集成,因此你可以隨時訪問 TensorFlow 的功能。一組標準的打包模型(例如,線性或邏輯迴歸、梯度提升樹、隨機森林)也可以直接使用(使用 tf.estimator API 實現)。
同時,它也提供在已有模型的基礎上繼續訓練模型,可通過 TensorFlow Hub 的模塊利用遷移學習來訓練 Keras 或 Estimator 模型。
tensorflow2.0推薦使用keras構建網絡,常見的網絡都包含在keras.layer中

3. 用 eager execution 運行和調試,然後在圖形上使用 tf.function。

TensorFlow 2.0 默認用 eager execution 運行,以便於輕鬆使用和順利調試。此外,tf.function 註釋透明地將 Python 程序轉換成 TensorFlow 圖。這個過程保留了 TensorFlow1.x 基於圖形執行的所有優點:性能優化、遠程執行,以及序列化、導出和部署的能力,同時增加了用簡單 Python 表達程序的靈活性和易用性。

4. 使用分佈式策略進行分佈式訓練。

對於大部分 ML 訓練任務來說,Distribution Strategy API 使得在不同的硬件配置上分佈和訓練模型變得很容易,而無需改變模型定義。由於 TensorFlow 爲一系列硬件加速器(如 CPU、GPU、TPU)提供支持,你可以將訓練工作負載分配給單節點/多加速器以及多節點/多加速器配置,包括 TPU Pods。儘管這個 API 支持多種羣集配置,但提供了在本地或雲環境中的 Kubernete 集羣上部署訓練的模板。

5. 保存模型( SavedModel)。

TensorFlow 將在 SavedModel 上標準化,來作爲 TentsorFlow Serving、TensorFlow Lite、TensorFlow.js、TentsorFlow Hub 等的交換格式。(tensorflow1.x 的SavedModels 或存儲的 GraphDefs 將向後兼容,用 TensorFlow 1.x 保存的 SavedModels 將繼續在 2.x 中加載和執行。然而,2.0 中的更改意味着原始檢查點中的變量名可能會更改,所以使用 2.0 之前的檢查點而代碼已轉化爲 2.0 時,可能無法保證有效)

3、tensorflow2.0 兼容性和連續性

爲了簡化向 TensorFlow 2.0 的過渡,將會有一個轉化工具來更新 TensorFlow 1.x Python 代碼,以使用 TensorFlow 2.0 兼容的 API,或標記代碼無法自動轉換的情況。但不是所有的變化都可以完全自動化進行。例如,一些被棄用的 API 沒有直接的等效物。這也是我們要引入 tensorflow.compat.v1 兼容性模塊的原因,該模塊支持完整的 TensorFlow 1.x API(包括 tf.contrib)。該模塊將會在 TensorFlow 2.x 的時間線內得到維護,並允許用 TensorFlow 1.x 編寫的代碼保持功能。
此外,SavedModel 和 GraphDef 將向後兼容。用 1.x 版本保存的 SavedModel 格式的模型將繼續在 2.x 版本中加載和執行。但是,2.0 版本中的變更將意味着原始檢查點中的變量名可能會更改,因此使用 2.0 版本之前的檢查點(代碼已轉換爲 2.0 版本)並不能保證正常工作。有關詳細信息,請參閱 TensorFlow 2.0 指南。

4、tensorflow 2.0與1.x區別

具體說來:
• 刪除 queue runner 以支持 tf.data。
• 刪除圖形集合。
• 變量處理方式的變化。
• API 符號的移動和重命名。
• tf.contrib 將從核心 TensorFlow 存儲庫和構建過程中移除

4.1 默認動態圖機制

在tensorflow2.0中,動態圖默認的是不需要自己主動啓動它

import tensorflow as tf
a=tf.constant([1,2,3])
b=tf.constant([2,1,3])
print(a+b)
# tf.Tensor([3,3,6]),shape=(3,0),dtype=int32

有了動態圖,大大減少了計算量,再也不需要啓動複雜的session和graph;
與此同時,2.0刪除了Variable_scopes和tf.get_Variable(),需要用面向對象的方式來處理變量共享

4.2 API 符號的移動和重命名&

具體改動
• summary

tf.histogram_summary(var.op.name, var) 改爲  tf.summaries.histogram()
tf.scalar_summary('images', images)改爲:tf.summary.scalar('images', images)
tf.image_summary('images', images)改爲:tf.summary.image('images', images)
tf.merge_all_summaries()改爲:summary_op = tf.summaries.merge_all()
tf.train.SummaryWriter改爲:tf.summary.FileWriter

• example loss

cifar10.loss(labels, logits) 改爲:cifar10.loss(logits=logits, labels=labels)

• 交叉熵

 cross_entropy = tf.nn.softmax_cross_entropy_with_logits( logits,dense_labels, name='cross_entropy_per_example')
改爲:
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(
        logits=logits, labels=dense_labels, name='cross_entropy_per_example')

• concat

concated = tf.concat(1, [indices, sparse_labels])改爲:
concated = tf.concat([indices, sparse_labels], 1)

4.3 棄用collections

tensorflow 1.x 中可以通過集合 (collection) 來管理不同類別的資源。例如使用tf.add_to_collection 函數可以將資源加入一個或多個集合。使用tf.get_collection獲取一個集合裏面的所有資源。這些資源可以是張量、變量或者運行 Tensorflow程序所需要的資源。我們在訓練神經網絡時會大量使用集合管理技術。如通過tf.add_n(tf.get_collection(“losses”)獲得總損失。
由於collection控制變量很不友好,在TensorFlow2.0中,棄用了collections,這樣代碼會更加清晰。
tensorflow2.0非常依賴Keras API(棄用tf.layers),因此如果你使用tf.keras,每個層都會處理自己的變量,當你需要獲取可訓練變量的列表,可直接查詢每個層。
如:

from tensorflow import keras
from tensorflow.keras import Sequential
model = Sequential([
   keras.layers.Dense(100,activation="relu",input_shape=[2]),
   keras.layers.Dense(100,activation="relu"),
   keras.layers.Dense(1)
])

可通過model.weights,就可以查詢每一層的可訓練的變量。結果如下面這種形式。

<tf.Variable'dense/kernel:0' shape=(2,100),dtype=float32,numpy=array([[...]]),dtype=float32)>,

參考鏈接:
[1] TensorFlow2.0 / TF2.0 Tutorial 入門教程實戰案例- https://zhuanlan.zhihu.com/p/72194796
[2] tensorflow hub 預訓練實例 https://blog.csdn.net/markmin214/article/details/90812605
[3] tensorflow2.0 簡介 https://baijiahao.baidu.com/s?id=1622717828293482437&wfr=spider&for=pc
[4] tensorflow2.0 官方文檔 https://github.com/geektutu/tensorflow2-docs-zh

二、實例

1.簡單實例


import tensorflow as tf
from tensorflow.keras import layers
print(tf.__version__)
print(tf.keras.__version__)
#模型堆疊
最常見的模型類型是層的堆疊:tf.keras.Sequential 模型
model = tf.keras.Sequential()
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))


## 網絡配置
#tf.keras.layers 中網絡配置:
#activation:設置層的激活函數。此參數由內置函數的名稱指定,或指定爲可調用對象。默認情況下,系統不會應用任何激活函數。
#kernel_initializer 和 bias_initializer:創建層權重(核和偏差)的初始化方案。此參數是一個名稱或可調用對象,默認爲 "Glorot uniform" 初始化器。
#kernel_regularizer 和 bias_regularizer:應用層權重(核和偏差)的正則化方案,例如 L1 或 L2 正則化。默認情況下,系統不會應用正則化函數。
layers.Dense(32, activation='sigmoid')
layers.Dense(32, activation=tf.sigmoid)
layers.Dense(32, kernel_initializer='orthogonal')
layers.Dense(32, kernel_initializer=tf.keras.initializers.glorot_normal)
layers.Dense(32, kernel_regularizer=tf.keras.regularizers.l2(0.01))
layers.Dense(32, kernel_regularizer=tf.keras.regularizers.l1(0.01))
#訓練和評估
## 設置訓練流程
### 構建好模型後,通過調用 compile 方法配置該模型的學習流程:
model = tf.keras.Sequential()
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss=tf.keras.losses.categorical_crossentropy,
              metrics=[tf.keras.metrics.categorical_accuracy])
# 輸入 Numpy 數據
import numpy as np
train_x = np.random.random((1000, 72))
train_y = np.random.random((1000, 10))
val_x = np.random.random((200, 72))
val_y = np.random.random((200, 10))
model.fit(train_x, train_y, epochs=10, batch_size=100,
validation_data=(val_x, val_y))
# tf.data 輸入數據
dataset = tf.data.Dataset.from_tensor_slices((train_x, train_y))
# from_tensor_slices 把第一維數據切開,切成 1000 個 72*10的張量切片
dataset = dataset.batch(32)
dataset = dataset.repeat()
val_dataset = tf.data.Dataset.from_tensor_slices((val_x, val_y))
val_dataset = val_dataset.batch(32)
val_dataset = val_dataset.repeat()
model.fit(dataset, epochs=10, steps_per_epoch=30,
          validation_data=val_dataset, validation_steps=3)
# 評估與預測
test_x = np.random.random((1000, 72))
test_y = np.random.random((1000, 10))
model.evaluate(test_x, test_y, batch_size=32)
test_data = tf.data.Dataset.from_tensor_slices((test_x, test_y))
test_data = test_data.batch(32).repeat()
model.evaluate(test_data, steps=30)
# predict
result = model.predict(test_x, batch_size=32)
print(result)
  • 張量切片 from_tensor_slices
train_imgs = tf.constant(['train/img1.png', 'train/img2.png',
                          'train/img3.png', 'train/img4.png',
                          'train/img5.png', 'train/img6.png'])
train_labels = tf.constant([0, 0, 0, 1, 1, 1])
tr_data = Dataset.from_tensor_slices((train_imgs, train_labels))
輸出:
(b'train/img1.png', 0)
(b'train/img2.png', 0)
(b'train/img3.png', 0)
(b'train/img4.png', 1)
(b'train/img5.png', 1)
(b'train/img6.png', 1)
  • batch repeat shuffle
    – dataset.batch: 作用是讀取batch_size大小的數據
    – dataset.repeat: 作用是將數據集重複多少次,即epoch
    – dataset.shuffle: 作用是將數據打亂
    這裏有兩種使用情況:
    情況一:
    dataset.shuffle(3)
    dataset.batch(4)
    dataset.repeat(2)
    將數據取完一個epoch後,再取一個epoch。因此每一個epoch中,最後一個batch大小可能小於等於batch size。
    情況二:
    dataset.repeat(2)
    dataset.shuffle(3)
    dataset.batch(4)
    先將數據重複2次,成爲一個大的數據,最後一個batch大小可能小於等於batch size 。而且一個batch_size中的數據可能會有重複。
    參考鏈接:https://blog.csdn.net/YQMind/article/details/82901442

2.函數式編程

# 構建高級模型
## 函數式 api
###tf.keras.Sequential 模型是層的簡單堆疊,無法表示任意模型。使用 Keras 函數式 API 可以構建複雜的模型拓撲,例如:
#多輸入模型,
#多輸出模型,
#具有共享層的模型(同一層被調用多次),
#具有非序列數據流的模型(例如,殘差連接)。
#使用函數式 API 構建的模型具有以下特徵:
#層實例可調用並返回張量。
#輸入張量和輸出張量用於定義 tf.keras.Model 實例。
#此模型的訓練方式和 Sequential 模型一樣。
input_x = tf.keras.Input(shape=(72,))
hidden1 = layers.Dense(32, activation='relu')(input_x)
hidden2 = layers.Dense(16, activation='relu')(hidden1)
pred = layers.Dense(10, activation='softmax')(hidden2)
model = tf.keras.Model(inputs=input_x, outputs=pred)
model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss=tf.keras.losses.categorical_crossentropy,
              metrics=['accuracy'])
model.fit(train_x, train_y, batch_size=32, epochs=5)
 
#模型子類化
#通過對 tf.keras.Model 進行子類化並定義您自己的前向傳播來構建完全可自定義的模型。
#在 init 方法中創建層並將它們設置爲類實例的屬性。
#在 call 方法中定義前向傳播
class MyModel(tf.keras.Model):
    def __init__(self, num_classes=10):
        super(MyModel, self).__init__(name='my_model')
        self.num_classes = num_classes
        self.layer1 = layers.Dense(32, activation='relu')
        self.layer2 = layers.Dense(num_classes, activation='softmax')
    def call(self, inputs):
        h1 = self.layer1(inputs)
        out = self.layer2(h1)
        return out
    def compute_output_shape(self, input_shape):
        shape = tf.TensorShapej(input_shape).as_list()
        shape[-1] = self.num_classes
        return tf.TensorShape(shape)
model = MyModel(num_classes=10)
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
loss=tf.keras.losses.categorical_crossentropy,
metrics=['accuracy'])
model.fit(train_x, train_y, batch_size=16, epochs=5)
 
#自定義層
#通過對 tf.keras.layers.Layer 進行子類化並實現以下方法來創建自定義層:
#build:創建層的權重。使用 add_weight 方法添加權重。
#call:定義前向傳播。
#compute_output_shape:指定在給定輸入形狀的情況下如何計算層的輸出形狀。
# 或者,可以通過實現 get_config 方法和 from_config 類方法序列化層。
class MyLayer(layers.Layer):
    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim
        super(MyLayer, self).__init__(**kwargs)
    def build(self, input_shape):
        shape = tf.TensorShape((input_shape[1], self.output_dim))
        self.kernel = self.add_weight(name='kernel1', shape=shape,
        initializer='uniform', trainable=True)
        super(MyLayer, self).build(input_shape)
    def call(self, inputs):
        return tf.matmul(inputs, self.kernel)
    def compute_output_shape(self, input_shape):
        shape = tf.TensorShape(input_shape).as_list()
        shape[-1] = self.output_dim
        return tf.TensorShape(shape)
    def get_config(self):
        base_config = super(MyLayer, self).get_config()
        base_config['output_dim'] = self.output_dim
        return base_config
    @classmethod
    def from_config(cls, config):
        return cls(**config)
model = tf.keras.Sequential(
[
 MyLayer(10),
 layers.Activation('softmax')
])
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss=tf.keras.losses.categorical_crossentropy,
              metrics=['accuracy'])
model.fit(train_x, train_y, batch_size=16, epochs=5)
 
# 回調
callbacks = [
 tf.keras.callbacks.EarlyStopping(patience=2, monitor='val_loss'),
 tf.keras.callbacks.TensorBoard(log_dir='./logs')
]
model.fit(train_x, train_y, batch_size=16, epochs=5,
          callbacks=callbacks, validation_data=(val_x, val_y))
 
#保持和恢復
# 權重保存
model = tf.keras.Sequential([
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')])
model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.save_weights('./weights/model')
model.load_weights('./weights/model')
model.save_weights('./model.h5')
model.load_weights('./model.h5')
 
#保存網絡結構
#序列化成json
import json
import pprint
json_str = model.to_json()
pprint.pprint(json.loads(json_str))
fresh_model = tf.keras.models.model_from_json(json_str)
# 保持爲yaml格式 #需要提前安裝pyyaml
yaml_str = model.to_yaml()
print(yaml_str)
fresh_model = tf.keras.models.model_from_yaml(yaml_str)
 
# 保存整個模型
model = tf.keras.Sequential([
 layers.Dense(10, activation='softmax', input_shape=(72,)),
 layers.Dense(10, activation='softmax')
])
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(train_x, train_y, batch_size=32, epochs=5)
model.save('all_model.h5')
model = tf.keras.models.load_model('all_model.h5')
 
# 將 keras 用於 Estimator
# Estimator API 用於針對分佈式環境訓練模型。它適用於一些行業使用場景,例如用大型數據集進行分佈式訓練並導出模型以用於生產
model = tf.keras.Sequential([layers.Dense(10,activation='softmax'),
                             layers.Dense(10,activation='softmax')])
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])
estimator = tf.keras.estimator.model_to_estimator(model)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章