TensorFlow

TensorFlow 基礎入門

Google+ Pinterest LinkedIn Tumblr

注:這篇文章的內容來自課程[Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization]的程式設計練習。coursera上的程式設計練習設計得非常貼心,一步步引導學員完成練習,對於程式設計基礎薄弱的同學尤為友好。

到目前為止,您一直使用numpy來構建神經網路。現在我們將引導您使用一個深度學習框架,讓您可以更輕鬆地構建神經網路。TensorFlow、PaddlePaddle、Torch、Caffe、Keras等機器學習框架可顯著加速機器學習開發。在此作業中,您將學習在TensorFlow中執行以下操作:

  • 初始化變數

  • 開始會話

  • 訓練演算法

  • 實施神經網路

程式設計框架不僅可以縮短編碼時間,而且有時還可以執行優化來加速程式碼。

1 – 探索Tensorflow程式庫

首先,請匯入相關庫:

import math
import numpy as np
import h5py
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.python.framework import ops
from tf_utils import load_dataset, random_mini_batches, convert_to_one_hot, predict

%matplotlib inline
np.random.seed(1)

現在您已經匯入了該庫,我們將引導您完成不同的應用程式。您將從一個例子開始,在這裏我們為您計算一個訓練樣例的損失。

TensorFlow 基礎入門

y_hat = tf.constant(36, name='y_hat')            # 定義y_hat常量,值為36.
y = tf.constant(39, name='y')                    # 定義y,值為39

loss = tf.Variable((y - y_hat)**2, name='loss')  # 為損失建立一個變數

init = tf.global_variables_initializer()         # init將在後面執行 (session.run(init)),
                                                 # loss變數將被初始化,準備計算
with tf.Session() as session:                    # 建立一個會話並列印輸出
    session.run(init)                            # 初始化變數
    print(session.run(loss))                     # 列印loss值

在TensorFlow中編寫和執行程式有以下步驟:

  1. 建立尚未執行/評估的張量(變數)。

  2. 在這些張量之間寫入操作。

  3. 初始化張量。

  4. 建立一個會話。

  5. 執行會話,它將執行您上面寫的操作。

因此,當我們為損失建立一個變數時,我們簡單地將損失定義為其他數的函式,但沒有評估它的值。爲了評估它,我們必須執行init=tf.global_variables_initializer()。它初始化損失變數,並在最後一行程式碼中,評估損失的值並列印其值。

現在讓我們看一個簡單的例子:

a = tf.constant(2)
b = tf.constant(10)
c = tf.multiply(a,b)
print(c)

輸出為Tensor(「Mul:0」, shape=(), dtype=int32)

正如所料,您不會看到20!而是得到一個張量,結果是一個沒有shape屬性的張量,它的型別是」int32」。您所做的只是放在’計算圖’中,但您還沒有執行這個計算。爲了真正相加這兩個數字,您將不得不建立一個會話並執行它。

sess = tf.Session()
print(sess.run(c))

輸出為 20

很棒! 總結一下, 記得初始化變數,建立一個會話並在會話中執行這些操作

接下來,您還必須瞭解佔位符。佔位符是一個物件,其值只能在稍後指定。要指定佔位符的值,可以使用」饋送字典」(feed_dict變數)傳入值。下面,我們為x建立了一個佔位符,這允許我們稍後在執行會話時傳入一個數字。

# 在feed_dict中改變x的值

x = tf.placeholder(tf.int64, name = 'x')
print(sess.run(2 * x, feed_dict = {x: 3}))
sess.close()

輸出為 6

當您第一次定義x時,您不必為它指定一個值。佔位符只是一個變數,您將僅在以後執行會話時分配資料。也就是說您在執行會話時向這些佔位符 提供資料

以下是所發生的事情:當您指定計算所需的操作時,也就是告訴TensorFlow如何構建計算圖。計算圖可以有一些佔位符,其值將在稍後指定。最後,當您執行會話時,告訴TensorFlow執行計算圖。

1.1 – 線性函式

讓我們通過計算以下等式來開始程式設計練習:Y = WX + bY,其中W和X是隨機矩陣,b是隨機向量。

