TensowFlow 2 基本語法

TensorFlow安裝

tensorflow 在 Windows 10 只能使用 2.10.1 的版本才能啟用 GPU,所以請使用如下指令安裝套件。

#for windows 10
pip install tensorflow==2.10.1

但在 Linux 下 2.10.1 反而無法啟用 GPU,需安裝最新的版本,所以請使用如下指令安裝套件。

#for linux
./venv/bin/pip install tensorflow

TensorFlow的功能

為什麼要使用 TensorFlow,它的目的是什麼? 簡易的說,就是要把四則運算交由 GPU 執行。
為什麼要交由 GPU 執行? 因為 GPU 有上千台計算機(核心)可以同時幫忙計算,但 CPU 只有一台計算機。

x= 3.1415926 * (10**2) 這個指令是計算半徑為 10 的圓面積,此指令是由 CPU 的浮點運算器進行運算。

若要使用 GPU 運算,就要使用 Tensorflow 。 Tensorflow 的任務就是負責把運算切換到 GPU 執行。

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
#底下是由 CPU 執行
pi=3.1415926
r=10
print(pi*r*r)

#底下是由 GPU 執行
pi=tf.constant(3.1415926)
r=tf.Variable(10, dtype=tf.float32)
print(pi*r*r)

Hellow World

使用 tf.constant 定義一個常數 str,其內容值為 “hello, World”
如果直接把str印出,則會印出內容,維度,及型態
若只要印出內容,則必需加上str.numpy()

import tensorflow as tf
str = tf.constant("hello, World")
print("Tensor:", str)
print("Value :", str.numpy())

結果:
2021-01-24 21:50:03.414182: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library cudart64_110.dll
....................
2021-01-24 21:50:05.116465: I tensorflow/compiler/jit/xla_gpu_device.cc:99] Not creating XLA devices, tf_xla_enable_xla_devices not set
Tensor: tf.Tensor(b'hello, World', shape=(), dtype=string)
Value : b'hello, World'

輸出日誌

上面的程式碼執行後,有看到灰白色那一大段莫名奇妙五四三的訊息嗎! 真正重要的結果只有藍色那二行而以。那如何去除那些五四三的訊息呢。

TensorFlow 的訊息輸出機制,分為 4 個等級
0: INFO(通知)
1: WARNING(警告)
2: ERROR(錯誤)
3: FATAL(穩死的)

通知跟警告,其實都是廢話,所以只要顯示等級 2 及以上就好。如下代碼即可滿足我們的需求
 os.environ[‘TF_CPP_MIN_LOG_LEVEL’]=’2′

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
str = tf.constant("hello, World")
print("Tensor:", str)
print("Value :", str.numpy())

結果:
Tensor: tf.Tensor(b'hello, World', shape=(), dtype=string)
Value : b'hello, World'

tf.Tensor 常數類別

tensorflow 是一台功能很強大的計算機,但這台計算機沒有 int, float 這種原生基本資料型態,全部都是物件格式,這跟 Python 的特性一樣。

tf2 的基本常數類別為 tf.Tensor,中文翻譯為張量,不過翻成中文沒什麼意義,因為 “張量” 這名詞愈翻譯愈看不懂,所以只要記得 tf.Tensor 是 tensorflow 的常數類別就好

tf.Tensor 物件裏面的值一經指定後就無法變更的,裏面有很多的計算函數,且大部份的函數用法跟 numpy 類似。Tensor 物件裏面可以放入字串、數字或矩陣。

要建立 tf.Tensor 常數類別,並不是使用如下的方法

 x=tf.Tensor(.....)

建立 Tensor 物件必需使用 tf.constant() 這個方法,這個方法會產生 operation, value_index, dtype 等資料,然後再傳回 tf.Tensor 物件。

x=tf.constant(10, dtype=tf.int32) #產生 Tensor 物件

Tensor 屬性

Tensor 類別裏面有許多的屬性 (Property) 及方法 (method),比如 shape 維度,dtype 型態, numpy() 轉成Python 資料格式。

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
a=tf.constant(5)
b=tf.constant([[1,2,3], [4,5,6]])
print(a.shape, a.dtype, a.numpy())
print(b.shape, b.dtype, b.numpy())
結果 :
() <dtype: 'int32'> 5
(2, 3) <dtype: 'int32'> [[1 2 3]
[4 5 6]]

tf.constant方法

請注意 tf.constant 只是一個方法,其目的在建立一個 tf.Tensor 常數物件。因為是方法,所以constant 的 “c” 是小寫。而其傳回值為 tf.Tensor物件,所以底下代碼列印 a 這個接收變數時,型態為 tf.Tensor

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
a=tf.constant(5)
print(a)
結果:
tf.Tensor(1.0, shape=(), dtype=float32)

tf.Variable 變數類別

tf.Variable 為 tf2 的變數類別

請注意這不是物件導向中的 類別變數 喔,類別變數是物件導向的 static variable,是存在類別中的變數。

tf.Variable 裏面的值可以改變,列印出來的結果直接顯示為 tf.Variable。首先要用 x = tf.Variable(值) 初始化變數值。若要更改其值,需使用 x.assign(值) 。

為什麼改變值不能直接使用 x = 100 呢? 因為這時 x 的 tf 物件會被摧毀掉,然後重新指定成 Python 的 int 型態。

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
x=tf.Variable(10)
print(x)

#底下的 x 還是 tf.Variable型態
x.assign(100)
print(x)

#底下的 x 變成了 Python的 int 型態 
x=100
print(x)

結果 :
<tf.Variable 'Variable:0' shape=() dtype=int32, numpy=10>
<tf.Variable 'Variable:0' shape=() dtype=int32, numpy=100>
10

資料型態

