基于PaddlePaddle框架的BP神经网络的鲍鱼年龄的预测
生活随笔
收集整理的這篇文章主要介紹了
基于PaddlePaddle框架的BP神经网络的鲍鱼年龄的预测
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
# 經(jīng)典的線性回歸模型主要用來預(yù)測一些存在著線性關(guān)系的數(shù)據(jù)集。回歸模型可以理解為:存在一個點集,用一條曲線去擬合它分布的過程。如果擬合曲線是一條直線,則稱為線性回歸。如果是一條二次曲線,則被稱為二次回歸。線性回歸是回歸模型中最簡單的一種。 本教程使用PaddlePaddle建立起一個鮑魚年齡預(yù)測模型。
#
# 在線性回歸中:
#
# (1)假設(shè)函數(shù)是指,用數(shù)學(xué)的方法描述自變量和因變量之間的關(guān)系,它們之間可以是一個線性函數(shù)或非線性函數(shù)。 在本次線性回顧模型中,我們的假設(shè)函數(shù)為 Y’= wX+b ,其中,Y’表示模型的預(yù)測結(jié)果(預(yù)測的鮑魚年齡),用來和真實的Y區(qū)分。模型要學(xué)習的參數(shù)即:w,b。
#
# (2)損失函數(shù)是指,用數(shù)學(xué)的方法衡量假設(shè)函數(shù)預(yù)測結(jié)果與真實值之間的誤差。這個差距越小預(yù)測越準確,而算法的任務(wù)就是使這個差距越來越小。 建立模型后,我們需要給模型一個優(yōu)化目標,使得學(xué)到的參數(shù)能夠讓預(yù)測值Y’盡可能地接近真實值Y。這個實值通常用來反映模型誤差的大小。不同問題場景下采用不同的損失函數(shù)。 對于線性模型來講,最常用的損失函數(shù)就是均方誤差(Mean Squared Error, MSE)。
#
# (3)優(yōu)化算法:神經(jīng)網(wǎng)絡(luò)的訓(xùn)練就是調(diào)整權(quán)重(參數(shù))使得損失函數(shù)值盡可能得小,在訓(xùn)練過程中,將損失函數(shù)值逐漸收斂,得到一組使得神經(jīng)網(wǎng)絡(luò)擬合真實模型的權(quán)重(參數(shù))。所以,優(yōu)化算法的最終目標是找到損失函數(shù)的最小值。而這個尋找過程就是不斷地微調(diào)變量w和b的值,一步一步地試出這個最小值。 常見的優(yōu)化算法有隨機梯度下降法(SGD)、Adam算法等等
# # # **Step1.數(shù)據(jù)準備**
#
# **認識數(shù)據(jù):**
#
#
# 數(shù)據(jù)集共4177行,每行9列
#
# 前8列用來描述鮑魚的各種信息,分別是性別、長度、直徑、高度、總重量、皮重、內(nèi)臟重量、克重,最后一列為該鮑魚的年齡
#
#
# **數(shù)據(jù)準備:**
#
# 1.從文件中加載數(shù)據(jù)
#
# 2.對數(shù)據(jù)進行歸一化
#
# 3.構(gòu)造數(shù)據(jù)集提供器# 讀取文件
import numpy as np
import os
import matplotlib.pyplot as pltdata_X = []
data_Y = []
# 將性別(M:雄性,F:雌性,I:未成年)映射成數(shù)字
sex_map = { 'I': 0, 'M': 1, 'F': 2 }
with open ('/home/aistudio/data/data15920/baoyu.txt') as f:for line in f.readlines():line = line.split(',')line[0] = sex_map[line[0]]data_X.append(line[:-1])data_Y.append(line[-1:])
# 轉(zhuǎn)換為nparray
data_X = np.array(data_X, dtype='float32')
data_Y = np.array(data_Y, dtype='float32')
# 檢查大小
print('data shape', data_X.shape, data_Y.shape)
print('data_x shape[1]', data_X.shape[1])
# 歸一化
for i in range(data_X.shape[1]):_min = np.min(data_X[:,i]) #每一列的最小值_max = np.max(data_X[:,i]) #每一列的最大值data_X[:, i] = (data_X[:, i] - _min) / (_max - _min) #歸一化到0-1之間import paddle
import paddle.fluid as fluid
from sklearn.model_selection import train_test_split
# 分割訓(xùn)練集、測試集
X_train, X_test, y_train, y_test = train_test_split(data_X, #被劃分的樣本特征集data_Y, #被劃分的樣本標簽test_size=0.2, #測試集占比random_state=0) #隨機數(shù)種子,在需要重復(fù)試驗的時候,保證得到一組一樣的隨機數(shù)
# 自定義reader,每次返回一個樣本數(shù)據(jù)
def reader_creator(_X, _Y):def reader():for _x, _y in zip(_X, _Y):yield [_x, _y] #返回Iterable對象return reader# 一個minibatch中有16個數(shù)據(jù)
BATCH_SIZE = 20#定義了用于訓(xùn)練與驗證的數(shù)據(jù)提供器。提供器每次讀入一個大小為BATCH_SIZE的數(shù)據(jù)批次。
#BATCH_SIZE個數(shù)據(jù)項組成一個mini batch。
train_reader = paddle.batch(reader_creator(X_train, y_train),batch_size=BATCH_SIZE)
test_reader = paddle.batch(reader_creator(X_test, y_test), batch_size=BATCH_SIZE)# # **Step2.網(wǎng)絡(luò)配置**
#
# **(1)網(wǎng)絡(luò)搭建**:對于線性回歸來講,它就是一個從輸入到輸出的簡單的全連接層。
#
# 對于鮑魚年齡預(yù)測數(shù)據(jù)集,假設(shè)鮑魚屬性和年齡之間的關(guān)系可以被屬性間的線性組合描述。#定義輸入的形狀和數(shù)據(jù)類型,張量變量x,表示8維的特征值
x = fluid.layers.data(name='x', shape=[8], dtype='float32')#定義輸出的形狀和數(shù)據(jù)類型,張量y,表示目標值
y = fluid.layers.data(name='y', shape=[1], dtype='float32')#定義一個簡單的線性網(wǎng)絡(luò),連接輸入和輸出的全連接層
#input:輸入;
#size:該層輸出單元的數(shù)目
#act:激活函數(shù)
fc2 = fluid.layers.fc(input=x, size=200, bias_attr=True)
drop = fluid.layers.dropout(x=fc2, dropout_prob=0.5)
fc3 = fluid.layers.fc(input=drop, size=800, bias_attr=True, act='relu')
drop = fluid.layers.dropout(x=fc3, dropout_prob=0.5)
fc4 = fluid.layers.fc(input=drop, size=800, bias_attr=True, act='relu')
drop = fluid.layers.dropout(x=fc4, dropout_prob=0.5)
fc5 = fluid.layers.fc(input=drop, size=100, bias_attr=True, act='relu')
y_predict=fluid.layers.fc(input=fc5, size=1, bias_attr=True, act=None)# **(2)定義損失函數(shù)**
#
# 此處使用均方差損失函數(shù)。
#
# square_error_cost(input,lable):接受輸入預(yù)測值和目標值,并返回方差估計,即為(y-y_predict)的平方
cost = fluid.layers.square_error_cost(input=y_predict, label=y) #求方差
avg_cost = fluid.layers.mean(cost) #對方差求平均值,得到平均損失
#克隆main_program得到test_program,使用參數(shù)for_test來區(qū)分該程序是用來訓(xùn)練還是用來測試,該api請在optimization之前使用.
test_program = fluid.default_main_program().clone(for_test=True)
# **(3)定義優(yōu)化函數(shù)**# 此處使用的是隨機梯度下降。
optimizer = fluid.optimizer.AdamOptimizer(learning_rate=0.0001)
opts = optimizer.minimize(avg_cost)# 完成上述定義,也就是完成了 fluid.default_main_program 的構(gòu)建過程,fluid.default_main_program 中承載著神經(jīng)網(wǎng)絡(luò)模型,前向反向計算,以及優(yōu)化算法對網(wǎng)絡(luò)中可學(xué)習參數(shù)的更新。# **fluid的設(shè)計思想:**
# 用戶編寫一段python程序,通過調(diào)用 Fluid 提供的算子,向一段 Program 中添加**變量**以及**對變量的操作**(Operators )。
#
# 用戶**只需要描述核心的前向計算**,不需要關(guān)心反向計算、分布式下以及異構(gòu)設(shè)備下如何計算。
#
# Fluid 的 Program 的形式上類似一段 C++ 或 Java 程序。
#
# 包含:
#
# 1.本地變量的定義
#
# 2.一系列的operator
#
#
# **用戶完成網(wǎng)絡(luò)定義后,一段 Fluid 程序中通常存在 2 段 Program:**
#
# 1.**fluid.default_startup_program**:定義了創(chuàng)建模型參數(shù),輸入輸出,以及模型中可學(xué)習參數(shù)的初始化等各種操作
#
# default_startup_program 可以由框架自動生成,使用時無需顯示地創(chuàng)建
#
#
# 2.**fluid.default_main_program** :定義了神經(jīng)網(wǎng)絡(luò)模型,前向反向計算,以及優(yōu)化算法對網(wǎng)絡(luò)中可學(xué)習參數(shù)的更新
#
# 使用Fluid的核心就是構(gòu)建起 default_main_program# # **Step3.網(wǎng)絡(luò)訓(xùn)練 & Step4.網(wǎng)絡(luò)評估**# **(1)創(chuàng)建Executor**
#
# 首先定義運算場所 fluid.CPUPlace()和 fluid.CUDAPlace(0)分別表示運算場所為CPU和GPU
#
# Executor:接收傳入的program,通過run()方法運行program。#use_cuda為False,表示運算場所為CPU;use_cuda為True,表示運算場所為GPU
use_cuda = False
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()#創(chuàng)建一個Executor實例exe
exe = fluid.Executor(place) #正式進行網(wǎng)絡(luò)訓(xùn)練前,需先執(zhí)行參數(shù)初始化
exe.run(fluid.default_startup_program())# **(2)定義輸入數(shù)據(jù)維度**
#
# DataFeeder負責將數(shù)據(jù)提供器(train_reader,test_reader)返回的數(shù)據(jù)轉(zhuǎn)成一種特殊的數(shù)據(jù)結(jié)構(gòu),使其可以輸入到Executor中。
#
# feed_list設(shè)置向模型輸入的向變量表或者變量表名# In[ ]:# 告知網(wǎng)絡(luò)傳入的數(shù)據(jù)分為兩部分,第一部分是x值,第二部分是y值
feeder = fluid.DataFeeder(place=place, feed_list=[x, y])# **(3)定義繪制訓(xùn)練過程的損失值變化趨勢的方法draw_train_process**# In[ ]:iter=0;
iters=[]
train_costs=[]def draw_train_process(iters,train_costs):title="training cost"plt.title(title, fontsize=24)plt.xlabel("iter", fontsize=14)plt.ylabel("cost", fontsize=14)plt.plot(iters, train_costs,color='red',label='training cost') plt.grid()plt.show()# **(4)訓(xùn)練并保存模型**
#
# Executor接收傳入的program,并根據(jù)feed map(輸入映射表)和fetch_list(結(jié)果獲取表) 向program中添加feed operators(數(shù)據(jù)輸入算子)和fetch operators(結(jié)果獲取算子)。 feed map為該program提供輸入數(shù)據(jù)。fetch_list提供program訓(xùn)練結(jié)束后用戶預(yù)期的變量。
#
# 使用feed方式送入訓(xùn)練數(shù)據(jù),先將reader數(shù)據(jù)轉(zhuǎn)換為PaddlePaddle可識別的Tensor數(shù)據(jù),傳入執(zhí)行器進行訓(xùn)練。
#
# 注:enumerate() 函數(shù)用于將一個可遍歷的數(shù)據(jù)對象(如列表、元組或字符串)組合為一個索引序列,同時列出數(shù)據(jù)和數(shù)據(jù)下標# In[ ]:#訓(xùn)練輪數(shù):所有訓(xùn)練數(shù)據(jù)的一個前向傳遞和一個后向傳遞為一輪
EPOCH_NUM=100
#模型保存路徑
model_save_dir = "/home/aistudio/work/fit_a_line.inference.model"for pass_id in range(EPOCH_NUM): #訓(xùn)練EPOCH_NUM輪# 開始訓(xùn)練for batch_id, data in enumerate(train_reader()): #遍歷train_reader迭代器train_cost = exe.run(program=fluid.default_main_program(),#運行主程序feed=feeder.feed(data), #喂入一個batch的訓(xùn)練數(shù)據(jù)fetch_list=[avg_cost]) #fetch 誤差、準確率,fetch_list中設(shè)置要獲取的值if batch_id % 100 == 0:print("Pass:%d, Cost:%0.5f" % (pass_id, train_cost[0])) #每訓(xùn)練100次,打印一次平均損失值iter=iter+1 iters.append(iter) train_costs.append(train_cost[0])# 開始驗證,并輸出驗證集經(jīng)過一輪的平均損失test_costs = []for batch_id, data in enumerate(test_reader()): #遍歷test_reader迭代器test_cost= exe.run(program=test_program, #運行測試programfeed=feeder.feed(data), #喂入一個batch的測試數(shù)據(jù)fetch_list=[avg_cost]) #fetch均方誤差,fetch_list中設(shè)置要獲取的值test_costs.append(test_cost[0]) test_cost = (sum(test_costs) / len(test_costs)) #每輪的平均誤差print('Test:%d, Cost:%0.5f' % (pass_id, test_cost)) #打印平均損失#保存模型# 如果保存路徑不存在就創(chuàng)建
if not os.path.exists(model_save_dir):os.makedirs(model_save_dir)
print ('save models to %s' % (model_save_dir))#保存訓(xùn)練參數(shù)到指定路徑中,構(gòu)建一個專門用預(yù)測的program
fluid.io.save_inference_model(model_save_dir, #保存預(yù)測model的路徑['x'], #預(yù)測需要 feed 的數(shù)據(jù)[y_predict], #保存預(yù)測結(jié)果的變量exe) #exe 保存 inference model
#繪制訓(xùn)練過程,損失隨迭代次數(shù)的變化
draw_train_process(iters,train_costs)# # **Step5.模型預(yù)測**
# **(1)創(chuàng)建預(yù)測用的Executor**# In[ ]:infer_exe = fluid.Executor(place) #創(chuàng)建推測用的executor
inference_scope = fluid.core.Scope() #Scope指定作用域# **(2)可視化真實值與預(yù)測值方法定義**
def draw_infer_result(groud_truths,infer_results):title='abalone'plt.title(title, fontsize=24)x = np.arange(1,20) y = xplt.plot(x, y)plt.xlabel('ground truth', fontsize=14)plt.ylabel('infer result', fontsize=14)plt.scatter(groud_truths, infer_results,color='green',label='training cost') plt.grid()plt.show()# **(3)開始預(yù)測**
#
# 通過fluid.io.load_inference_model,預(yù)測器會從params_dirname中讀取已經(jīng)訓(xùn)練好的模型,來對從未遇見過的數(shù)據(jù)進行預(yù)測。with fluid.scope_guard(inference_scope):#修改全局/默認作用域(scope), 運行時中的所有變量都將分配給新的scope。#從指定目錄中加載預(yù)測模型[inference_program, #預(yù)測用的programfeed_target_names, #一個str列表,它包含需要在預(yù)測 Program 中提供數(shù)據(jù)的變量的名稱。fetch_targets] = fluid.io.load_inference_model(#fetch_targets: 從中可以得到預(yù)測結(jié)果。model_save_dir, #model_save_dir:模型保存路徑 infer_exe) #infer_exe: 預(yù)測用executor#獲取預(yù)測數(shù)據(jù)INFER_BATCH_SIZE=10infer_reader = paddle.batch(reader_creator(X_test, y_test), batch_size=INFER_BATCH_SIZE)#從infer_reader中分割xinfer_data = next(infer_reader())infer_x = np.array([data[0] for data in infer_data]).astype("float32")infer_y= np.array([data[1] for data in infer_data]).astype("float32")results = infer_exe.run(inference_program, #預(yù)測模型feed={feed_target_names[0]: np.array(infer_x)}, #喂入要預(yù)測的x值fetch_list=fetch_targets) #得到推測結(jié)果infer_results=[] #預(yù)測值groud_truths=[] #真實值sum_cost=0for i in range(INFER_BATCH_SIZE):infer_result=results[0][i] #經(jīng)過預(yù)測后的值ground_truth=infer_y[i] #真實值infer_results.append(infer_result)groud_truths.append(ground_truth)print("No.%d: infer result is %.2f,ground truth is %.2f" % (i, infer_result,ground_truth))cost=np.power(infer_result-ground_truth,2)sum_cost+=costprint("平均誤差為:",sum_cost/INFER_BATCH_SIZE)draw_infer_result(groud_truths,infer_results)
項目源代碼獲取請點擊這里
總結(jié)
以上是生活随笔為你收集整理的基于PaddlePaddle框架的BP神经网络的鲍鱼年龄的预测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机信息检索 服务方式,计算机信息检索
- 下一篇: 鲍鱼年龄预测