練習:計算WX + b,其中W,X和b符合隨機正態分佈。W的形狀是(4,3),X為(3,1),b是(4,1)。作為一個示例,下面程式碼是如何定義一個具有shape(3,1)的常量X:

X = tf.constant(np.random.randn(3,1),name ="X")

您可能會發現以下函式很有用:

  • tf.matmul(…, …)做一個矩陣乘法

  • tf.add(…, …)做一個加法

  • np.random.randn(…)隨機初始化

# GRADED FUNCTION: linear_function

def linear_function():
    """
    實現一個線性函式: 
            初始化W為一個形狀為(4,3)的隨機張量
            初始化X為一個形狀為(3,1)的隨機張量
            初始化b為一個形狀為(4,1)的隨機張量
    返回: 
    result -- 執行Y = WX + b會話的結果 
    """

    np.random.seed(1)

    ### START CODE HERE ### (4 lines of code)
    X = tf.constant(np.random.randn(3, 1), name = "X")
    W = tf.constant(np.random.randn(4, 3), name = "W")
    b = tf.constant(np.random.randn(4, 1), name = "b")
    Y = tf.add(tf.matmul(W, X), b)
    ### END CODE HERE ### 

    # 使用tf.Session()建立會話,並用sess.run執行您要計算的變數

    ### START CODE HERE ###
    sess = tf.Session()
    result = sess.run(Y)
    ### END CODE HERE ### 

    # 關閉會話 
    sess.close()

    return result

1.2 – 計算sigmoid

非常棒! 您剛剛實現了一個線性函式。Tensorflow提供了各種常用的神經網路函式,如tf.sigmoid和tf.softmax。對於這個練習,我們計算一個輸入的sigmoid函式。

您將使用佔位符變數x執行此練習。執行會話時,應該使用饋送字典傳入z。在本練習中,您需要(1) 建立一個佔位符x,(2) 使用tf.sigmoid定義計算sigmoid值,然後(3) 執行會話。

練習:實現下面的sigmoid函式,參考使用以下程式碼:

tf.placeholder(tf.float32,name ="...")
tf.sigmoid(...)
sess.run(..., feed_dict = {x: z})

請注意,有兩種典型的方式來建立和使用tensorflow中的會話:

方法1:

sess = tf.Session()
# Run the variables initialization (if needed), run the operations
result = sess.run(..., feed_dict = {...})
sess.close() # Close the session

方法2:

with tf.Session() as sess: 
    # run the variables initialization (if needed), run the operations
    result = sess.run(..., feed_dict = {...})
    # This takes care of closing the session for you :)
# GRADED FUNCTION: sigmoid

def sigmoid(z):
    """
    計算z的sigmoid值

    引數:
    z -- 輸入值,標量或向量

    返回: 
    results -- z的sigmoid值
    """

    ### START CODE HERE ### ( approx. 4 lines of code)
    # 為x建立一個佔位符,命名為'x'.
    x = tf.placeholder(tf.float32, name = "x")

    # 計算sigmoid(x)
    sigmoid = tf.sigmoid(x)

    # 建立一個會話,執行之。請使用上面提到的方法2。 
    # 您應該使用一個feed_dic將z的值傳遞給x。 
    with tf.Session() as sess:
        # 執行會話並輸出結果給"result"
        result = sess.run(sigmoid, feed_dict = {x:z})

    ### END CODE HERE ###

    return result

總結一下,您現在知道如何:

  1. 建立佔位符

  2. 指定計算對應的計算圖

  3. 建立會話

  4. 執行會話,必要時使用饋送字典來指定佔位符變數的值。

1.3 – 計算代價(cost)

您也可以使用內建函式來計算神經網路的代價。因此,您大可不必編寫程式碼計算函式:

TensorFlow 基礎入門

在tensorflow中只需一行程式碼即可完成!

練習:實現交叉熵損失,您將使用的函式是:

tf.nn.sigmoid_cross_entropy_with_logits(logits = ..., labels = ...)

您的程式碼應該輸入z,計算sigmoid(得到a),然後計算交叉熵代價J。所有這些都可以通過一次呼叫tf.nn.sigmoid_cross_entropy_with_logits來完成,它將計算:

