1. 程式人生 > >識別貓的單隱藏層神經網絡(我的第一個模型)

識別貓的單隱藏層神經網絡(我的第一個模型)

負數 所有 sha 分類 col 缺少 right shadow 一個

摘要:算法詳解;代碼;可視化查看超參數影響

目標:識別一張圖是不是貓

數據集:訓練數據209張64*64

測試數據50張 64*64

方案:二分分類法

算法:logistic回歸 技術分享圖片 ,限定了你的輸入(X),和做優化時,需要優化哪些量(W,b)

激活函數:sigmod 技術分享圖片

sigmod函數圖像:

技術分享圖片

特點:所有輸出y值都落在0-1之間

ps:logistic回歸是算法,但其激活函數取sigmod,是因為,你想得到一個在(0-1)之間的值,所以,這才用到了sigmod函數。

損失函數:技術分享圖片

成本函數技術分享圖片

成本函數的由來:假設第1張圖真實值是1(第一張圖本來就是貓),

預測時,認為

它是貓的概率是0.8,體現在sigmod函數輸出0.8,(a=0.8)

則正確率技術分享圖片

同理,如果假設某圖不是只貓,其y=0,

其正確率 技術分享圖片

合並技術分享圖片

技術分享圖片

log是一個單調遞增的函數,可以變成一個凸函數,便於使用梯度下降進行優化

把上式log化

技術分享圖片

上式還不是成本函數,因為,上式值越大表明,越準確

按照習慣來說,需要成本函數越小,預測值與真實值越接近,越準確

所以,直接加個負號就行了

所以,成本函數就是技術分享圖片

計算圖

技術分享圖片

代碼:

  1. 載入數據
  2. 處理數據(/255),縮小數據,因為1比255更好計算
  3. 初始化(w,b),w是一個n維列向量,b=0
  4. 建立sigmod函數
  5. 利用訓練數據集 建立正反向傳播函數,如計算圖,並求梯度,以便使用梯度下降
  6. 建立優化(梯度下降)函數,利用好梯度,選取下降方向,另需選取學習率技術分享圖片
    ,叠代次數。這兩個選取與過擬合,欠擬合息息相關
  7. 利用叠代num_iterations次後,出來的w,b。組裝好sigmod函數,預測,測試集數據
  8. 測試/訓練集 正確率輸出,利於判斷
  9. 可視化輸出,比較出一個好的學習率技術分享圖片,和叠代次數。(超參數選擇,一個無法學習的東西

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import h5py
  4. import sys
  5. sys.path.append(r‘F:\study\assignment2‘)
  6. from lr_utils import
    load_dataset
  7. ‘‘‘‘‘
  8. 數據讀取與標準化
  9. 讀取的x數據是(20964,64,3)的格式
  10. 需要將其平鋪成(64*64*3,209
  11. ‘‘‘
  12. train_x_orig,train_y_orig,test_x_orig,test_y_orig,classes=load_dataset()
  13. train_x_flatten=train_x_orig.reshape(train_x_orig.shape[0],-1).T
  14. test_x_flatten=test_x_orig.reshape(test_x_orig.shape[0],-1).T
  15. #上面一定要記得轉置,因為reshape成了(mn)的形式
  16. #-1,是不用去考慮到底要轉換成多少列了,只要是負數就行
  17. #然後是將數據縮小,便於計算,因為1255更好計算,反正也不影響計算機結果
  18. #標準化數據 rgb值都小於255
  19. train_x=train_x_flatten / 255
  20. test_x=test_x_flatten / 255
  21. train_y=train_y_orig
  22. test_y=test_y_orig
  23. #上面就把數據整理好了
  24. ‘‘‘‘‘
  25. 下面開始寫函數了
  26. ‘‘‘
  27. #建立sigmod函數
  28. def sigmod(x):
  29. return (1/(1+np.exp(-x)))
  30. #初始化wb, psw是一個列向量
  31. def initialize(n_x):
  32. w=np.zeros(shape=(n_x,1))
  33. b=0
  34. return(w,b)
  35. #建立正反向傳播函數
  36. def propagate(w,b,X,Y):
  37. """
  38. 正向傳播
  39. """
  40. A=sigmod(np.dot(w.T,X)+b)
  41. m=X.shape[1]
  42. cost=(-1/m)*np.sum(Y * np.log(A)+(1-Y) * np.log(1-A))
  43. ‘‘‘‘‘ ps:尼瑪不知道為什這個三點冒號也要按照縮進格式來
  44. 反向傳播
  45. ‘‘‘
  46. dw=np.dot(X,(A-Y).T)/m
  47. db=np.sum(A-Y)/m
  48. ‘‘‘‘‘
  49. 組裝數據
  50. ‘‘‘
  51. grads={‘dw‘:dw,‘db‘:db}
  52. return (grads,cost)
  53. #建立優化函數
  54. def optimize(w,b,X,Y,num_iterations,learning_rate,print_cost):
  55. costs=[]
  56. for i in range(num_iterations):
  57. grads,cost=propagate(w,b,X,Y)
  58. dw=grads[‘dw‘]
  59. db=grads[‘db‘]
  60. w=w-learning_rate*dw
  61. b=b-learning_rate*db
  62. #記錄誤差
  63. if i % 100==0:
  64. costs.append(cost)
  65. if print_cost and i%100==0:
  66. print(叠代次數:%i.誤差值:%f‘ %(i,cost))
  67. #組裝數據
  68. params={‘w‘:w,‘b‘:b}
  69. return (params,costs)
  70. #建立預測函數
  71. def predict(w,b,X):
  72. value=sigmod(np.dot(w.T,X)+b)
  73. Y_prediction=(value>0.5)+0
  74. ‘‘‘‘‘
  75. 對於上一代碼詳解
  76. value>0.5是個判斷語句,>0.5會返回True
  77. +0.是讓布爾值轉化成數字,1
  78. ‘‘‘
  79. return Y_prediction
  80. #下面是整合所有函數了
  81. def model(X_train,Y_train,X_test,Y_test,num_iterations=2000,learning_rate=0.01,print_cost=False):
  82. #先調用X_trainY_train,來訓練處wb
  83. m=X_train.shape[1]
  84. w,b=initialize(X_train.shape[0])
  85. params,costs=optimize(w,b,X_train,Y_train,num_iterations,learning_rate,print_cost)
  86. w,b=params[‘w‘],params[‘b‘]
  87. #計算預測值
  88. Y_prediction_train=predict(w,b,X_train)
  89. Y_prediction_test=predict(w,b,X_test)
  90. #比較
  91. print(‘TrainRightRate:‘,format(100-np.mean(np.abs(Y_prediction_train-Y_train))*100),‘%‘)
  92. print(‘TestRightRate:‘,format(100-np.mean(np.abs(Y_prediction_test-Y_test))*100),‘%‘)
  93. ‘‘‘‘‘
  94. 上面代碼詳解
  95. absY_p-T_r),此處兩相比較,相同,預測對了,則詳減為0,預測錯了,則為1或者-1
  96. abs,全部取正
  97. mean,平均值,即有多少個+-1在所有數據中,即在所有數據中錯誤的個數/總數據
  98. 我要的是正確率,所以前面要用100來減
  99. ‘‘‘
  100. #數據組裝
  101. d={
  102. ‘costs‘:costs,
  103. ‘Y_prediction_train‘:Y_prediction_train,
  104. ‘Y_prediction_test‘:Y_prediction_test,
  105. ‘w‘:w,
  106. ‘b‘:b,
  107. ‘learning_rate‘:learning_rate,
  108. ‘num_iterations‘:num_iterations}
  109. return d
  110. #d=model(train_x,train_y,test_x,test_y,num_iterations=2000,learning_rate=0.005,print_cost=True)
  111. ‘‘‘‘‘
  112. 上面就算是整個模型搭建完了,下面是可視化
  113. 表示叠代次數,學習率,與成本函數的關系
  114. ‘‘‘
  115. learning_rate=[0.01,0.001,0.0001]
  116. models={}
  117. for i in learning_rate:
  118. print ("learning rate is: " + str(i))
  119. models[str(i)]=model(train_x,train_y,test_x,test_y,num_iterations=500,learning_rate=i)
  120. print (‘\n‘ + "-------------------------------------------------------" + ‘\n‘)
  121. for i in learning_rate:
  122. plt.plot(np.squeeze(models[str(i)][‘costs‘]),label=str(models[str(i)]["learning_rate"]))
  123. plt.ylabel(‘cost‘)
  124. plt.xlabel(‘iterations‘)
  125. legend = plt.legend(loc=‘upper center‘, shadow=True)
  126. frame = legend.get_frame()
  127. frame.set_facecolor(‘0.90‘)
  128. plt.show()

代碼筆記

  1. 從另外一個文件中導入py文件中的某個函數

    import sys

    sys.path.append(r‘path‘)

    from lr_utils import load_datasert

  2. 記住X要組裝成(n,m)矩陣,w是一個(n,1)的列向量

    有利於記住使用np.dot()時,哪個放前面,哪個放後面,也 有利於廣播時是否需要轉置的判斷

  3. 數據處理

    本例子中是將每個元/255,讓[0,255],的數據計算,變成了[0,1]的數據計算,加快計算

    還有很多其他的數據處理方式,還沒學到,多做多學

  4. np.reshape(a,-1)中-1的妙用,只要把一個數組的行寫出來了,列向量可以使用-1,讓計算機自動計算分配,只要是負值就行
  5. w-=learning_rate*dw 不知道為什麽不能使用,需要常規操作,w=w-learning_rate*dw
  6. A and B,兩個判斷,只要有一個是False,那整個語句就是錯的,本例子,使用and來控制是否輸出叠代次數與誤差
  7. 布爾值轉數字 讓布爾值‘+0‘就行了,numpy對於判斷語句,也是並行運行的
  8. 對於同類型的數據,多用字典dict組裝,如梯度,初始值
  9. np.squeeze()函數,將(5,1,1)轉換成(5,)降維處理,有利於運行,也是可視化操作時,作為輸入時,不可缺少的操作

    >>> a=np.random.randn(10000,1,1,1,1)

    >>> sys.getsizeof(a)

    80160

    >>> b=np.random.randn(10000)

    >>> sys.getsizeof(b)

    80096

  10. 可視化操作中,參數解釋:loc:選擇把線型說明放在哪個地方,shadow,是否加營養

    frame.set_facecolor(‘0.9‘),給說明的地方加了框之後,再選擇填充框的透明度

  11. 使用‘‘‘作解釋時,也需要遵循Python的縮進格式,否則會報錯
  12. 空一行 print(‘\n‘)

識別貓的單隱藏層神經網絡(我的第一個模型)