天天看點

[概念]TF學習筆記day02+張量(常量+變量+占位符)一、張量二、TF常量型張量三、TF變量型張量四、TF占位符型張量五、拓展閱讀

一、張量

我們知道, 計算圖中的一個節點可以表示一個張量或者一個操作符

那麼張量是什麼?

張量,可了解為一個 n 維數值陣列

每個張量的次元機關用階來描述,零階張量是一個标量,一階張量是一個向量,二階張量是一個矩陣

是以标量、向量(矢量)和矩陣等都是特殊類型的張量

[概念]TF學習筆記day02+張量(常量+變量+占位符)一、張量二、TF常量型張量三、TF變量型張量四、TF占位符型張量五、拓展閱讀

TensorFlow 支援以下三種類型的張量:

1、常量:常量是其值不能改變的張量。

2、變量:當一個量在會話中的值需要更新時,使用變量來表示。例如,在神經網絡中,權重需要在訓練期間更新,可以通過将權重聲明為變量來實作。變量在使用前需要被顯示初始化。

3、占位符:用于将值輸入 TensorFlow 圖中。它們可以和 feed_dict 一起使用來輸入資料。在訓練神經網絡時,它們通常用于提供新的訓練樣本。在會話中運作計算圖時,可以為占位符指派。這樣在建構一個計算圖時不需要真正地輸入資料。需要注意的是,占位符不包含任何資料,是以不需要初始化它們。

二、TF常量型張量

import tensorflow as tf
           

“正常操作”

1、聲明一個标量常量:
t_1 = tf.constant(4)
with tf.Session() as sess:
    print(sess.run(t_1))
           
4
           
2、聲明一個向量常量:
t_2 = tf.constant([1,3])
with tf.Session() as sess:
    print(sess.run(t_2))
           
[1 3]
           
t_2 = tf.constant([4,3,2])
with tf.Session() as sess:
    print(sess.run(t_2))
           
[4 3 2]
           
3、建立一個所有元素為零的張量,可以使用 tf.zeros() 函數。這個語句可以建立一個形如 [M,N] 的零元素矩陣,資料類型(dtype)可以是 int32、float32 等:

tf.zeros([M,N],tf.dtype)

例如 :

zero_t = tf.zeros([2,3],tf.int32)
with tf.Session() as sess:
    print(sess.run(zero_t))
           
[[0 0 0]
 [0 0 0]]
           
4、建立一個所有元素都設為 1 的張量。下面的語句即建立一個形如 [M,N]、元素均為 1 的矩陣:

tf.ones([M,N],tf,dtype)

ones_t = tf.ones([2,3],tf.int32)
with tf.Session() as sess:
    print(sess.run(ones_t))
           
[[1 1 1]
 [1 1 1]]
           
5、還可以建立與現有 Numpy 數組或張量常量具有相同形狀的張量常量,如下所示:
<tf.Tensor 'zeros_like:0' shape=(3,) dtype=int32>
           
<tf.Tensor 'ones_like:0' shape=(3,) dtype=int32>
           
6、在一定範圍内生成一個從初值到終值等差排布的序列:

tf.linspace(start,stop,num)

相應的值為 (stop-start)/(num-1)。例如:

range_t = tf.linspace(2.0,5.0,5) #從2到5 切成5份
with tf.Session() as sess:
    print(sess.run(range_t))
           
[2.   2.75 3.5  4.25 5.  ]
           
7、從開始(預設值=0)生成一個數字序列,增量為 delta(預設值=1),直到終值(但不包括終值):

tf.range(start,limit,delta)

下面給出執行個體:

range_t = tf.range(10)
with tf.Session() as sess:
    print(sess.run(range_t))
#Result:[0 1 2 3 4 5 6 7 8 9]
           
[0 1 2 3 4 5 6 7 8 9]
           
range_t = tf.range(0,10,1)
with tf.Session() as sess:
    print(sess.run(range_t))
           
[0 1 2 3 4 5 6 7 8 9]
           

“随機操作”

TensorFlow 允許建立具有不同分布的随機張量

1、使用以下語句建立一個具有一定均值(預設值=0.0)和标準差(預設值=1.0)、形狀為 [M,N] 的正态分布随機數組:
t_random = tf.random_normal([2,3], mean=2.0, stddev=4,seed=12)
with tf.Session() as sess:
    print(sess.run(t_random))
           
[[ 0.25347447  5.37991     1.9527606 ]
 [-1.5376031   1.2588985   2.8478067 ]]
           
2、建立一個具有一定均值(預設值=0.0)和标準差(預設值=1.0)、形狀為 [M,N] 的截尾正态分布随機數組:
t_random = tf.truncated_normal([1,5], stddev=2,seed=12)
with tf.Session() as sess:
    print(sess.run(t_random))
           
[[-0.87326276  1.689955   -0.02361972 -1.7688016  -3.87749   ]]
           
3、要在種子的 [minval(default=0),maxval] 範圍内建立形狀為 [M,N] 的給定伽馬分布随機數組,請執行如下語句:
t_random = tf.random_uniform([2,3], maxval=4,seed=12)
with tf.Session() as sess:
    print(sess.run(t_random))
           
[[2.54461   3.6963658 2.7051091]
 [2.0085006 3.8445983 3.5426888]]
           
4、(不起作用好像)要将給定的張量随機裁剪為指定的大小,使用以下語句:

圖像分類中,在深度學習的訓練時将圖檔的随機剪裁(random crop)已經成為很普遍的資料擴充(data augmentation)方法,随機剪裁(縮寫為:IRC)不但提高了模型精度,也增強了模型穩定性

<tf.Tensor 'random_crop:0' shape=(2, 5) dtype=float32>
           

這裡,t_random 是一個已經定義好的張量。這将導緻随機從張量 t_random 中裁剪出一個大小為 [2,5] 的張量。

5、随機重新排序

很多時候需要以随機的順序來呈現訓練樣本,可以使用 tf.random_shuffle() 來沿着它的第一維随機排列張量。如果 t_random 是想要重新排序的張量,使用下面的代碼:

with tf.Session() as sess:
    print(sess.run(t_random))
print("随機重新排序後")
t = tf.random_shuffle(t_random)
with tf.Session() as sess:
    print(sess.run(t))
           
[[2.54461   3.6963658 2.7051091]
 [2.0085006 3.8445983 3.5426888]]
随機重新排序後
[[2.0085006 3.8445983 3.5426888]
 [2.54461   3.6963658 2.7051091]]
           
6、随機生成的張量受初始種子值的影響

要在多次運作或會話中獲得相同的随機數,應該将種子設定為一個常數值。當使用大量的随機張量時,可以使用 tf.set_random_seed() 來為所有随機産生的張量設定種子。以下指令将所有會話的随機張量的種子設定為 54:

種子隻能有整數值

三、TF變量型張量

tensorflow中的變量是承載和更新參數的對象

變量通常在神經網絡中表示權重和偏置

此外還可以儲存或恢複變量

變量是由tf.Variable()語句建立的

它必須初始化, 可以用常量來初始化變量,也可以用一個變量來初始化另一個變量

常量初始化變量

下面的代碼中建立了兩個不同的張量變量 t_a 和 t_b。兩者将被初始化為形狀為 [50,50] 的随機均勻分布,最小值=0,最大值=10:

rand_t = tf.random_uniform([50,50],0,10,seed=0)
t_a = tf.Variable(rand_t)
t_b = tf.Variable(rand_t)
           

注意:變量通常在神經網絡中表示權重和偏置。

下面的代碼中定義了兩個變量,分别是權重和偏置。權重變量使用正态分布随機初始化,均值為 0,标準差為 2,權重大小為 100×100。偏置由 100 個元素組成,每個元素初始化為 0。在這裡也使用了可選參數名以給計算圖中定義的變量命名:

weights = tf.Variable(tf.random_normal([100,100],stddev=2))
bias = tf.Variable(tf.zeros([100]), name = 'biases')
           

變量初始化變量

下面的語句将利用前面定義的權重變量來初始化 weight2:

賦予變量實際的意義

上面兩種方式的初始化, 并不代表計算圖中的變量已經被指派了

我們之前說過, 計算圖像是一張藍圖, 在此之前張量隻被抽象定義,隻有在會話時候, 才将張量賦予實際的意義

在會話時, 賦予常量實際的意義,是自動的; 而賦予變量實際的意義,還需要再加些東西

具體需要通過聲明初始化操作對象來實作:

舉個栗子, 希望程式實作從1數到10 :

import tensorflow as tf

#建立計算圖
value = tf.Variable(0, name="value")#建立一個變量,并将其初始化為标量0:
one = tf.constant(1)
new_value = tf.add(value, one)#add和assign操作符僅僅是計算圖中的節點,是以在會話運作前,它們不會執行
update_value = tf.assign(value, new_value)


#運作會話,完成計算圖中定義的操作
initialize_var = tf.global_variables_initializer() #聲明初始化操作對象, 用于計算圖中變量的指派
with tf.Session() as sess:
    sess.run(initialize_var)
    print(sess.run(value))
    for _ in range(10):
        sess.run(update_value)
        print(sess.run(value))
           
0
1
2
3
4
5
6
7
8
9
10
           

程式解讀: 這個栗子的計算圖有四個節點,分别是value變量、one常量、add加法操作符以及assign指派操作符.這個計算圖要實作的功能是value和one通過add相加,得到的值流到assign操作符,讓它再指派回value. 運作會話時,由于變量需要顯式初始化,是以需要聲明初始化操作對象,然後讓它run下來完成初始化

此外, 每個變量也可以在運作圖中單獨使用 tf.Variable.initializer 來初始化

import tensorflow as tf