TensorFlow 基礎入門

# GRADED FUNCTION: cost

def cost(logits, labels):
    """
    使用交叉熵計算代價

    引數:
    logits -- 包含z的向量,最後一個線性單元的輸出(在sigmoid啟用之前)
    labels -- 標籤向量y(1或0) 

    注意: 在本類中我們叫做"z"和"y"的,在TensorFlow文件中分別稱作"logits"和"labels"。所以logits將傳入z, 而labels傳入y. 

    返回:
    cost -- 執行會話計算出的成本(根據公式(2))
    """

    ### START CODE HERE ### 

    # 為"logits" (z) 和 "labels" (y)建立佔位符
    z = tf.placeholder(tf.float32, shape = logits.shape, name = "logits")
    y = tf.placeholder(tf.float32, shape = labels.shape, name = "labels")

    # 使用損失函式
    cost = tf.nn.sigmoid_cross_entropy_with_logits(logits = z, labels = y)

    # 建立會話,參考上面的方法1
    sess = tf.Session()

    # 執行會話
    cost = sess.run(cost, feed_dict={z: logits, y: labels})

    # 關閉會話
    sess.close()

    ### END CODE HERE ###

    return cost

1.4 – 使用一位有效編碼(One Hot encoding)

在很多深度學習裡,您會得到一個y向量,數字範圍從0到C-1,其中C是類的數量。比如C為4,那麼您可能得到以下的y向量,您需要按如下方式進行轉換:

TensorFlow 基礎入門

這通常稱為」一位有效(one hot)」編碼,因為在轉換的表示中,每列的對應元素是」有效位(hot)」(意思是設定為1)。要在numpy中進行這種轉換,您可能需要編寫好幾行程式碼。在tensorflow中,只需一行程式碼:

tf.one_hot(labels, depth, axis)

練習:執行下面的函式,取一個標籤向量和類別總數C,返回one hot編碼。請使用tf.one_hot()來實現。

# GRADED FUNCTION: one_hot_matrix

def one_hot_matrix(labels, C):
    """
    建立一個矩陣,其第i行對應第i個類別,且第j列對應第j個訓練樣本,也即如果樣本j的標籤為i,則矩陣(i,j)的元素值為1。

    引數:
    labels -- 包含標籤的向量 
    C -- 類別的數量,也是one hot維度值

    返回: 
    one_hot -- one hot矩陣
    """

    ### START CODE HERE ###

    # 建立等於C的常量,命名為'C'.
    C = tf.constant(C)

    # 使用tf.one_hot, 請注意axis引數值
    one_hot_matrix = tf.one_hot(labels, C, axis = 0)

    # 建立會話
    sess = tf.Session()

    # 執行會話
    one_hot = sess.run(one_hot_matrix)

    # 關閉會話
    sess.close()

    ### END CODE HERE ###

    return one_hot

1.5 – 使用零和一初始化

現在您將學習如何初始化一個零和一的向量。你要呼叫的函式是tf.ones()。要用零初始化,你可以使用tf.zeros()來代替。這些函式傳入一個shape,分別返回一個全部元素為0和1的且維數等於shape的陣列。

練習:實現下面的函式,傳入shape並返回一個數組(維數和shape相同)。

tf.ones(shape)
# GRADED FUNCTION: ones

def ones(shape):
    """
    建立一個維度為shape的全1陣列

    引數:
    shape -- 您要建立的陣列的維度shape

    返回: 
    ones -- 全1陣列
    """

    ### START CODE HERE ###

    # 使用tf.ones(...)建立"ones"張量
    ones = tf.ones(shape)

    # 建立會話
    sess = tf.Session()

    # 執行會話,計算'ones'
    ones = sess.run(ones)

    # 關閉會話
    sess.close()

    ### END CODE HERE ###
    return ones

2 – 在tensorflow中構建您的第一個神經網路

在這部分任務中,您將使用tensorflow建立一個神經網路。請記住,實現tensorflow模型分為兩部分:

  • 建立計算圖

  • 執行圖

讓我們深入探討您要解決的問題!

2.0 – 問題陳述:SIGNS資料集

有一天下午,和一些朋友一起,我們決定教電腦破譯手語。我們花了幾個小時在白牆前拍攝照片,得到了以下資料集。現在您的工作是構建一個演算法,以便幫助語言障礙人士與不懂手語的人進行溝通。

  • 訓練資料集:1080個圖片(64×64畫素),代表從0到5的手勢(每個數字180張圖片)。

  • 測試資料集:120張圖片(64×64畫素),代表從0到5的手勢(每個數字20張圖片)。

請注意,這是SIGNS資料集的一個子集。完整的資料集包含更多的手勢。

以下是每個數字的示例,以及我們如何表示標籤。這些是在我們將影象解像度降低到64×64畫素之前的原始圖片。

TensorFlow 基礎入門

執行以下程式碼以載入資料集。

X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()

通常,我們需要將影象資料集壓平(flatten),然後除以255將其歸一化。最重要的是,將每個標籤轉換為one hot向量。執行下面的程式碼以執行此操作。

# 壓平訓練和測試圖片
X_train_flatten = X_train_orig.reshape(X_train_orig.shape[0], -1).T
X_test_flatten = X_test_orig.reshape(X_test_orig.shape[0], -1).T
# 歸一化影象向量
X_train = X_train_flatten/255.
X_test = X_test_flatten/255.
# 將訓練和測試標籤轉換為one hot矩陣
Y_train = convert_to_one_hot(Y_train_orig, 6)
Y_test = convert_to_one_hot(Y_test_orig, 6)

print ("number of training examples = " + str(X_train.shape[1]))
print ("number of test examples = " + str(X_test.shape[1]))
print ("X_train shape: " + str(X_train.shape))
print ("Y_train shape: " + str(Y_train.shape))
print ("X_test shape: " + str(X_test.shape))
print ("Y_test shape: " + str(Y_test.shape))
number of training examples = 1080
number of test examples = 120
X_train shape: (12288, 1080)
Y_train shape: (6, 1080)
X_test shape: (12288, 120)
Y_test shape: (6, 120)

請注意,12288來自64×64×364×64×3。每個影象是方形的,64×64畫素,3是RGB顏色。在繼續任務之前,請確保您瞭解所有這些形狀的含義。

您的目標是構建能夠高準確度識別手勢的演算法。要做到這一點,您要建立一個tensorflow模型,這個模型幾乎和您之前使用numpy構建的貓識別模型一樣(但現在使用softmax輸出)。將您的numpy實現與tensorflow實現進行比較是一個不錯的點子。

模型定義為LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX。SIGMOID輸出層替換為SOFTMAX。當超過兩個類別時,SOFTMAX層比SIGMOID更通用。

2.1 – 建立佔位符

您的第一項任務是為X和Y建立佔位符,可以稍後在執行會話時傳遞訓練資料。

練習:執行下面的函式以建立tensorflow中的佔位符。

# GRADED FUNCTION: create_placeholders

def create_placeholders(n_x, n_y):
    """
    為tensorflow會話建立佔位符.

    引數:
    n_x -- 標量, 影象向量的大小(num_px * num_px = 64 * 64 * 3 = 12288)
    n_y -- 標量, 類別的數量(從0到5, 所以 -> 6)

    返回:
    X -- 資料輸入佔位符,形狀為[n_x, None],資料型別"float"
    Y -- 輸入標籤的佔位符,形狀[n_y, None],資料型別"float"

    提示:
    - 您將使用None,因為它使我們能夠靈活處理佔位符所代表的樣本的數量.
      事實上,測試/訓練階段樣本的數量是不同的.
    """

    ### START CODE HERE ### (approx. 2 lines)
    X = tf.placeholder(dtype = tf.float32, shape = (n_x, None), name = "X")
    Y = tf.placeholder(dtype = tf.float32, shape = (n_y, None), name = "Y")
    ### END CODE HERE ###

    return X, Y

2.2 – 初始化引數

您的第二個任務是在tensorflow中初始化引數。

練習:執行下面的函式來初始化tensorflow中的引數。您將使用Xavier來初始化權重,使用零初始化偏置,其形狀如下所示。作為一個示範,對於W1和b1您可以使用:

W1 = tf.get_variable("W1", [25,12288], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
b1 = tf.get_variable("b1", [25,1], initializer = tf.zeros_initializer())

請使用seed = 1來確保您的結果與我們的結果相符。

# GRADED FUNCTION: initialize_parameters

def initialize_parameters():
    """
    Initializes parameters to build a neural network with tensorflow. The shapes are:
                        W1 : [25, 12288]
                        b1 : [25, 1]
                        W2 : [12, 25]
                        b2 : [12, 1]
                        W3 : [6, 12]
                        b3 : [6, 1]

    Returns:
    parameters -- a dictionary of tensors containing W1, b1, W2, b2, W3, b3
    """

    tf.set_random_seed(1)                   # so that your "random" numbers match ours

    ### START CODE HERE ### (approx. 6 lines of code)
    W1 = tf.get_variable("W1", [25, 12288], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
    b1 = tf.get_variable("b1", [25, 1], initializer = tf.zeros_initializer())
    W2 = tf.get_variable("W2", [12, 25], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
    b2 = tf.get_variable("b2", [12, 1], initializer = tf.zeros_initializer())
    W3 = tf.get_variable("W3", [6, 12], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
    b3 = tf.get_variable("b3", [6, 1], initializer = tf.zeros_initializer())
    ### END CODE HERE ###

    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2,
                  "W3": W3,
                  "b3": b3}

    return parameters

2.3 – Tensorflow中的前向傳播

您現在將實現tensorflow中的前向傳播模組。該函式將接收引數字典並完成前向傳遞。您將使用的函式有:

  • tf.add(…, …)做一個加法

  • tf.matmul(…, …)做一個矩陣乘法

  • tf.nn.relu(…)應用ReLU啟用

問題:實現神經網路的前向傳遞。我們為您新增了numpy等價程式碼註釋,以便您可以將tensorflow實現與numpy進行比較。重要的是要注意前向傳播在z3處停止。原因在於,在tensorflow中,最後的線性層輸出作為輸入給計算損失的函式。因此,您不需要a3!

# GRADED FUNCTION: forward_propagation

def forward_propagation(X, parameters):
    """
    Implements the forward propagation for the model: LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX

    Arguments:
    X -- input dataset placeholder, of shape (input size, number of examples)
    parameters -- python dictionary containing your parameters "W1", "b1", "W2", "b2", "W3", "b3"
                  the shapes are given in initialize_parameters

    Returns:
    Z3 -- the output of the last LINEAR unit
    """

    # Retrieve the parameters from the dictionary "parameters" 
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    W3 = parameters['W3']
    b3 = parameters['b3']

    ### START CODE HERE ### (approx. 5 lines)              # Numpy Equivalents:
    Z1 = tf.add(tf.matmul(W1, X), b1)                      # Z1 = np.dot(W1, X) + b1
    A1 = tf.nn.relu(Z1)                                    # A1 = relu(Z1)
    Z2 = tf.add(tf.matmul(W2, A1), b2)                     # Z2 = np.dot(W2, a1) + b2
    A2 = tf.nn.relu(Z2)                                    # A2 = relu(Z2)
    Z3 = tf.add(tf.matmul(W3, A2), b3)                     # Z3 = np.dot(W3,Z2) + b3
    ### END CODE HERE ###

    return Z3

2.4 – 計算代價

如前所見,使用以下方法計算代價非常簡單:

tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = ..., labels = ...))

問題:實現如下代價函式。

  • 重的一點,tf.nn.softmax_cross_entropy_with_logits的「logits」和「labels」輸入形狀為(樣本數量, 類別數目)。 我們已經為您轉換了Z3和Y.

  • 另外,tf.reduce_mean是對樣本進行求和的。

# GRADED FUNCTION: compute_cost 

def compute_cost(Z3, Y):
    """
    Computes the cost

    Arguments:
    Z3 -- output of forward propagation (output of the last LINEAR unit), of shape (6, number of examples)
    Y -- "true" labels vector placeholder, same shape as Z3

    Returns:
    cost - Tensor of the cost function
    """

    # to fit the tensorflow requirement for tf.nn.softmax_cross_entropy_with_logits(...,...)
    logits = tf.transpose(Z3)
    labels = tf.transpose(Y)

    ### START CODE HERE ### (1 line of code)
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = logits, labels = labels))
    ### END CODE HERE ###

    return cost

2.5 – 反向傳播 & 引數更新

這裏您要感謝程式設計框架。所有反向傳播和引數更新都在1行程式碼裡處理,模型中加入這行程式碼非常容易。

計算代價函式後,您將建立一個「優化器」物件。執行tf.session時,必須一起呼叫此物件與代價。當被呼叫時,它將使用所選擇的方法和學習速率對給定代價進行優化。

例如,梯度下降優化器:

optimizer = tf.train.GradientDescentOptimizer(learning_rate = learning_rate).minimize(cost)

要進行優化,您應該這樣做:

_ , c = sess.run([optimizer, cost], feed_dict={X: minibatch_X, Y: minibatch_Y})

通過tensorflow圖以相反順序來計算反向傳播,從代價到輸入。

注意編碼時,我們經常使用_ 作為「一次性」變數來儲存我們稍後不需要使用的值 。這裏,_ 返回我們不需要的優化器的評估值(c取值代價變數)。

2.6 – 構建模型

現在,將把它們組合在一起!

練習:實現模型。您將會呼叫之前實現的功能。

def model(X_train, Y_train, X_test, Y_test, learning_rate = 0.0001,
          num_epochs = 1500, minibatch_size = 32, print_cost = True):
    """
    Implements a three-layer tensorflow neural network: LINEAR->RELU->LINEAR->RELU->LINEAR->SOFTMAX.

    Arguments:
    X_train -- training set, of shape (input size = 12288, number of training examples = 1080)
    Y_train -- test set, of shape (output size = 6, number of training examples = 1080)
    X_test -- training set, of shape (input size = 12288, number of training examples = 120)
    Y_test -- test set, of shape (output size = 6, number of test examples = 120)
    learning_rate -- learning rate of the optimization
    num_epochs -- number of epochs of the optimization loop
    minibatch_size -- size of a minibatch
    print_cost -- True to print the cost every 100 epochs

    Returns:
    parameters -- parameters learnt by the model. They can then be used to predict.
    """

    ops.reset_default_graph()                         # to be able to rerun the model without overwriting tf variables
    tf.set_random_seed(1)                             # to keep consistent results
    seed = 3                                          # to keep consistent results
    (n_x, m) = X_train.shape                          # (n_x: input size, m : number of examples in the train set)
    n_y = Y_train.shape[0]                            # n_y : output size
    costs = []                                        # To keep track of the cost

    # Create Placeholders of shape (n_x, n_y)
    ### START CODE HERE ### (1 line)
    X, Y = tf.placeholder(dtype=tf.float32, shape=(n_x, None), name = "X"), tf.placeholder(dtype=tf.float32, shape=(n_y, None), name = "Y")
    ### END CODE HERE ###

    # Initialize parameters
    ### START CODE HERE ### (1 line)
    parameters = initialize_parameters()
    ### END CODE HERE ###

    # Forward propagation: Build the forward propagation in the tensorflow graph
    ### START CODE HERE ### (1 line)
    Z3 = forward_propagation(X, parameters)
    ### END CODE HERE ###

    # Cost function: Add cost function to tensorflow graph
    ### START CODE HERE ### (1 line)
    cost = compute_cost(Z3, Y)
    ### END CODE HERE ###

    # Backpropagation: Define the tensorflow optimizer. Use an AdamOptimizer.
    ### START CODE HERE ### (1 line)
    optimizer = tf.train.GradientDescentOptimizer(learning_rate = learning_rate).minimize(cost)
    ### END CODE HERE ###

    # Initialize all the variables
    init = tf.global_variables_initializer()

    # Start the session to compute the tensorflow graph
    with tf.Session() as sess:

        # Run the initialization
        sess.run(init)

        # Do the training loop
        for epoch in range(num_epochs):

            epoch_cost = 0.                       # Defines a cost related to an epoch
            num_minibatches = int(m / minibatch_size) # number of minibatches of size minibatch_size in the train set
            seed = seed + 1
            minibatches = random_mini_batches(X_train, Y_train, minibatch_size, seed)

            for minibatch in minibatches:

                # Select a minibatch
                (minibatch_X, minibatch_Y) = minibatch

                # IMPORTANT: The line that runs the graph on a minibatch.
                # Run the session to execute the "optimizer" and the "cost", the feedict should contain a minibatch for (X,Y).
                ### START CODE HERE ### (1 line)
                _ , minibatch_cost = sess.run([optimizer, cost], feed_dict={X: minibatch_X, Y: minibatch_Y})
                ### END CODE HERE ###

                epoch_cost += minibatch_cost / num_minibatches

            # Print the cost every epoch
            if print_cost == True and epoch % 100 == 0:
                print ("Cost after epoch %i: %f" % (epoch, epoch_cost))
            if print_cost == True and epoch % 5 == 0:
                costs.append(epoch_cost)

        # plot the cost
        plt.plot(np.squeeze(costs))
        plt.ylabel('cost')
        plt.xlabel('iterations (per tens)')
        plt.title("Learning rate =" + str(learning_rate))
        plt.show()

        # lets save the parameters in a variable
        parameters = sess.run(parameters)
        print ("Parameters have been trained!")

        # Calculate the correct predictions
        correct_prediction = tf.equal(tf.argmax(Z3), tf.argmax(Y))

        # Calculate accuracy on the test set
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

        print ("Train Accuracy:", accuracy.eval({X: X_train, Y: Y_train}))
        print ("Test Accuracy:", accuracy.eval({X: X_test, Y: Y_test}))

        return parameters

