共有7897張圖像,其中訓練集5897張,測試集2000張圖像,每幅圖像的大小為32*32*3
數據集:
鏈接:https://pan.baidu.com/s/1hnBhDg6XJW7m_bmqA-tNXw
提取碼:appn
# 導入依賴包 import sys import numpy as np # import lr_utils import matplotlib.pyplot as plt import paddle import paddle.fluid as fluid %matplotlib inline
# 加載數據, 並展示一張,由於數據圖片較小,所以顯示出來比較模糊 train_set_x_orig=np.load("/home/aistudio/data/data1589/traindata.npy") train_set_y=np.load("/home/aistudio/data/data1589/trainlabel.npy") test_set_x_orig=np.load("/home/aistudio/data/data1589/testdata.npy") test_set_y=np.load("/home/aistudio/data/data1589/testlabel.npy") plt.imshow(train_set_x_orig[2]) plt.show()
# 輸出數據集的信息 m_train=train_set_x_orig.shape[0] m_test=test_set_x_orig.shape[0] num_px=train_set_x_orig.shape[1] print ("訓練樣本數: m_train = " + str(m_train)) print ("測試樣本數: m_test = " + str(m_test)) print ("圖片高度/寬度: num_px = " + str(num_px)) print ("圖片大小: (" + str(num_px) + ", " + str(num_px) + ", 3)") print ("train_set_x shape: " + str(train_set_x_orig.shape)) print ("train_set_y shape: " + str(train_set_y.shape)) print ("test_set_x shape: " + str(test_set_x_orig.shape)) print ("test_set_y shape: " + str(test_set_y.shape))
訓練樣本數: m_train = 5897 測試樣本數: m_test = 2000 圖片高度/寬度: num_px = 32 圖片大小: (32, 32, 3) train_set_x shape: (5897, 32, 32, 3) train_set_y shape: (5897, 1) test_set_x shape: (2000, 32, 32, 3) test_set_y shape: (2000, 1)
###因為paddlepaddle認識的數據是3*l*h的,所以需要進行數據格式轉換 train_set_x = np.array(train_set_x_orig).reshape(m_train, 3, num_px, num_px).astype(np.float32) train_set_y = np.array(train_set_y).reshape(m_train, 1).astype(np.float32) test_set_x = np.array(test_set_x_orig).reshape(m_test, 3, num_px, num_px).astype(np.float32) test_set_y = np.array(test_set_y).reshape(m_test, 1).astype(np.float32)
#歸一化 train_set_x=train_set_x/ 255.0 * 2.0 - 1.0 test_set_x=test_set_x/ 255.0 * 2.0 - 1.0
# 讀取訓練數據或測試數據 def read_data(train_set_x,train_set_y,buffer_size): def reader(): for i in range(buffer_size): yield train_set_x[i,:], int(train_set_y[i]) return reader
def convolutional_neural_network(): """ 定義卷積神經網絡分類器: 輸入的二維圖像,經過兩個卷積-池化層,使用以softmax為激活函數的全連接層作為輸出層 Args: img -- 輸入的原始圖像數據 Return: predict -- 分類的結果 """ img = fluid.layers.data( name='img', shape =[3,32,32],dtype = 'float32') #第一個卷積層 # hidden = fluid.nets.simple_img_conv_pool(input, num_filters, filter_size, pool_size, pool_stride, pool_padding=0) hidden=fluid.nets.simple_img_conv_pool( input=img, num_filters=64, filter_size=10, pool_size=5, pool_stride=1, pool_padding=0 ) #第二個卷積層 h2=fluid.nets.simple_img_conv_pool( input=hidden, num_filters=128, filter_size=3, pool_size=2, pool_stride=1, pool_padding=0 ) # predict = fluid.layers.fc(h2,size=1,act='sigmoid') predict = fluid.layers.fc(h2,size=2,act='softmax') #predict=fluid.layers.dropout(x=predict, dropout_prob=0.5) return predict
# 設置訓練場所 use_cuda = True place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
#配置網絡結構 def train_func(): label = fluid.layers.data(name='label', shape = [1],dtype = 'int64') #predict = convolutional_neural_network() predict=convolutional_neural_network() # 損失函數,cross_entropy 函數內部使用交叉熵損失函數 cost = fluid.layers.cross_entropy(input=predict, label=label) avg_cost = fluid.layers.mean(cost) return avg_cost
def optimizer_func(): # 創建Momentum優化器,並設置學習率(learning_rate)、動量(momentum) optimizer=fluid.optimizer.Momentum(learning_rate=0.001,momentum=0.5) #使用Adam算法進行優化, learning_rate 是學習率(它的大小與網絡的訓練收斂速度有關系) #optimizer = fluid.optimizer.AdamOptimizer(learning_rate=0.001) return optimizer
feed_order = ['img', 'label'] #數據格式 params_dirname = "./DNN_model" #模型保存路徑
# 事件處理函數 from paddle.utils.plot import Ploter from paddle.fluid.contrib.trainer import EndStepEvent train_title = "Train cost" test_title = "Test cost" plot_cost = Ploter(train_title, test_title) step = 0 def event_handler_plot(event): global step if isinstance(event, EndStepEvent): if event.step % 2 == 0: # 若干個batch,記錄cost if event.metrics[0] < 10: plot_cost.append(train_title, step, event.metrics[0]) plot_cost.plot() if event.step % 20 == 0: # 若干個batch,記錄cost test_metrics = trainer.test( reader=test_reader, feed_order=feed_order) if test_metrics[0] < 10: plot_cost.append(test_title, step, test_metrics[0]) plot_cost.plot() # if test_metrics[0] < 1.0: # # 如果准確率達到閾值,則停止訓練 # print('loss is less than 10.0, stop') # trainer.stop() # 將參數存儲,用於預測使用 if params_dirname is not None: trainer.save_params(params_dirname ) step += 1
#訓練所用到的具體數據 BATCH_SIZE=16 # 設置訓練reader train_reader = paddle.batch( paddle.reader.shuffle( read_data(train_set_x,train_set_y,buffer_size=209), buf_size=50), batch_size=BATCH_SIZE) # 設置測試reader test_reader = paddle.batch( paddle.reader.shuffle( read_data(test_set_x,test_set_y,buffer_size=50), buf_size=20), batch_size=BATCH_SIZE)
#創建訓練器 from paddle.fluid.contrib.trainer import Trainer trainer= Trainer( train_func= train_func, place= place, optimizer_func= optimizer_func )
#開始訓練 trainer.train( reader=train_reader, num_epochs=30, event_handler=event_handler_plot, feed_order= feed_order )
from paddle.fluid.contrib.inferencer import Inferencer inferencer = Inferencer( infer_func=convolutional_neural_network, param_path=params_dirname, place=place)
#取出一個 mini-batch for mini_batch in test_reader(): # 轉化為 numpy 的 ndarray 結構,並且設置數據類型 test_x = np.array([data[0] for data in mini_batch]).astype("float32") test_y = np.array([data[1] for data in mini_batch]).astype("int64") # 真實進行預測 mini_batch_result = inferencer.infer({'img': test_x}) result=(mini_batch_result[0][:,-1]>0.5)+0 #True or False 轉0/1,直接后面+0即可 # 打印預測結果 # mini_batch_result = np.argsort(mini_batch_result) #找出可能性最大的列標,升序排列, ###經過分析,這是多分類問題會用到的函數,找出概率值最大的下標 # mini_batch_result = mini_batch_result[0][:, -1] #把這些列標拿出來 print('預測結果:%s'%result) # 打印真實結果 label = np.array(test_y) # 轉化為 label print('真實結果:%s'%label) break
# 查看百分比 def right_ratio(right_counter, total): ratio = float(right_counter)/total return ratio
# 評估函數 data_set 是一個reader def evl(data_set): total = 0 #操作的元素的總數 right_counter = 0 #正確的元素 pass_num = 0 # print(liruoyi) for mini_batch in data_set(): pass_num += 1 #預測 test_x = np.array([data[0] for data in mini_batch]).astype("float32") test_y = np.array([data[1] for data in mini_batch]).astype("int64") mini_batch_result = inferencer.infer({'img': test_x}) mini_batch_result=(mini_batch_result[0][:,-1]>0.5)+0 #True or False 轉0/1,直接后面+0即可 #預測的結果 # mini_batch_result = np.argsort(mini_batch_result) #找出可能性最大的列標,升序排列 # mini_batch_result = mini_batch_result[0][:, -1]+0 #把這些列標拿出來 #print('預測結果:%s'%result) label = np.array(test_y) # 轉化為 label # print('真實結果:%s'%label) #計數 label_len = len(label) total += label_len for i in range(label_len): if mini_batch_result[i] == label[i]: right_counter += 1 ratio = right_ratio(right_counter, total) return ratio
ratio = evl(train_reader) print('訓練數據的正確率 %0.2f%%'%(ratio*100)) ratio = evl(test_reader) print('預測數據的正確率 %0.2f%%'%(ratio*100))