#建立計算圖
value = tf.Variable(0, name="value")#建立一個變量,并将其初始化為标量0:
one = tf.constant(1)
new_value = tf.add(value, one)#add和assign操作符僅僅是計算圖中的節點,是以在會話運作前,它們不會執行
update_value = tf.assign(value, new_value)


#運作會話,完成計算圖中定義的操作
#initialize_var = tf.global_variables_initializer() #聲明初始化操作對象, 用于計算圖中變量的指派
with tf.Session() as sess:
    sess.run(value.initializer)#變量在運作圖中單獨初始化,常量就不用了.
    print(sess.run(value))
    for _ in range(10):
        sess.run(update_value)
        print(sess.run(value))
           
0
1
2
3
4
5
6
7
8
9
10
           

儲存變量

神經網絡訓練完後, 一般都需要儲存訓練好的參數,也就是我們所謂的權重和偏置, 其實際上就是變量, 是以我們要使用 Saver 類來儲存變量,定義一個 Saver 操作對象:

saver = tf.train.Saver()

四、TF占位符型張量

介紹完常量和變量之後,我們來講解最重要的張量——占位符

它是不需要初始化的

在會話中運作計算圖時,可以為占位符指派,通過會話對象中run裡feed_dict

它用于将值輸入計算圖中,它和feed_dict一起來輸入資料

run(fetches,feed_dict=None,options=None,run_metadata)

是以在訓練神經網絡時(會話),它們通常用于提供新的訓練樣本

如何定義一個占位符:

tf.placeholder(dtype,shape=None,name=None)

dtype 是占位符的資料類型,并且必須在聲明占位符時指定

下面示例中, 定義一個占位符型張量x, 并計算 y=2*x,會話時使用 feed_dict 輸入一個随機的 4×5 矩陣:

import tensorflow as tf

#計算圖
x = tf.placeholder("float")#占位符
y = 2*x
data = tf.random_uniform([4,5], 10)#随機常量

#run時才算進入會話
with tf.Session() as sess:
    print(data) #未進入會話
    x_data = sess.run(data) #會話時才能取出它的值
    print(x_data)#提出來了
    print("\n\n")
    print(sess.run(y, feed_dict = {x:x_data}))
           
Tensor("random_uniform_2:0", shape=(4, 5), dtype=float32)
[[9.789586  4.122238  2.5008888 2.8134599 2.4266639]
 [3.33526   3.5702267 6.666023  1.2452259 3.4237428]
 [6.941977  8.032328  2.8022385 8.071983  6.399656 ]
 [6.231288  2.589786  1.2040987 8.232471  1.4575834]]



[[19.579172   8.244476   5.0017776  5.6269197  4.8533278]
 [ 6.67052    7.1404533 13.332046   2.4904518  6.8474855]
 [13.883954  16.064655   5.604477  16.143967  12.799312 ]
 [12.462576   5.179572   2.4081974 16.464943   2.9151669]]
           

代碼解釋:

計算圖一共有4個節點,分别是占位型張量x、常數型張量2、乘法操作符y以及單獨的常數型張量data. 會話時取出data的值指派給x_data,然後放入feed_dict再一次進入會話指派給占位符x, 提取y的運作結果

run的時候才算進入會話

是以第一次run隻是fetch data裡的資料, 第二次才開始fetch y進行乘法運算

五、拓展閱讀

拓展1

很多時候需要大規模的常量張量對象;在這種情況下,為了優化記憶體,最好将它們聲明為一個可訓練标志設定為 False 的變量:

t_large = tf.Variable(large_array,trainable=False)
with tf.Session() as sess:
    sess.run(t_large.initializer)
    print(sess.run(t_large))
           
[1 2 3]
           

trainable:如果為True,則會預設将變量添加到圖形集合GraphKeys.TRAINABLE_VARIABLES中。此集合用于優化器Optimizer類優化的的預設變量清單【可為optimizer指定其他的變量集合】,也就是要訓練的變量清單。

拓展2

TensorFlow 被設計成與 Numpy 配合運作,是以所有的 TensorFlow 資料類型都是基于 Numpy 的。

使用 tf.convert_to_tensor() 可以将給定的值轉換為張量類型,并将其與 TensorFlow 函數和運算符一起使用。該函數接受 Numpy 數組、Python 清單和 Python 标量,并允許與張量對象互操作。

拓展3

下表列出了 TensorFlow 支援的常見的資料類型:

[概念]TF學習筆記day02+張量(常量+變量+占位符)一、張量二、TF常量型張量三、TF變量型張量四、TF占位符型張量五、拓展閱讀

拓展4

for i in range(1,10,1):
    print(i)
           
1
2
3
4
5
6
7
8
9
           
import numpy as np
           
for i in np.arange(1,10,1):
    print(i)

           
1
2
3
4
5
6
7
8
9
           

TensorFlow 序列不可疊代。試試下面的代碼:

File "<ipython-input-30-83ab65fa2626>", line 1
    for i in tf.range(10)
                         ^
SyntaxError: invalid syntax
           

繼續閱讀