不論是常數 (tf.Tensor) 或變數 (tf.Variable),都可以使用 dtype 指定型態,常用的型態有

整數 : tf.int8(-128~127),tf.int16(-32768~32767),tf.int32(-21億~21億),tf.int64(-2^63~2^63-1),
預設為 tf.int32。

無號整數(unsigned) : tf.uint8(0~255),tf.uint16(0~65535),tf.uint32(0~42億),tf.uint64(0~2^64-1)

浮點數 : tf.float16,tf.float32(單精度浮點數,準確到小數第7位),tf.float64(雙精度浮點數, 準確到小數第15位),預設為 tf.float32。

字串 : tf.string

a=tf.Variable(10)
b=tf.Variable(10.)
c=tf.Variable("Hello") print(a) print(b)
print(c) 結果: <tf.Variable 'Variable:0' shape=() dtype=int32, numpy=10> <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=10.0> <tf.Variable 'Variable:0' shape=() dtype=string, numpy=b'abcd'>

產生 tf 物件時,如果指定的數字是整數 (10),而 dtype=tf.float32,此時會先將整數轉成浮點數再產生 tf 物件。

a=tf.constant(10, dtype=tf.float32)

但如果指定的數字為浮點數 (10.0),而 dtype=tf.int32,因為浮點數無法轉成整數,所以會產生例外錯誤,如下

a=tf.constant(10.0, dtype=tf.int32) <==會發生例外錯誤

四則運算

TensorFlow 這個強大的計算機,當然可以進行四則運算。

a=tf.constant(10)
b=tf.Variable(3)
print(a+b)

結果 :
tf.Tensor(13, shape=(), dtype=int32)

指定運算子 “= “

使用指定運算子 “=”,比如 a = x + y,不論 x, y 是 tf.Tensor 或 tf.Variable,最後的結果一定是 tf.Tensor

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
x=tf.constant(10)
y=tf.Variable(3)
a = x / y
print(a)
結果 :
tf.Tensor(3.3333333333333335, shape=(), dtype=float64)

不同型態無法運算

無論是tf.Tensor 或是 tf.Variable,型態如果不一樣,是則無法運算的

x=tf.constant(10.)# tf.float32
y=tf.constant(3) # tf.int32
#print(x+y)#會發生例外錯誤

運算後的型態

整數作 +-* 運算,結果還是整數

import os
import tensorflow as tf
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
a=tf.constant(10)
b=tf.Variable(3)
print("a+b : ", a+b)
print("a-b : ", a-b)
print("a*b : ", a*b)
結果 : 
a+b :  tf.Tensor(13, shape=(), dtype=int32)
a-b :  tf.Tensor(7, shape=(), dtype=int32)
a*b :  tf.Tensor(30, shape=(), dtype=int32)

但整數作 “除號” 運算,結果是 tf.float64

import os
import tensorflow as tf
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
a=tf.constant(10)
b=tf.Variable(3)
print("a/b : ", a/b)
結果:
a/b :  tf.Tensor(3.3333333333333335, shape=(), dtype=float64)

求商數

如果相除後要取得整數,則要使用 “//”,其實這就是在求商數。整數//整數,結果是整數

import os
import tensorflow as tf
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
a=tf.constant(10)
b=tf.Variable(3)
print("a//b : ", a//b)
結果:
a//b :  tf.Tensor(3, shape=(), dtype=int32)

浮點數也可以求商數,不過結果是浮點數

import os
import tensorflow as tf
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
a=tf.constant(10.)
b=tf.Variable(3.)
print("a // b : ", a // b)
結果:
a // b :  tf.Tensor(3.0, shape=(), dtype=float32)

求餘數

 求取餘數的運算子為 “%”。tf 只有整數才能求餘數,浮點數也可以求餘數。 python 的浮點數也是可以求餘數的。

import os
import tensorflow as tf
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
a=tf.constant(10)
b=tf.Variable(3)
print("a % b : ", a % b)
print("10 % 3.5 : ", 10 % 3.6)#Python 浮點數可以求餘數
結果:
a % b :  tf.Tensor(1, shape=(), dtype=int32)
10 % 3.5 :  2.8

tf 與 Python 變數

tf 格式可以跟 Python 的整數變數作四則運算

tf  有點小聰明,會先把 Python 整數依 tf 格式變更成 tf 整數或小數,再進行運算

import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import tensorflow as tf
a=tf.Variable(5)
b=tf.Variable(5., dtype=tf.float64)
c=2
print(a+c) #將 c 轉成 tf.int32
print(b+c) #將 c 轉成 tf.float64

結果:
tf.Tensor(7, shape=(), dtype=int32)
tf.Tensor(7.0, shape=(), dtype=float64)

但如果 tf 是整數,而 Python 變數是浮點數呢? 因為 Python 浮點數無法自動轉成整數,所以會出現例外錯誤。

import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import tensorflow as tf
a=tf.Variable(5)
c=2.
print(a+c)

結果:
Traceback (most recent call last):
  File "E:\python_ai\test4\main.py", line 6, in 
    print(a+c)
  File "E:\python_ai\test4\venv\lib\site-packages\tensorflow\python\ops\variables.py", line 1074, in _run_op
    return tensor_oper(a.value(), *args, **kwargs)
.............

型態轉換

不同型態的常數或變數無法進行四則運算,所以型態轉換變成了必要的手段。

tf.cast(變數, 型態) 就是型態轉換的函數。

import tensorflow as tf
a = tf.constant(10.)
b = tf.cast(a, tf.int32)
print("a=", a)
print("b=", b)
結果:
a= tf.Tensor(10.0, shape=(), dtype=float32)
b= tf.Tensor(10, shape=(), dtype=int32)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *