宣告
本文參考【中文】【吳恩達課后編程作業】Course 2 - 改善深層神經網路 - 第三周作業_何寬的博客-CSDN博客我對這篇博客加上自己的理解,力求看懂
本文所使用的資料已上傳到百度網盤【點擊下載】,提取碼:dvrc,請在開始之前下載好所需資料,或者在本文底部copy資料代碼,
博主使用的時python3.9,tensorflow2到目前為止,我們一直在使用numpy來自己撰寫神經網路,現在我們將一步步的使用深度學習的框架來很容易的構建屬于自己的神經網路,我們將學習TensorFlow這個框架:
- 初始化變數
- 建立一個會話
- 訓練的演算法
- 實作一個神經網路
我們知道在使用框架的時候,只需要寫好前向傳播就好了,這是因為在使用tensor轉化為Variable后具有求導的特性,即自動記錄變數的梯度相關資訊
1 - 匯入TensorFlow庫
import numpy as np import h5py import matplotlib.pyplot as plt import tensorflow as tf import tensorflow.compat.v1 as tf #以下兩行代碼是因為我們的tensorflow等級太高了,我們需要給他降級 tf.disable_v2_behavior() from tensorflow.python.framework import ops import tf_utils import time np.random.seed(1)
我們現在已經匯入了相關的庫,我們將引導你完成不同的應用,我們現在看一下下面的計算損失的公式:

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() #運行之后的初始化(ession.run(init)) #損失變數將被初始化并準備計算 with tf.Session() as session: #創建一個session并列印輸出 session.run(init) #初始化變數 print(session.run(loss)) #列印損失值
9
對于Tensorflow的代碼實作而言,實作代碼的結構如下:
-
創建Tensorflow變數(此時,尚未直接計算)
-
實作Tensorflow變數之間的操作定義
-
初始化Tensorflow變數
-
創建Session
-
運行Session,此時,之前撰寫操作都會在這一步運行,
因此,當我們為損失函式創建一個變數時,我們簡單地將損失定義為其他數量的函式,但沒有評估它的價值, 為了評估它,我們需要運行init=tf.global_variables_initializer(),初始化損失變數,在最后一行,我們最后能夠評估損失的值并列印它的值,
現在讓我們看一個簡單的例子:
a = tf.constant(2) # 定義常量,普通的tensor b = tf.constant(10) c = tf.multiply(a,b) print(c)
Tensor("Mul:0", shape=(), dtype=int32)
并沒有輸出具體的值,是因為我們還沒有創建Session
sess = tf.Session() # 創建Session print(sess.run(c))
20
? 總結一下,記得初始化變數,然后創建一個session來運行它,
? 接下來,我們需要了解一下占位符(placeholders)這個占位符只能是tensorflow1使用,因此我們需要降階,占位符是一個物件,它的值只能在稍后指定,要指定占位符的值,可以使用一個feed字典(feed_dict變數)來傳入,接下來,我們為x創建一個占位符,這將允許我們在稍后運行會話時傳入一個數字,
x = tf.placeholder(tf.int64,name='x') print(sess.run(2*x,feed_dict={x:3}))
6
當我們第一次定義x時,我們不必為它指定一個值, 占位符只是一個變數,我們會在運行會話時將資料分配給它,
線性函式
讓我們通過計算以下等式來開始編程:Y = WX + b ,W和X是隨機矩陣,b是隨機向量,
??我們計算WX + b ,其中W,X 和b是從隨機正態分布中抽取的, W的維度是(4,3),X 是(3,1),b 是(4,1), 我們開始定義一個shape=(3,1)的常量X:
def linear_function(): """ 實作一個線性功能: 初始化W,型別為tensor的隨機變數,維度為(4,3) 初始化X,型別為tensor的隨機變數,維度為(3,1) 初始化b,型別為tensor的隨機變數,維度為(4,1) 回傳: result - 運行了session后的結果,運行的是Y = WX + b """ np.random.seed(1) x = tf.constant(np.random.randn(3,1),name = 'x') w = np.random.randn(4,3) b = np.random.randn(4,1) Y = tf.add(tf.matmul(w,x),b) sess = tf.Session() result = sess.run(Y) sess.close() # 使用完記得關閉 return result
我們來測驗一下:
print('result = ' + str(linear_function()))
result = [[-2.15657382] [ 2.95891446] [-1.08926781] [-0.84538042]]
計算sigmoid
?我們已經實作了線性函式,TensorFlow提供了多種常用的神經網路的函式比如tf.softmax和 tf.sigmoid,
??我們將使用占位符變數x,當運行這個session的時候,我們西藥使用使用feed字典來輸入z,我們將創建占位符變數x,使用tf.sigmoid來定義運算子,最后運行session,我們會用到下面的代碼:
tf.placeholder(tf.float32, name = “…”)
tf.sigmoid(…)
sess.run(…, feed_dict = {x: z})
def sigmoid(z): """ 實作使用sigmoid函式計算z 引數: z - 輸入的值,標量或矢量 回傳: result - 用sigmoid計算z的值 """ x = tf.placeholder(tf.float32,name='x') sigmoid = tf.sigmoid(x) with tf.Session() as sess: result = sess.run(sigmoid,feed_dict = {x:z}) return result
我們測驗一下:
print('sigmoid(0) = ' + str(sigmoid(0))) print('sigimoid(12) = ' + str(sigmoid(12)))
sigmoid(0) = 0.5 sigimoid(12) = 0.99999386
計算成本

實作成本函式,需要用到的是:
tf.nn.sigmoid_cross_entropy_with_logits(logits = ..., labels = ...)
你的代碼應該輸入z,計算sigmoid(得到 a),然后計算交叉熵成本J ,所有的步驟都可以通過一次呼叫tf.nn.sigmoid_cross_entropy_with_logits來完成,
使用獨熱編碼(0、1編碼)
很多時候在深度學習中y yy向量的維度是從0 到C ? 1的,C 是指分類的類別數量,如果C = 4 ,那么對y 而言你可能需要有以下的轉換方式:
下面我們要做的是取一個標簽矢量和C類總數,回傳一個獨熱編碼,
def one_hot_matrix(labels,C): """ 創建一個矩陣,其中第i行對應第i個類號,第j列對應第j個訓練樣本 所以如果第j個樣本對應著第i個標簽,那么entry (i,j)將會是1 引數: lables - 標簽向量 C - 分類數 回傳: one_hot - 獨熱矩陣 """ C = tf.constant(C,name='C') one_hot_matrix = tf.one_hot(indices=labels,depth = C ,axis =0) sess = tf.Session() one_hot = sess.run(one_hot_matrix) sess.close() return(str(one_hot))
測驗一下:
labels = np.array([1,2,3,0,2,1]) one_hot = one_hot_matrix(labels,C = 4) print(str(one_hot))
[[0. 0. 0. 1. 0. 0.] [1. 0. 0. 0. 0. 1.] [0. 1. 0. 0. 1. 0.] [0. 0. 1. 0. 0. 0.]]
初始化為0和1
現在我們將學習如何用0或者1初始化一個向量,我們要用到tf.ones()和tf.zeros(),給定這些函式一個維度值那么它們將會回傳全是1或0的滿足條件的向量/矩陣,我們來看看怎樣實作它們:
def ones(shape): ones = tf.ones(shape) sess = tf.Session() ones = sess.run(ones) sess.close() return ones
測驗一下:
print('ones = '+ str(ones([4,4])))
ones = [[1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.]]
使用TensorFlow構建你的第一個神經網路
這里就是一個one_hot一個型別

首先我們需要加載資料集:
X_train_orig , Y_train_orig , X_test_orig , Y_test_orig , classes = tf_utils.load_dataset()
讓我們看看資料集里面有什么
index = 12 plt.imshow(X_train_orig[index]) print('Y = ' + str(np.squeeze(Y_train_orig[:,index])))
Y = 5
和往常一樣,我們要對資料集進行扁平化,然后再除以255以歸一化資料,除此之外,我們要需要把每個標簽轉化為獨熱向量,像上面的圖一樣,
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 #轉換為獨熱矩陣 Y_train = tf_utils.convert_to_one_hot(Y_train_orig,6) Y_test = tf_utils.convert_to_one_hot(Y_test_orig,6) print("訓練集樣本數 = " + str(X_train.shape[1])) print("測驗集樣本數 = " + 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))
訓練集樣本數 = 1080 測驗集樣本數 = 120 X_train.shape: (12288, 1080) Y_train.shape: (6, 1080) X_test.shape: (12288, 120) Y_test.shape: (6, 120)
?我們的目標是構建能夠高準確度識別符號的演算法, 要做到這一點,你要建立一個TensorFlow模型,這個模型幾乎和你之前在貓識別中使用的numpy一樣(但現在使用softmax輸出),要將您的numpy實作與tensorflow實作進行比較的話這是一個很好的機會,
??目前的模型是:LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX,SIGMOID輸出層已經轉換為SOFTMAX,當有兩個以上的類時,一個SOFTMAX層將SIGMOID一般化,
我的理解是,因為在深度學習出來之前就已經有numpy了,它并不適合深度學習,而tf.Tensor為了彌補numpy的缺點,更多是為了深度學習而生
創建placeholders
我們的第一項任務是為X和Y創建占位符,這將允許我們稍后在運行會話時傳遞您的訓練資料,
def create_placeholders(n_x,n_y): """ 為TensorFlow會話創建占位符 引數: n_x - 一個實數,圖片向量的大小(64*64*3 = 12288) n_y - 一個實數,分類數(從0到5,所以n_y = 6) 回傳: X - 一個資料輸入的占位符,維度為[n_x, None],dtype = "float" Y - 一個對應輸入的標簽的占位符,維度為[n_Y,None],dtype = "float" 提示: 使用None,因為它讓我們可以靈活處理占位符提供的樣本數量,事實上,測驗/訓練期間的樣本數量是不同的, """ X = tf.placeholder(tf.float32, [n_x, None], name="X") Y = tf.placeholder(tf.float32, [n_y, None], name="Y") return X, Y
測驗一下:
X, Y = create_placeholders(12288, 6) print("X = " + str(X)) print("Y = " + str(Y))
X = Tensor("X_4:0", shape=(12288, ?), dtype=float32)
Y = Tensor("Y_1:0", shape=(6, ?), dtype=float32)
初始化引數
初始化tensorflow中的引數,我們將使用Xavier初始化權重和用零來初始化偏差,比如:
在tensorflow2中已經不支持tf.contrib了,但是有tf.glorot與之代替
W1 = tf.get_variable("W1", [25,12288], initializer=tf.glorot_uniform_initializer(seed=1)) b1 = tf.get_variable("b1", [25,1], initializer = tf.zeros_initializer())
tf.Variable() 每次都在創建新物件,對于get_variable()來說,對于已經創建的變數物件,就把那個物件回傳,如果沒有創建變數物件的話,就創建一個新的,
def initialize_parameters(): """ 初始化神經網路的引數,引數的維度如下: W1 : [25, 12288] b1 : [25, 1] W2 : [12, 25] b2 : [12, 1] W3 : [6, 12] b3 : [6, 1] 回傳: parameters - 包含了W和b的字典 """ tf.set_random_seed(1) #指定隨機種子 W1 = tf.get_variable("W1",[25,12288],initializer=tf.glorot_uniform_initializer(seed=1)) b1 = tf.get_variable("b1",[25,1],initializer=tf.zeros_initializer()) W2 = tf.get_variable("W2", [12, 25], initializer=tf.glorot_uniform_initializer(seed=1)) b2 = tf.get_variable("b2", [12, 1], initializer = tf.zeros_initializer()) W3 = tf.get_variable("W3", [6, 12], initializer=tf.glorot_uniform_initializer(seed=1)) b3 = tf.get_variable("b3", [6, 1], initializer = tf.zeros_initializer()) parameters = {"W1": W1, "b1": b1, "W2": W2, "b2": b2, "W3": W3, "b3": b3} return parameters
測驗一下:
tf.reset_default_graph() #用于清除默認圖形堆疊并重置全域默認圖形, with tf.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"]))
W1 = <tf.Variable 'W1:0' shape=(25, 12288) dtype=float32_ref> b1 = <tf.Variable 'b1:0' shape=(25, 1) dtype=float32_ref> W2 = <tf.Variable 'W2:0' shape=(12, 25) dtype=float32_ref> b2 = <tf.Variable 'b2:0' shape=(12, 1) dtype=float32_ref>
前向傳播
我們要實作神經網路的前向傳播,我們會拿numpy與TensorFlow實作的神經網路的代碼作比較,最重要的是前向傳播要在Z3處停止,因為在TensorFlow中最后的線性輸出層的輸出作為計算損失函式的輸入,所以不需要A3.
def forward_propagation(X,parameters): """ 實作一個模型的前向傳播,模型結構為LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX 引數: X - 輸入資料的占位符,維度為(輸入節點數量,樣本數量) parameters - 包含了W和b的引數的字典 回傳: Z3 - 最后一個LINEAR節點的輸出 """ W1 = parameters['W1'] b1 = parameters['b1'] W2 = parameters['W2'] b2 = parameters['b2'] W3 = parameters['W3'] b3 = parameters['b3'] Z1 = tf.add(tf.matmul(W1,X),b1) # Z1 = np.dot(W1, X) + b1 #Z1 = tf.matmul(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 return Z3
測驗一下:
tf.reset_default_graph() #用于清除默認圖形堆疊并重置全域默認圖形, with tf.Session() as sess: X,Y = create_placeholders(12288,6) parameters = initialize_parameters() Z3 = forward_propagation(X,parameters) print("Z3 = " + str(Z3))
Z3 = Tensor("Add_2:0", shape=(6, ?), dtype=float32)
計算成本
def compute_cost(Z3,Y): """ 計算成本 引數: Z3 - 前向傳播的結果 Y - 標簽,一個占位符,和Z3的維度相同 回傳: cost - 成本值 """ logits = tf.transpose(Z3) #轉置 labels = tf.transpose(Y) #轉置 cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits,labels=labels)) return cost
測驗一下:
tf.reset_default_graph() with tf.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))
cost = Tensor("Mean:0", shape=(), dtype=float32)
構建模型
博主自己在里面想加一下L2正則化
l2_loss = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
loss = tf.add_n([cost] + l2_loss, name="loss")
但是發現除了時間變長,什么變化也沒有,希望大佬幫忙指正
def model(X_train,Y_train,X_test,Y_test, learning_rate=0.0001,num_epochs=1500,minibatch_size=32, print_cost=True,is_plot=True): """ 實作一個三層的TensorFlow神經網路:LINEAR->RELU->LINEAR->RELU->LINEAR->SOFTMAX 引數: X_train - 訓練集,維度為(輸入大小(輸入節點數量) = 12288, 樣本數量 = 1080) Y_train - 訓練集分類數量,維度為(輸出大小(輸出節點數量) = 6, 樣本數量 = 1080) X_test - 測驗集,維度為(輸入大小(輸入節點數量) = 12288, 樣本數量 = 120) Y_test - 測驗集分類數量,維度為(輸出大小(輸出節點數量) = 6, 樣本數量 = 120) learning_rate - 學習速率 num_epochs - 整個訓練集的遍歷次數 mini_batch_size - 每個小批量資料集的大小 print_cost - 是否列印成本,每100代列印一次 is_plot - 是否繪制曲線圖 回傳: parameters - 學習后的引數 """ ops.reset_default_graph() #能夠重新運行模型而不覆寫tf變數 tf.set_random_seed(1) seed = 3 (n_x , m) = X_train.shape #獲取輸入節點數量和樣本數 n_y = Y_train.shape[0] #獲取輸出節點數量 costs = [] #成本集 #給X和Y創建placeholder X,Y = create_placeholders(n_x,n_y) #初始化引數 parameters = initialize_parameters() #前向傳播 Z3 = forward_propagation(X,parameters) #計算成本 cost = compute_cost(Z3,Y) l2_loss = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES) loss = tf.add_n([cost] + l2_loss, name="loss") #反向傳播,使用Adam優化 optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost) #初始化所有的變數 init = tf.global_variables_initializer() #開始會話并計算 with tf.Session() as sess: #初始化 sess.run(init) #正常訓練的回圈 for epoch in range(num_epochs): epoch_cost = 0 #每代的成本 num_minibatches = int(m / minibatch_size) #minibatch的總數量 seed = seed + 1 minibatches = tf_utils.random_mini_batches(X_train,Y_train,minibatch_size,seed) for minibatch in minibatches: #選擇一個minibatch (minibatch_X,minibatch_Y) = minibatch #資料已經準備好了,開始運行session _ , minibatch_cost = sess.run([optimizer,cost],feed_dict={X:minibatch_X,Y:minibatch_Y}) #計算這個minibatch在這一代中所占的誤差 epoch_cost = epoch_cost + minibatch_cost / num_minibatches #記錄并列印成本 ## 記錄成本 if epoch % 5 == 0: costs.append(epoch_cost) #是否列印: if print_cost and epoch % 100 == 0: print("epoch = " + str(epoch) + " epoch_cost = " + str(epoch_cost)) #是否繪制圖譜 if is_plot: plt.plot(np.squeeze(costs)) plt.ylabel('cost') plt.xlabel('iterations (per tens)') plt.title("Learning rate =" + str(learning_rate)) plt.show() #保存學習后的引數 parameters = sess.run(parameters) print("引數已經保存到session,") #計算當前的預測結果 correct_prediction = tf.equal(tf.argmax(Z3),tf.argmax(Y)) #計算準確率 accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float")) print("訓練集的準確率:", accuracy.eval({X: X_train, Y: Y_train})) print("測驗集的準確率:", accuracy.eval({X: X_test, Y: Y_test})) return parameters
我們來正式運行一下模型,沒有顯卡是真的很慢
#開始時間 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) + " 秒" )
epoch = 0 epoch_cost = 1.8557019233703616 epoch = 100 epoch_cost = 1.0172552628950642 epoch = 200 epoch_cost = 0.733183786724553 epoch = 300 epoch_cost = 0.5730706182393162 epoch = 400 epoch_cost = 0.46869878651517827 epoch = 500 epoch_cost = 0.3812084595362345 epoch = 600 epoch_cost = 0.31382483198787225 epoch = 700 epoch_cost = 0.25364145591403503 epoch = 800 epoch_cost = 0.20389534262093628 epoch = 900 epoch_cost = 0.16644860126755456 epoch = 1000 epoch_cost = 0.1466958195422635 epoch = 1100 epoch_cost = 0.10727535018866712 epoch = 1200 epoch_cost = 0.08655262428025405 epoch = 1300 epoch_cost = 0.05933702635494144 epoch = 1400 epoch_cost = 0.05227517494649599
引數已經保存到session, 訓練集的準確率: 0.9990741 測驗集的準確率: 0.725 CPU的執行時間 = 1832.5628375000001 秒
現在,我們的演算法已經可以識別0-5的手勢符號了,準確率在72.5%,
??我們的模型看起來足夠大了,可以適應訓練集,但是考慮到訓練與測驗的差異,你也完全可以嘗試添加L2或者dropout來減少過擬合,將session視為一組代碼來訓練模型,在每個minibatch上運行會話時,都會訓練我們的引數,總的來說,你已經運行了很多次(1500代),直到你獲得訓練有素的引數,
好了,讓我們拍幾張照片來測驗一下吧!
我在做的時候在調庫的時候他總是報錯,就是因為tensorflow1和tensorflow2不兼容,然后經過一系列的思想斗爭,最終將所使用的庫拿到這里運行一下,發現不報錯了
以下是我們要使用的包
def predict(X, parameters): W1 = tf.convert_to_tensor(parameters["W1"]) b1 = tf.convert_to_tensor(parameters["b1"]) W2 = tf.convert_to_tensor(parameters["W2"]) b2 = tf.convert_to_tensor(parameters["b2"]) W3 = tf.convert_to_tensor(parameters["W3"]) b3 = tf.convert_to_tensor(parameters["b3"]) params = {"W1": W1, "b1": b1, "W2": W2, "b2": b2, "W3": W3, "b3": b3} x = tf.placeholder("float", [12288, 1]) z3 = forward_propagation_for_predict(x, params) p = tf.argmax(z3) sess = tf.Session() prediction = sess.run(p, feed_dict = {x: X}) return prediction
還有這個
def forward_propagation_for_predict(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'] # 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 return Z3
博主自己拍了6張圖片,然后裁剪成1:1的樣式(其實原本就是正方形的就是1:1),再通過格式工廠把很大的圖片縮放成64x64的圖片,同時把jpg轉化為png,因為mpimg只能讀取png的圖片,
import matplotlib.pyplot as plt # plt 用于顯示圖片 import matplotlib.image as mpimg # mpimg 用于讀取圖片 import numpy as np #這是我女朋友拍的圖片 my_image1 = "5.png" #定義圖片名稱 fileName1 = "C:/Users/TJRA/Desktop/" + my_image1 #圖片地址 image1 = mpimg.imread(fileName1) #讀取圖片 plt.imshow(image1) #顯示圖片 my_image1 = image1.reshape(1,64 * 64 * 3).T #重構圖片 my_image_prediction = predict(my_image1, parameters) #開始預測 print("預測結果: y = " + str(np.squeeze(my_image_prediction)))
預測結果: y = 2
import matplotlib.pyplot as plt # plt 用于顯示圖片 import matplotlib.image as mpimg # mpimg 用于讀取圖片 import numpy as np #這是我女朋友拍的圖片 my_image1 = "1.png" #定義圖片名稱 fileName1 = "C:/Users/TJRA/Desktop/" + my_image1 #圖片地址 image1 = mpimg.imread(fileName1) #讀取圖片 plt.imshow(image1) #顯示圖片 my_image1 = image1.reshape(1,64 * 64 * 3).T #重構圖片 my_image_prediction = predict(my_image1, parameters) #開始預測 print("預測結果: y = " + str(np.squeeze(my_image_prediction)))
預測結果: y = 1
import matplotlib.pyplot as plt # plt 用于顯示圖片 import matplotlib.image as mpimg # mpimg 用于讀取圖片 import numpy as np #這是我女朋友拍的圖片 my_image1 = "2.png" #定義圖片名稱 fileName1 = "C:/Users/TJRA/Desktop/" + my_image1 #圖片地址 image1 = mpimg.imread(fileName1) #讀取圖片 plt.imshow(image1) #顯示圖片 my_image1 = image1.reshape(1,64 * 64 * 3).T #重構圖片 my_image_prediction = predict(my_image1, parameters) #開始預測 print("預測結果: y = " + str(np.squeeze(my_image_prediction)))
預測結果: y = 2

博主拍了六張照片,只對了2張,事實看來,這次的神經網路還有很大的提升空間
相關庫代碼
#tf_utils.py import h5py import numpy as np import tensorflow as tf import math def load_dataset(): train_dataset = h5py.File('datasets/train_signs.h5', "r") train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set features train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your train set labels test_dataset = h5py.File('datasets/test_signs.h5', "r") test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set features test_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labels classes = np.array(test_dataset["list_classes"][:]) # the list of classes train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0])) test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0])) return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes def random_mini_batches(X, Y, mini_batch_size = 64, seed = 0): """ Creates a list of random minibatches from (X, Y) Arguments: X -- input data, of shape (input size, number of examples) Y -- true "label" vector (containing 0 if cat, 1 if non-cat), of shape (1, number of examples) mini_batch_size - size of the mini-batches, integer seed -- this is only for the purpose of grading, so that you're "random minibatches are the same as ours. Returns: mini_batches -- list of synchronous (mini_batch_X, mini_batch_Y) """ m = X.shape[1] # number of training examples mini_batches = [] np.random.seed(seed) # Step 1: Shuffle (X, Y) permutation = list(np.random.permutation(m)) shuffled_X = X[:, permutation] shuffled_Y = Y[:, permutation].reshape((Y.shape[0],m)) # Step 2: Partition (shuffled_X, shuffled_Y). Minus the end case. num_complete_minibatches = math.floor(m/mini_batch_size) # number of mini batches of size mini_batch_size in your partitionning for k in range(0, num_complete_minibatches): mini_batch_X = shuffled_X[:, k * mini_batch_size : k * mini_batch_size + mini_batch_size] mini_batch_Y = shuffled_Y[:, k * mini_batch_size : k * mini_batch_size + mini_batch_size] mini_batch = (mini_batch_X, mini_batch_Y) mini_batches.append(mini_batch) # Handling the end case (last mini-batch < mini_batch_size) if m % mini_batch_size != 0: mini_batch_X = shuffled_X[:, num_complete_minibatches * mini_batch_size : m] mini_batch_Y = shuffled_Y[:, num_complete_minibatches * mini_batch_size : m] mini_batch = (mini_batch_X, mini_batch_Y) mini_batches.append(mini_batch) return mini_batches def convert_to_one_hot(Y, C): Y = np.eye(C)[Y.reshape(-1)].T return Y def predict(X, parameters): W1 = tf.convert_to_tensor(parameters["W1"]) b1 = tf.convert_to_tensor(parameters["b1"]) W2 = tf.convert_to_tensor(parameters["W2"]) b2 = tf.convert_to_tensor(parameters["b2"]) W3 = tf.convert_to_tensor(parameters["W3"]) b3 = tf.convert_to_tensor(parameters["b3"]) params = {"W1": W1, "b1": b1, "W2": W2, "b2": b2, "W3": W3, "b3": b3} x = tf.placeholder("float", [12288, 1]) z3 = forward_propagation_for_predict(x, params) p = tf.argmax(z3) sess = tf.Session() prediction = sess.run(p, feed_dict = {x: X}) return prediction def forward_propagation_for_predict(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'] # 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 return Z3
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/528791.html
標籤:其他