執行下面的程式碼來訓練您的模型!在我們的機器上大約需要5分鐘。

parameters = model(X_train, Y_train, X_test, Y_test)

令人驚訝的是,您的演算法可以識別代表0到5之間的數字的手勢,精確度為71.7%。

總結:

  • 您的模型看起來足夠大,足以適應訓練集。但是,考慮到訓練和測試之間的精度差異,您可以嘗試新增L2或dropout正則化來減少過擬合。

  • 將會話視為一組程式碼來訓練模型。每次在小批次上執行會話時,都會訓練引數。總的來說,您已經執行了很多次(1500個epoch)的會話,直到您獲得訓練好的引數。

2.7 – 使用自己的圖片進行測試

祝賀您完成這項任務。現在可以拍攝您的手勢,並檢視模型的輸出:

import scipy
from PIL import Image
from scipy import ndimage

## START CODE HERE ## (PUT YOUR IMAGE NAME) 
my_image = "thumbs_up.jpg"
## END CODE HERE ##

# We preprocess your image to fit your algorithm.
fname = "images/" + my_image
image = np.array(ndimage.imread(fname, flatten=False))
my_image = scipy.misc.imresize(image, size=(64,64)).reshape((1, 64*64*3)).T
my_image_prediction = predict(my_image, parameters)

plt.imshow(image)
print("Your algorithm predicts: y = " + str(np.squeeze(my_image_prediction)))

Your algorithm predicts: y = 3

TensorFlow 基礎入門

儘管您可以看到演算法似乎對其進行了錯誤分類,但您還是值得表揚。原因在於訓練集不包含任何「豎起大拇指」手勢,所以模型不知道如何處理它!我們稱之為「不匹配的資料分佈」,它是下一門課程「構建機器學習專案」將會研究的內容。

您應該記住的是:

  • Tensorflow是用於深度學習的程式設計框架

  • Tensorflow中的兩個主要物件類是張量和操作符。

  • 在tensorflow中編碼時,您必須採取以下步驟:

    • 建立一個包含張量(變數,佔位符…)和操作(tf.matmul,tf.add,…)的圖

    • 建立一個會話

    • 初始化會話

    • 執行會話以執行圖

  • 您可以像在model()中看到的那樣多次執行圖

  • 在「優化器」物件上執行會話時,會自動完成反向傳播和優化。

TensorFlow 基礎入門

Write A Comment