吳恩達深度學習 第二課第三周編程作業_TensorFlow Tutorial TensorFlow教程


TensorFlow Tutorial TensorFlow教程

歡迎來到本周的編程作業。到目前為止,您一直使用numpy來構建神經網絡。現在我們將引導你通過一個深度學習框架,它將允許你更容易地建立神經網絡。像TensorFlow, PaddlePaddle, Torch, Caffe, Keras等機器學習框架可以顯著加快你機器學習的發展。所有這些框架都有大量文檔,您可以隨意閱讀。在這個作業中,你將學習在TensorFlow中完成以下操作:

初始化變量
開始你自己的會話
訓練算法
實現一個神經網絡

編程框架不僅可以縮短您的編碼時間,有時還可以執行優化來加速您的代碼

1 - Exploring the Tensorflow Library 探索Tensorflow庫

首先,您將導入庫:

 1 import math
 2 import numpy as np
 3 import h5py
 4 import matplotlib.pyplot as plt
 5 import tensorflow as tf
 6 from tensorflow.python.framework import ops
 7 from tf_utils import load_dataset, random_mini_batches, convert_to_one_hot, predict
 8 
 9 %matplotlib inline
10 np.random.seed(1)

現在您已經導入了庫,我們將帶您瀏覽它的不同應用程序。你將從一個例子開始,我們計算一個訓練例子的損失。

 原代碼為:

y_hat = tf.constant(36, name='y_hat')            # Define y_hat constant. Set to 36.
y = tf.constant(39, name='y')                    # Define y. Set to 39

loss = tf.Variable((y - y_hat)**2, name='loss')  # Create a variable for the loss

init = tf.global_variables_initializer()         # When init is run later (session.run(init)),
                                                 # the loss variable will be initialized and ready to be computed
with tf.Session() as session:                    # Create a session and print the output
    session.run(init)                            # Initializes the variables
    print(session.run(loss))                     # Prints the loss

根據網上參考,適應tf2.0版本修改的:

import tensorflow as tf
tf.compat.v1.disable_eager_execution()           #保證session.run()能夠正常運行
y_hat = tf.constant(36, name='y_hat')            # Define y_hat constant. Set to 36.
y = tf.constant(39, name='y')                    # Define y. Set to 39
 
loss = tf.Variable((y - y_hat)**2, name='loss')  # Create a variable for the loss
init = tf.compat.v1.global_variables_initializer()         # When init is run later (session.run(init)),
# the loss variable will be initialized and ready to be computed
with tf.compat.v1.Session () as session: # Create a session and print the output session.run(init) # Initializes the variables print(session.run(loss))

運行結果:

 

在TensorFlow中編寫和運行程序有以下步驟:

1、創建Tensorflow變量(此時,尚未直接計算)
2、實現Tensorflow變量之間的操作定義。
3、初始化Tensorflow變量
4、創建一個會話,也就是session。
5、運行會話。這將運行您上面所寫的操作。

因此,當我們為損失創建一個變量時,我們只是將損失定義為其他數量的函數,但沒有計算它的值。要對它求值,我們必須運行init=tf.global_variables_initializer()。這樣就初始化了loss變量,並且在最后一行中,我們終於能夠計算loss的值打印它的值

現在讓我們看一個簡單的例子。運行下面的單元格:
  (鏈接:https://blog.csdn.net/weixin_47440593/article/details/107721334

  參考的博客為https://blog.csdn.net/u013733326/article/details/79971488

  原博客中作者用的是tf1.x版本的,本文用的是tf2.x版本,這里掛一下網友整理的兩個版本更新的對比https://docs.qq.com/sheet/DZkR6cUZpdFJ2bUxS?tab=BB08J2

   tensorflow2.0用1.0的代碼

  )

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

運行結果:

 

 

 正如所料,您不會看到20!你得到一個變量,說結果是一個沒有形狀屬性的張量(沒有維度),類型是“int32”。你所做的一切都被放到了“計算圖(computation graph)”中,但是你還沒有運行這個計算。為了實際地將兩個數字相乘,您必須創建一個會話並運行它

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

運行結果:

20

太棒了!總之,請記住初始化變量、創建會話並在會話內運行操作

接下來,您還需要了解占位符。占位符是只能在以后指定其值的對象。要為占位符指定值,可以使用“feed字典”(feed_dict變量)傳入值。下面,我們為x創建了一個占位符。這允許我們在稍后運行會話時傳入一個數字。

# Change the value of x in the feed_dict

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

運行結果:

6

 

placeholder means '占位符'

tf.placeholder函數說明

當你第一次定義x時,你不需要為它指定一個值。占位符只是一個變量,您將在稍后運行會話時將數據分配給它。我們說,在運行會話時向這些占位符提供數據。

當您指定一個計算所需的操作時,您正在告訴TensorFlow如何構造一個計算圖。計算圖中可以有一些占位符,它們的值將稍后指定。最后,當您運行會話時,您告訴TensorFlow執行計算圖。

 

1.1 - Linear function 線性函數

 

 

你可能會發現以下功能有幫助:

·tf.matmul(…,…)來做一個矩陣乘法 #matmul 就是matrix和multiply
·tf.add(…,…)做加法
·隨機初始化n .random.randn(…)

# GRADED FUNCTION: linear_function

def linear_function():
    """
    Implements a linear function: 
            Initializes W to be a random tensor of shape (4,3)
            Initializes X to be a random tensor of shape (3,1)
            Initializes b to be a random tensor of shape (4,1)
    Returns: 
    result -- runs the session for 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 ### 
    
    # Create the session using tf.Session() and run it with sess.run(...) on the variable you want to calculate
    
    ### START CODE HERE ###
    sess = tf.compat.v1.Session()
    result = sess.run(Y)
    ### END CODE HERE ### 
    
    # close the session 
    sess.close()

    return result
# GRADED FUNCTION: linear_function
print( "result = " + str(linear_function()))

運行結果:

 

 

 

1.2 - Computing the sigmoid 計算sigmoid

太棒了!你只是實現了一個線性函數。Tensorflow提供了各種常用的神經網絡函數,比如tf.sigmoid和tf.softmax。在這個練習中,我們計算輸入的sigmoid函數。

在這個練習中,您必須

(i)創建一個占位符x,

(ii)定義使用tf計算sigmoid所需的操作。

(iii)運行會話。

練習**:實現下面的sigmoid函數。你應該使用以下方法:

tf.placeholder(tf.float32, name = "...")

tf.sigmoid(...)

sess.run(..., feed_dict = {x: z})

 

注意,在tensorflow中有兩種典型的創建和使用會話的方法:

Method 1:

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

 

Method 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):
    """
    Computes the sigmoid of z
    
    Arguments:
    z -- input value, scalar or vector
    
    Returns: 
    results -- the sigmoid of z
    """
    
    ### START CODE HERE ### ( approx. 4 lines of code)
    # Create a placeholder for x. Name it 'x'.
    x = tf.compat.v1.placeholder(tf.float32, name= 'x')

    # compute sigmoid(x)
    sigmoid = tf.sigmoid(x)

    # Create a session, and run it. Please use the method 2 explained above. 
    # You should use a feed_dict to pass z's value to x. 
    with tf.compat.v1.Session() as sess:
        # Run session and call the output "result"
        result = sess.run(sigmoid, feed_dict = {x : z})
    
    ### END CODE HERE ###
    
    return result
# GRADED FUNCTION: sigmoid
print ("sigmoid(0) = " + str(sigmoid(0)))
print ("sigmoid(12) = " + str(sigmoid(12)))

運行結果:

 

 

總結一下,你如何知道如何去**:

1、創建占位符。

2、指定與要計算的操作對應的計算圖。

3、創建會話

4、運行會話,必要時使用feed字典指定占位符變量的值。

1.3 - Computing the Cost 計算成本

 

 

 you can do it in one line of code in tensorflow!

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

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

 1 # GRADED FUNCTION: cost
 2 
 3 def cost(logits, labels):
 4     """
 5     Computes the cost using the sigmoid cross entropy
 6     
 7     Arguments:
 8     logits -- vector containing z, output of the last linear unit (before the final sigmoid activation)
 9                   包含z的向量,最后一個線性單元的輸出(在最后的s型激活之前)
10     labels -- vector of labels y (1 or 0)  標簽向量y
11     
12     Note: What we've been calling "z" and "y" in this class are respectively called "logits" and "labels" 
13     in the TensorFlow documentation. So logits will feed into z, and labels into y. 
14   注意:我們在這個類中所稱的“z”和“y”分別稱為“logits”和“label”
15     在TensorFlow文檔中。所以logits會被輸入z, label會被輸入y。  
16     Returns:
17     cost -- runs the session of the cost (formula (2))
18     """
19     
20     ### START CODE HERE ### 
21     
22     # Create the placeholders for "logits" (z) and "labels" (y) (approx. 2 lines)
23     z = tf.compat.v1.placeholder(tf.float32, name = 'z')
24     y = tf.compat.v1.placeholder(tf.float32, name = 'y')
25     
26     # Use the loss function (approx. 1 line)
27     cost = tf.nn.sigmoid_cross_entropy_with_logits(logits = z, labels = y)
28     
29     # Create a session (approx. 1 line). See method 1 above.
30     sess = tf.compat.v1.Session()
31     
32     # Run the session (approx. 1 line).
33     cost = sess.run(cost, feed_dict = {z:logits, y:labels})#使用feed字典來輸入,用z去喂logits,用y去喂label
34     
35     # Close the session (approx. 1 line). See method 1 above.
36     sess.close()
37     
38     ### END CODE HERE ###
39     
40     return cost
# GRADED FUNCTION: cost
logits = sigmoid(np.array([0.2,0.4,0.7,0.9]))
cost = cost(logits, np.array([0,0,1,1]))
print ("cost = " + str(cost))

運行結果:

 

 

 

1.4 - Using One Hot encodings 使用獨熱編碼(0、1編碼)

在深度學習中,很多時候你會得到一個數字從0到C-1的y向量,其中C是類別的數量。如果C是樣本數4,那么你可能有以下y向量,你將需要轉換如下:

這被稱為“one hot”編碼,因為在轉換后的表示中,每列中只有一個元素是“hot”(即設置為1)。在tensorflow中,你可以使用一行代碼:

tf.one_hot(labels, depth, axis)

練習:執行下面的函數取一個向量的標簽和類𝐶的總數,並返回一個獨熱編碼。使用tf.one_hot()來完成此操作。

 1 # GRADED FUNCTION: one_hot_matrix
 2 
 3 def one_hot_matrix(labels, C):
 4     """
 5     Creates a matrix where the i-th row corresponds to the ith class number and the jth column
 6                      corresponds to the jth training example. So if example j had a label i. Then entry (i,j) 
 7                      will be 1.     創建一個矩陣,其中第i行對應第i個類號,第j列對應第j個訓練樣本    
 8                                     所以如果第j個樣本對應着第i個標簽,那么entry (i,j)將會是1
 9                      
10     Arguments:
11     labels -- vector containing the labels           lables - 標簽向量
12     C -- number of classes, the depth of the one hot dimension          C - 分類數 一個熱維度的深度
13     
14     Returns: 
15     one_hot -- one hot matrix 一個熱矩陣
16     """
17     
18     ### START CODE HERE ###
19     
20     # Create a tf.constant equal to C (depth), name it 'C'. (approx. 1 line)
21     C = tf.constant(C, name = 'C')
22     
23     # Use tf.one_hot, be careful with the axis (approx. 1 line)
24     one_hot_matrix = tf.one_hot(labels, C, axis = 0)#這里是初始化,第一、二個參數都是靠形參來說輸入的
25     
26     # Create the session (approx. 1 line)
27     sess = tf.compat.v1.Session()
28     
29     # Run the session (approx. 1 line)
30     one_hot = sess.run(one_hot_matrix)#為啥這里不用喂數據呢?數據靠形參輸入的;run一下返回的是一個矩陣
31     
32     # Close the session (approx. 1 line). See method 1 above.
33     sess.close()
34     
35     ### END CODE HERE ###
36     
37     return one_hot
# GRADED FUNCTION: one_hot_matrix
labels = np.array([1,2,3,0,2,1])
one_hot = one_hot_matrix(labels, C = 4)
print ("one_hot = " + str(one_hot))

運行結果:

 

 

 

1.5 - Initialize with zeros and ones 初始化0和1

現在您將學習如何初始化一個由0和1組成的向量。您將要調用的函數是tf.ones()。要用零進行初始化,可以使用tf.zeros()。這些函數采用一個形狀,並分別返回一個充滿0和1的維形數組。

練習:實現下面的函數以獲取一個形狀並返回一個數組(形狀的維數為1)。

tf.ones(shape)

 

 1 # GRADED FUNCTION: ones
 2 
 3 def ones(shape):
 4     """
 5     Creates an array of ones of dimension shape     創建一個維度為shape的變量(數組),其值全為1
 6     
 7     Arguments:
 8     shape -- shape of the array you want to create 你要創建的數組的維度
 9         
10     Returns: 
11     ones -- array containing only ones 只包含1的數組   
12     """
13     
14     ### START CODE HERE ###
15     
16     # Create "ones" tensor using tf.ones(...). (approx. 1 line)
17     ones = tf.ones(shape)
18     
19     # Create the session (approx. 1 line)
20     sess = tf.compat.v1.Session()
21     
22     # Run the session to compute 'ones' (approx. 1 line)
23     ones = sess.run(ones)
24     
25     # Close the session (approx. 1 line). See method 1 above.
26     sess.close()
27     
28     ### END CODE HERE ###
29     return ones
# GRADED FUNCTION: ones
print ("ones = " + str(ones([3])))

運行結果:

 

 

 

2 - Building your first neural network in tensorflow 使用TensorFlow構建你的第一個神經網絡

在作業的這一部分中,您將使用tensorflow構建一個神經網絡。記住,實現tensorflow模型有兩個部分:

·創建計算圖
·運行圖表

讓我們鑽研一下你想解決的問題吧!

 

2.0 - Problem statement: SIGNS Dataset  問題陳訴:符號數據集

一天下午,我們和一些朋友決定教我們的電腦破譯手語。我們花了幾個小時在一面白牆前拍照,並得到了以下數據集。現在你的工作是建立一種算法來促進語言障礙的人與不懂手語的人之間的交流。

訓練集:有從0到5的數字的1080張圖片(64x64像素),每個數字擁有180張圖片。

測試集:有從0到5的數字的120張圖片(64x64像素),每個數字擁有5張圖片。

注意,這是符號數據集的一個子集。完整的數據集包含更多的符號。

下面是每個數字的樣本,以及我們如何表示標簽的解釋。這些都是原始圖片,我們實際上用的是64 * 64像素的圖片。

Figure 1: SIGNS dataset

首先我們需要加載數據集:

# Loading the dataset 加載數據集
X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()

更改下面的索引並運行單元格以在數據集中顯示一些示例

# Example of a picture
index = 0
plt.imshow(X_train_orig[index])
print ("y = " + str(np.squeeze(Y_train_orig[:, index])))

運行結果:

 

 

和往常一樣,我們要對數據集進行扁平化,然后再除以255以歸一化數據,除此之外,我們要需要把每個標簽轉化為獨熱向量,像上面的圖一樣。

# Flatten the training and test images  扁平化
X_train_flatten = X_train_orig.reshape(X_train_orig.shape[0], -1).T  #這里的-1被理解為unspecified value,意思是未指定為給定的
X_test_flatten = X_test_orig.reshape(X_test_orig.shape[0], -1).T
# Normalize image vectors  歸一化
X_train = X_train_flatten/255.
X_test = X_test_flatten/255.
# Convert training and test labels to one hot matrices 轉化為獨熱矩陣
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))

運行結果:

 

 

 注意12288來自64×64×3。每個圖像是正方形的,64×64像素,3是RGB顏色。在繼續之前,請確保所有這些形狀對你有意義。

您的目標是建立一種能夠高精度識別符號的算法。為此,您將構建一個tensorflow模型,該模型與之前在numpy中構建的用於貓識別的模型幾乎相同(但現在使用softmax輸出)。現在是比較numpy實現和tensorflow實現的好時機。

模型為LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX。SIGMOID輸出層已轉換為SOFTMAX。SOFTMAX層將SIGMOID泛化到有兩個以上的類時。

2.1 - Create placeholders 創建占位符

您的第一個任務是為X和y創建占位符,這將允許您在稍后運行會話時傳入訓練數據。

練習:實現下面的函數在tensorflow中創建占位符。

 1 # GRADED FUNCTION: create_placeholders
 2 
 3 def create_placeholders(n_x, n_y):
 4     """
 5     Creates the placeholders for the tensorflow session.     為TensorFlow會話創建占位符
 6     
 7     Arguments:
 8     n_x -- scalar, size of an image vector (num_px * num_px = 64 * 64 * 3 = 12288) 一個實數,圖片向量的大小(64*64*3 = 12288)
 9     n_y -- scalar, number of classes (from 0 to 5, so -> 6) 一個實數,分類數(從0到5,所以n_y = 6)
10     
11     Returns:
12     X -- placeholder for the data input, of shape [n_x, None] and dtype "float" 一個數據輸入的占位符,維度為[n_x, None],dtype = "float"
13     Y -- placeholder for the input labels, of shape [n_y, None] and dtype "float"一個對應輸入的標簽的占位符,維度為[n_y,None],dtype = "float"
14     
15     Tips:
16     - You will use None because it let's us be flexible on the number of examples you will for the placeholders.
17       In fact, the number of examples during test/train is different.
18     使用None,因為它讓我們可以靈活處理占位符提供的樣本數量。事實上,測試/訓練期間的樣本數量是不同的。
19     """
20     ### START CODE HERE ### (approx. 2 lines)
21     X = tf.compat.v1.placeholder(dtype = tf.float32, shape = [n_x, None]) ##這里注意下tf版本,和原博客不一致
22     Y = tf.compat.v1.placeholder(dtype = tf.float32, shape = [n_y, None])
23     ### END CODE HERE ###
24     
25     return X, Y
# GRADED FUNCTION: create_placeholders
X, Y = create_placeholders(12288, 6)
print ("X = " + str(X))
print ("Y = " + str(Y))

運行結果:

 

 這邊輸出的第一個參數為名字,因為沒有設置name,反復運行的話,1:0這里 1是會改變的,表示的是分配必要的內存,每次的內存不一樣。

 

2.2 - Initializing the parameters 初始化參數

第二個任務是初始化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())

Please use seed = 1 to make sure your results match ours.

原博文報錯:

AttributeError: module 'tensorflow' has no attribute 'reset_default_graph'

解決辦法:將tf.reset_default_graph()  改為 ops.reset_default_graph()

 

AttributeError: module 'tensorflow' has no attribute 'set_random_seed'

解決方法:module 'tensorflow' has no attribute 'set_random_seed',將tf.set_random_seed(1)   改為  tf.random.set_seed(1)   本人是tf2.0版本

 

AttributeError: module 'tensorflow' has no attribute 'contrib'

由於TF2.x刪除了contrib,我使用了initializer = tf.initializers.GlorotUniform(seed=1))來代替initializer=tf.contrib.layers.xavier_initializer(seed=1))

 1 # GRADED FUNCTION: initialize_parameters
 2 
 3 def initialize_parameters():
 4     """
 5     Initializes parameters to build a neural network with tensorflow. The shapes are: 初始化神經網絡的參數,參數的維度如下:
 6                         W1 : [25, 12288]
 7                         b1 : [25, 1]
 8                         W2 : [12, 25]
 9                         b2 : [12, 1]
10                         W3 : [6, 12]
11                         b3 : [6, 1]
12     
13     Returns:
14     parameters -- a dictionary of tensors containing W1, b1, W2, b2, W3, b3  包含了W和b的字典
15     """
16     
17 #     tf.set_random_seed(1)                   # so that your "random" numbers match ours
18     tf.random.set_seed(1)       
19     
20     ### START CODE HERE ### (approx. 6 lines of code)
21 #   W1 = tf.compat.v1.get_variable('W1', [25, 12288], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
22     W1 = tf.compat.v1.get_variable("W1",[25,12288],initializer = tf.initializers.GlorotUniform(seed=1))
23     b1 = tf.compat.v1.get_variable('b1', [25, 1], initializer = tf.zeros_initializer())
24 #   W2 = tf.compat.v1.get_variable('W2', [12, 25], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
25     W2 = tf.compat.v1.get_variable("W2", [12, 25], initializer = tf.initializers.GlorotUniform(seed=1))
26     b2 = tf.compat.v1.get_variable('b2', [12, 1], initializer = tf.zeros_initializer())
27 #   W3 = tf.compat.v1.get_variable('W3', [6, 1], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
28     W3 = tf.compat.v1.get_variable("W3", [6, 12], initializer = tf.initializers.GlorotUniform(seed=1))
29     b3 = tf.compat.v1.get_variable('b3', [6, 1], initializer = tf.zeros_initializer())
30 
31     ### END CODE HERE ###
32 
33     parameters = {"W1": W1,
34                   "b1": b1,
35                   "W2": W2,
36                   "b2": b2,
37                   "W3": W3,
38                   "b3": b3}
39     
40     return parameters
# GRADED FUNCTION: initialize_parameters
# tf.reset_default_graph() #用於清除默認圖形堆棧並重置全局默認圖形  由於本次使用的TF框架是2.x的原因 更改為:
ops.reset_default_graph() #用於清除默認圖形堆棧並重置全局默認圖形。 
with tf.compat.v1.Session() as sess:
    parameters = initialize_parameters()
    print("W1 = " + str(parameters["W1"]))
    print("b1 = " + str(parameters["b1"]))
    print("W2 = " + str(parameters["W2"]))
    print("b2 = " + str(parameters["b2"]))

運行結果:

 

 正如預期的那樣,還沒有對參數進行計算。

2.3 - Forward propagation in tensorflow  TensorFlow中的前向傳播

現在您將在tensorflow中實現前向傳播模塊。該函數將接受一個參數字典,並完成前向傳遞。您將使用的功能是:

tf.add(...,...) to do an addition  加法

tf.matmul(...,...) to do a matrix multiplication 矩陣乘法

tf.nn.relu(...) to apply the ReLU activation 應用relu激活函數

問題:實現神經網絡的前向傳遞。我們為您注釋了對應的numpy,以便您可以比較tensorflow實現和numpy。值得注意的是,正向傳播在z3停止。原因是在tensorflow中,最后的線性層輸出被作為函數的輸入來計算損失。因此,您不需要a3!

 1 # GRADED FUNCTION: forward_propagation
 2 
 3 def forward_propagation(X, parameters):
 4     """
 5     Implements the forward propagation for the model: LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX
 6         實現一個模型的前向傳播,模型結構為LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX
 7     Arguments:
 8     X -- input dataset placeholder, of shape (input size, number of examples) 輸入數據的占位符,維度為(輸入節點數量,樣本數量)
 9     parameters -- python dictionary containing your parameters "W1", "b1", "W2", "b2", "W3", "b3" 包含了W和b的參數的字典
10                   the shapes are given in initialize_parameters
11 
12     Returns:
13     Z3 -- the output of the last LINEAR unit 最后一個LINEAR節點的輸出
14     """
15     
16     # Retrieve the parameters from the dictionary "parameters"  從字典“parameters”檢索參數
17     W1 = parameters['W1']
18     b1 = parameters['b1']
19     W2 = parameters['W2']
20     b2 = parameters['b2']
21     W3 = parameters['W3']
22     b3 = parameters['b3']
23     
24     ### START CODE HERE ### (approx. 5 lines)              # Numpy Equivalents:
25     Z1 = tf.add(tf.matmul(W1, X), b1)                      # Z1 = np.dot(W1, X) + b1
26     #Z1 = tf.matmul(W1,X) + b1             #也可以這樣寫
27     A1 = tf.nn.relu(Z1)                                    # A1 = relu(Z1)
28     Z2 = tf.add(tf.matmul(W2, A1), b2)                     # Z2 = np.dot(W2, a1) + b2
29     A2 = tf.nn.relu(Z2)                                    # A2 = relu(Z2)
30     Z3 = tf.add(tf.matmul(W3, A2), b3)                     # Z3 = np.dot(W3,Z2) + b3
31     ### END CODE HERE ###
32     
33     return Z3
# GRADED FUNCTION: forward_propagation
# tf.reset_default_graph()  #用於清除默認圖形堆棧並重置全局默認圖形。由於使用tf2.0版本,這個不適用
ops.reset_default_graph()
with tf.compat.v1.Session() as sess:
    X, Y = create_placeholders(12288, 6)
    parameters = initialize_parameters()
    Z3 = forward_propagation(X, parameters)
    print("Z3 = " + str(Z3))

運行結果:

 

 您可能已經注意到,正向傳播不輸出任何緩存。當我們講到brackpropagation的時候,你就會明白為什么了。

2.4 Compute cost  計算成本

如前所見,很容易計算成本使用:

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基本上是對例子進行總結。

 1 # GRADED FUNCTION: compute_cost 
 2 
 3 def compute_cost(Z3, Y):
 4     """
 5     Computes the cost 計算成本
 6     
 7     Arguments:
 8     Z3 -- output of forward propagation (output of the last LINEAR unit), of shape (6, number of examples) 前向傳播的結果
 9     Y -- "true" labels vector placeholder, same shape as Z3 標簽,一個占位符,和Z3的維度相同
10     
11     Returns:
12     cost - Tensor of the cost function 成本函數的值
13     """
14     
15     # to fit the tensorflow requirement for tf.nn.softmax_cross_entropy_with_logits(...,...)
16     logits = tf.transpose(Z3) #轉置
17     labels = tf.transpose(Y)
18     
19     ### START CODE HERE ### (1 line of code)
20     cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = logits, labels = labels))
21     ### END CODE HERE ###
22     
23     return cost
# GRADED FUNCTION: compute_cost
# tf.reset_default_graph()
ops.reset_default_graph() #用於清除默認圖形堆棧並重置全局默認圖形。

with tf.compat.v1.Session() as sess:
    X, Y = create_placeholders(12288, 6)
    parameters = initialize_parameters()
    Z3 = forward_propagation(X, parameters)
    cost = compute_cost(Z3, Y)
    print("cost = " + str(cost))

運行結果:

 

 

 

2.5 - Backward propagation & parameter updates  反向傳播&參數更新

這就是你感激編程框架的地方。所有的反向傳播和參數更新都在一行代碼中完成。在模型中加入這條線是很容易的。

在計算成本函數之后。您將創建一個“optimizer”對象。在運行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 - Building the model 建立模型

現在,你要把它們結合在一起!

練習:實現模型。您將調用之前實現的函數。

  1 def model(X_train, Y_train, X_test, Y_test, learning_rate = 0.0001,
  2           num_epochs = 1500, minibatch_size = 32, print_cost = True, is_plot = True):
  3     """
  4     Implements a three-layer tensorflow neural network: LINEAR->RELU->LINEAR->RELU->LINEAR->SOFTMAX.
  5         實現一個三層的TensorFlow神經網絡:LINEAR->RELU->LINEAR->RELU->LINEAR->SOFTMAX
  6         
  7     Arguments:
  8     X_train -- training set, of shape (input size = 12288, number of training examples = 1080) 
  9     訓練集,維度為(輸入大小(輸入節點數量) = 12288, 樣本數量 = 1080)
 10     
 11     Y_train -- test set, of shape (output size = 6, number of training examples = 1080)
 12     訓練集分類數量,維度為(輸出大小(輸出節點數量) = 6, 樣本數量 = 1080)
 13     
 14     X_test -- training set, of shape (input size = 12288, number of training examples = 120)
 15     測試集,維度為(輸入大小(輸入節點數量) = 12288, 樣本數量 = 120)
 16     
 17     Y_test -- test set, of shape (output size = 6, number of test examples = 120)
 18     測試集分類數量,維度為(輸出大小(輸出節點數量) = 6, 樣本數量 = 120)
 19     
 20     learning_rate -- learning rate of the optimization  學習速率,
 21     num_epochs -- number of epochs of the optimization loop 整個訓練集的遍歷次數
 22     minibatch_size -- size of a minibatch  每個小批量數據集的大小
 23     print_cost -- True to print the cost every 100 epochs 是否打印成本,每100代打印一次
 24     is_plot - 是否繪制曲線圖
 25     
 26     Returns:
 27     parameters -- parameters learnt by the model. They can then be used to predict. 學習后的參數,然后可以用作預測
 28     """
 29     
 30     ops.reset_default_graph()                         # to be able to rerun the model without overwriting tf variables
 31     #能夠重新運行模型而不覆蓋tf變量
 32     
 33 #     tf.set_random_seed(1)                             # to keep consistent results
 34     tf.random.set_seed(1)
 35     seed = 3                                          # to keep consistent results
 36     (n_x, m) = X_train.shape                          # (n_x: input size, m : number of examples in the train set) 獲取輸入節點數量和樣本數
 37     n_y = Y_train.shape[0]                            # n_y : output size 獲取輸出節點數量
 38     costs = []                                        # To keep track of the cost 保持對成本的追蹤
 39     
 40     #要用到之前創建好的函數
 41     # Create Placeholders of shape (n_x, n_y) 給X和Y創建placeholder
 42     ### START CODE HERE ### (1 line)
 43     X, Y = create_placeholders(n_x, n_y)
 44     ### END CODE HERE ###
 45 
 46     # Initialize parameters 初始化參數
 47     ### START CODE HERE ### (1 line)
 48     parameters = initialize_parameters()
 49     ### END CODE HERE ###
 50     
 51     # Forward propagation: Build the forward propagation in the tensorflow graph
 52     ### START CODE HERE ### (1 line)
 53     Z3 = forward_propagation(X, parameters)
 54     ### END CODE HERE ###
 55     
 56     # Cost function: Add cost function to tensorflow graph
 57     ### START CODE HERE ### (1 line)
 58     cost = compute_cost(Z3, Y)
 59     ### END CODE HERE ###
 60     
 61     # Backpropagation: Define the tensorflow optimizer. Use an AdamOptimizer.反向傳播,使用Adam優化
 62     ### START CODE HERE ### (1 line)
 63     optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate = learning_rate).minimize(cost)
 64     ### END CODE HERE ###
 65     
 66     # Initialize all the variables 初始化所有的變量
 67     init = tf.compat.v1.global_variables_initializer()
 68 
 69     # Start the session to compute the tensorflow graph 開始會話並計算tensorflow圖
 70     with tf.compat.v1.Session() as sess:
 71         
 72         # Run the initialization 初始化
 73         sess.run(init)
 74         
 75         # Do the training loop
 76         for epoch in range(num_epochs):
 77 
 78             epoch_cost = 0.                       # Defines a cost related to an epoch 定義一個每代的成本
 79             num_minibatches = int(m / minibatch_size) # number of minibatches of size minibatch_size in the train set  minibatch的總數量
 80             seed = seed + 1
 81             minibatches = random_mini_batches(X_train, Y_train, minibatch_size, seed)  #原代碼
 82 #             minibatches = tf_utils.random_mini_batches(X_train, Y_train, minibatch_size, seed) #參考的代碼
 83             for minibatch in minibatches:
 84 
 85                 # Select a minibatch 選擇一個minibatch
 86                 (minibatch_X, minibatch_Y) = minibatch
 87                 
 88                 # IMPORTANT: The line that runs the graph on a minibatch. 重要:在一個小批處理上運行圖形的線。
 89                 # Run the session to execute the "optimizer" and the "cost", the feed_dict should contain a minibatch for (X,Y).
 90                 #為了執行“優化器”和“成本”,feed_dict應該包含一個針對(X,Y)的小批處理。
 91                 ### START CODE HERE ### (1 line)
 92                 _ , minibatch_cost = sess.run([optimizer, cost], feed_dict = {X : minibatch_X, Y : minibatch_Y})
 93                 ### END CODE HERE ###
 94                 
 95                 #計算這個minibatch在這一代中所占的誤差
 96                 epoch_cost += minibatch_cost / num_minibatches
 97                 
 98                
 99             # Print the cost every epoch 每一個epoch都打印成本
100             if print_cost == True and epoch % 100 == 0:
101                 print ("Cost after epoch %i: %f" % (epoch, epoch_cost))
102             if print_cost == True and epoch % 5 == 0:
103                 costs.append(epoch_cost)
104                 
105         # plot the cost 這邊自己修改成可請求的
106         if is_plot:
107             plt.plot(np.squeeze(costs))
108             plt.ylabel('cost')
109             plt.xlabel('iterations (per tens)')
110             plt.title("Learning rate =" + str(learning_rate))
111             plt.show()
112 
113         # lets save the parameters in a variable  保存學習后的參數在一個變量里
114         parameters = sess.run(parameters)
115         print ("Parameters have been trained!")
116 
117         # Calculate the correct predictions 計算當前的預測結果
118         correct_prediction = tf.equal(tf.argmax(Z3), tf.argmax(Y))
119 
120         # Calculate accuracy on the test set 計算測試集的准確率  mean是平均值的意思?
121         accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
122 
123         print ("Train Accuracy:", accuracy.eval({X: X_train, Y: Y_train}))
124         print ("Test Accuracy:", accuracy.eval({X: X_test, Y: Y_test}))
125         
126         return parameters
實現我們的模型
import time
#開始時間
start_time = time.perf_counter() 
#開始訓練
parameters = model(X_train, Y_train, X_test, Y_test)
#結束時間
end_time = time.perf_counter() 
#計算時差
print("CPU的執行時間 = " + str(end_time - start_time) + "" )

運行結果:

 

 

 

 令人驚訝的是,您的算法能夠識別表示0到5之間數字的符號,准確率為71.7%。

見解:

你的模型看起來足夠大,可以很好地適應訓練集。然而,考慮到訓練和測試精度之間的差異,你可以嘗試增加L2放棄正則化減少過擬合
可以將會話看作是訓練模型的代碼塊。每次在迷你批處理上運行會話時,它都會訓練參數。總的來說,您已經運行了會話很多次(1500個epoch),直到您獲得了經過良好訓練的參數。

 

 

 

2.7 - Test with your own image (optional / ungraded exercise)  測試你自己的圖片(選做)

恭喜你完成了這項任務。您現在可以拍攝您的手的照片,並看到您的模型的輸出。要做到這一點:

1、點擊這個筆記本上面一欄的“文件”,然后點擊“打開”進入你的Coursera中心。

2、將您的圖像添加到此Jupyter Notebook的目錄,在“images”文件夾

3、將圖像名稱寫入以下代碼4。運行代碼並檢查算法是否正確!

 

博主自己拍了5張圖片,然后裁剪成1:1的樣式,再通過格式工廠把很大的圖片縮放成64x64的圖片,同時把jpg轉化為png,因為mpimg只能讀取png的圖片。

 1 import matplotlib.pyplot as plt #plt用於顯示圖片
 2 import matplotlib.image as mpimg # mpimg 用於讀取圖片
 3 import numpy as np
 4 import tensorflow.compat.v1 as tf
 5 tf.disable_v2_behavior()
 6 from tf_utils import load_dataset, random_mini_batches, convert_to_one_hot, predict
 7 
 8 
 9 #這是博主自己拍的圖片
10 my_image1 = "hq_thumbs_up.png"                                            #定義圖片名稱
11 fileName1 = "D:/吳恩達深度學習代碼作業/代碼作業/第二課第三周編程作業/assignment3/images/" + my_image1                      #圖片地址
12 image1 = mpimg.imread(fileName1)                               #讀取圖片
13 plt.imshow(image1)                                             #顯示圖片
14 # image1=transform.resize(image1,(64,64,3)).reshape(64*64*3,1)#這個圖片的size不是很合適,調一下
15 my_image1 = image1.reshape(1,64 * 64 * 3).T                    #重構圖片
16 my_image_prediction = predict(my_image1, parameters)  #開始預測
17 print("預測結果: y = " + str(np.squeeze(my_image_prediction)))
預測豎起大拇指

運行結果:

 

 改變圖片,

 

 

2.5 - Backward propagation & parameter updates


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM