TensorFlow 2.0學習筆記(3):基本介紹

Yanwei Liu
15 min readApr 12, 2020

--

TensorFlow 2.0學習筆記(1):服飾影像分類TensorFlow 2.0學習筆記(2):預訓練影像分類模型使用,兩篇文章中,我們讓讀者們很快的認識了TensorFlow完整專案的運作流程。本篇文章將帶領讀者了解學習TensorFlow需要有的觀念。

本文程式碼參考自:

輕鬆學會 Google TensorFlow 2.0 人工智慧深度學習實作開發書中之範例程式

購買連結

TensorFlow 2.0 介紹

import tensorflow as tf

基本型態

# 產生一個常數
c = tf.constant(1)
# 產生一個變數
v = tf.Variable(1)
print(c)
print(v)
零階張量稱為標量
x = tf.constant(4)
print(x) # 顯示Tensor 常數資訊,Shape=()表示標量,dtype=int32 表示整數print("{} 階Tensor".format(x.ndim)) # 顯示Tensor 的維度
一階張量稱為向量
x = tf.constant([1, 2, 3, 4, 5, 6])
print("{}階Tensor ".format(x.ndim)) # 顯示Tensor的維度
二階張量稱為矩陣
x = tf.constant([[1, 2, 3], [4, 5, 6]])
print("{}階Tensor ".format(x.ndim)) # 顯示Tensor的維度

動態圖

Eager Execution

不同與以往TF 1.X版本的靜態圖模式需要建立計算圖才能執行,Eager Execution模式一旦執行就會返回數值。

Eager Execution 的優點如下:

  • 立即返回數值,方便除錯。
  • 無需 Session.run() 就可以把它們的值返回到 Python。
  • 為自定義和高階梯度提供強大支援。
  • 幾乎所有 TensorFlow 運算都適用。

TensorFlow 1.x 和 TensorFlow2.0比較:

TensorFlow 1.x code:
>>> a = tf.constant(1)
>>> print(a)
Tensor("Const_5:0", shape=(), dtype=int32)
>>> sess = tf.Session()
>>> print("a = {}".format(sess.run(a)))
a = 1
TensorFlow 2.0 code:
>>> a = tf.constant(1)
>>> print(a)
tf.Tensor(1, shape=(), dtype=int32)

基本運算

import numpy as np
import tensorflow as tf
print("Eager Execution 是否啟動: {}".format(tf.executing_eagerly()))定義常數 Tensor
a = tf.constant(3)
b = tf.constant(4)
print("a = {}".format(a))
print("b = {}".format(b))
檢查資料型態
print(a)
print(b)
基本的運算
c = a + b
print("a + b = {}".format(c))
d = a * b
print("a * b = {}".format(d))
2D Tensor 的運算,在Eager Execution模式下可以混和 Tensor 和 Numpy 做運算
a = tf.constant([[1., 2.], [3., 4.]], dtype=tf.float32)
b = np.array([[1., 0.], [2., 3.]], dtype=np.float32)
print("a constant: {}D Tensor".format(a.ndim))
c = a + b
print("a + b = \n{}".format(c))
d = tf.matmul(a, b)
print("a * b = \n{}".format(d))
Tensor 格式轉 Numpy 格式
print(c)
print("NumpyArray:\n {}".format(c.numpy()))
計算梯度
w = tf.Variable([[1.0]])
with tf.GradientTape() as tape:
loss = w * w
grad = tape.gradient(loss, w)
print(grad)

Keras

TensorFlow2.0將Keras納為內建高階API,因此不必再而外安裝keras套件,直接透過tf.keras指令使用。

相較於tf.keraskeras的差別,tf.keras更能全面支援tensorflow的指令與模式,

例如支援Eager Exection, tf.data, TPU訓練等等。

下面將會介紹兩種最常使用的網路搭建方法:
1.Sequential Model (序列模型)
2.Function API (函數式模型)

Sequential Model

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.utils import plot_model
from IPython.display import Image
#輸入為28x28 (拉平為784的一維向量)的影像,輸出為10(分為十個類別)。
#方法1和方法2成果一樣
方法1:
model = keras.Sequential(name='Sequential')
model.add(layers.Dense(64, activation='relu', input_shape=(784,)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
方法2:
model = tf.keras.Sequential(
[layers.Dense(64, activation='relu', input_shape=784,)),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')])
顯示出剛剛搭建的網路
# 產生網絡拓撲圖
plot_model(model, to_file='Sequential_Model.png')
# 秀出網絡拓撲圖
Image('Sequential_Model.png')

Functional API

使用Functional API 一樣可以快速幾行代碼完成和上面Sequential Model 相同的架構。

inputs = keras.Input(shape=(784,), name='Input')
hidden1 = layers.Dense(64, activation='relu', name='hidden1')(inputs)
hidden2 = layers.Dense(64, activation='relu', name='hidden2')(hidden1)
outputs = layers.Dense(10, activation='softmax', name='Output')(hidden2)
model = keras.Model(inputs=inputs, outputs=outputs)# 產生網絡拓撲圖
plot_model(model, to_file='Functional_API_Sample_Model.png')
# 秀出網絡拓撲圖
Image('Functional_API_Sample_Model.png')

Multi Input Model:多輸入單輸出模型,下面的範例為商品價格預測,要預測商品價格,我們需要商品照片、品牌、使用狀況等等。而商品圖片和品牌我們可以經過不同層輸入並做不同的處理,網路架構如下。

img_input = keras.Input(shape=(28, 28, 1), name='Image_Input')
info_input = keras.Input(shape=(1, ), name='Information_Input')
hidden1_1 = layers.Conv2D(64, kernel_size=5, strides=2, activation='relu', name='hidden1_1')(img_input)
hidden1_2 = layers.Conv2D(32, kernel_size=5, strides=2, activation='relu', name='hidden1_2')(hidden1_1)
hidden1_2_ft= layers.Flatten()(hidden1_2)
hidden1_3 = layers.Dense(64, activation='relu', name='hidden1_3')(info_input)
concat = layers.Concatenate()([hidden1_2_ft, hidden1_3])
hidden2 = layers.Dense(64, activation='relu', name='hidden2')(concat)
outputs = layers.Dense(1, name='Output')(hidden2)
model = keras.Model(inputs=[img_input, info_input], outputs=outputs)# 產生網絡拓撲圖
plot_model(model, to_file='Functional_API_Multi_Input_Model.png')
# 秀出網絡拓撲圖
Image('Functional_API_Multi_Input_Model.png')

Multi Output Network:單輸入多輸出模型,這種類型的架構在影響處理的領域很長看到,下面舉幾個常見多輸出模型應用例子。

  • 物件偵測:輸入一張圖像,預測物件位置與物件類別等。
  • 人像識別:輸入一張圖像,預測圖片中人的性別、年齡等。
inputs = keras.Input(shape=(28, 28, 1), name='Input')hidden1 = layers.Conv2D(64, kernel_size=3, activation='relu', name='hidden1')(inputs)
hidden2 = layers.Conv2D(64, kernel_size=3, strides=2, activation='relu', name='hidden2')(hidden1)
hidden3 = layers.Conv2D(64, kernel_size=3, strides=2, activation='relu', name='hidden3')(hidden2)
flatten = layers.Flatten()(hidden3)
age_output = layers.Dense(1, name='Age_Output')(flatten)
gender_output = layers.Dense(1, name='Gender_Output')(flatten)
model = keras.Model(inputs=inputs, outputs=[age_output, gender_output])# 產生網絡拓撲圖
plot_model(model, to_file='Functional_API_Multi_Output_Model.png')
# 秀出網絡拓撲圖
Image('Functional_API_Multi_Output_Model.png')

Multi Input and Multi Output Network:多輸入多輸出模型,例如天氣預測,輸入可能為當前的天氣資訊和衛星雲圖,而輸出就是降雨機率、溫度和濕度等。

image_inputs = keras.Input(shape=(28, 28, 1), name='Image_Input')
hidden1 = layers.Conv2D(64, kernel_size=3, activation='relu', name='hidden1')
hidden2 = layers.Conv2D(64, kernel_size=3, strides=2, activation='relu', name='hidden2')
hidden3 = layers.Conv2D(64, kernel_size=3, strides=2, activation='relu', name='hidden3')
flatten = layers.Flatten()
info_inputs = keras.Input(shape=(10, ), name='Info_Input')
hidden4 = layers.Dense(64)
concat = layers.Concatenate()([flatten, hidden4])weather_outputs = layers.Dense(1, name='Output1')
temp_outputs = layers.Dense(1, name='Output2')
humidity_outputs = layers.Dense(1, name='Output3')
model = keras.Model(inputs=[image_inputs, info_inputs],
outputs=[weather_outputs, temp_outputs, humidity_outputs]
)
# 產生網絡拓撲圖
plot_model(model, to_file='Functional_API_Multi_Input_Multi_Output_Model.png')
# 秀出網絡拓撲圖
Image('Functional_API_Multi_Input_Multi_Output_Model.png')

tf.data

1.tf.data.Dataset.from_tensors

dataset = tf.data.Dataset.from_tensors(tf.constant([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], shape=(10, )))
print(dataset)

2.tf.data.Dataset.from_tensor_slices

x_data = tf.data.Dataset.from_tensor_slices(tf.constant([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], shape=(10, )))
print(x_data)
y_data = tf.data.Dataset.from_tensor_slices(tf.constant([0, 2, 4, 6, 8, 10, 12, 14, 16, 18], shape=(10, )))
print(y_data)

3.for loop讀取數據:

for data in dataset:
print(data)
for data1, data2 in zip(x_data, y_data):
print('x: {}, y: {}'.format(data1, data2))

4.take:讀取資料

for data1, data2 in zip(x_data.take(5), y_data.take(5)):
print('x: {}, y: {}'.format(data1, data2))

5.map:可以使用map來轉換數據

tf.data.Dataset.range(10).map(lambda x: x*2)

6.設定每batch讀取的數量

dataset = tf.data.Dataset.zip({"x": x, "y": y}).batch(2)for data in dataset.take(5):
print('x: {}, y: {}'.format(data['x'], data['y']))

7.shuffle:dataset資料 會被載入buffer中,並從buffer中隨機選取資料出來,取出資料產生的空位會從新的數據替補。而buffer_size是設定buffer大小,最好的設定是大於等於整個dataset資料個個數。

dataset = dataset.shuffle(10)
for data in dataset.take(5):
print('x: {}, y: {}'.format(data['x'], data['y']))

8.repeat:當dataset的資料讀取完後就讀會取不到資料,透過設定repeat(n)可以重複讀取dataset n次。

for data in dataset.take(10):
print('x: {}, y: {}'.format(data['x'], data['y']))
print('-' * 50)
dataset = dataset.repeat(2)
for data in dataset.take(10):
print('x: {}, y: {}'.format(data['x'], data['y']))

--

--

No responses yet