新手第四课-PaddlePaddle快速入门
新手第四課-PaddlePaddle快速入門
文章目錄
- 新手第四課-PaddlePaddle快速入門
- PaddlePaddle基礎(chǔ)命令
- 計(jì)算常量的加法:1+1
- 計(jì)算變量的加法:1+1
- 使用PaddlePaddle做線性回歸
PaddlePaddle基礎(chǔ)命令
PaddlePaddle是百度開源的深度學(xué)習(xí)框架,類似的深度學(xué)習(xí)框架還有谷歌的 Tensorflow、Facebook的 Pytorch等,在入門深度學(xué)習(xí)時(shí),學(xué)會(huì)并使用一門常見的框架,可以讓學(xué)習(xí)效率大大提升。
在 PaddlePaddle中,計(jì)算的對(duì)象是張量,我們可以先使用PaddlePaddle來計(jì)算一個(gè)[[1, 1], [1, 1]] * [[1, 1], [1, 1]]。
計(jì)算常量的加法:1+1
首先導(dǎo)入 PaddlePaddle庫
import paddle.fluid as fluid定義兩個(gè)張量的常量x1和x2,并指定它們的形狀是[2, 2],并賦值為1鋪滿整個(gè)張量,類型為int64.
# 定義兩個(gè)張量 x1 = fluid.layers.fill_constant(shape=[2, 2], value=1, dtype='int64') x2 = fluid.layers.fill_constant(shape=[2, 2], value=1, dtype='int64')接著定義一個(gè)操作,該計(jì)算是將上面兩個(gè)張量進(jìn)行加法計(jì)算,并返回一個(gè)求和的算子。PaddlePaddle提供了大量的操作,比如加減乘除、三角函數(shù)等,讀者可以在 fluid.layers找到。
# 將兩個(gè)張量求和 y1 = fluid.layers.sum(x=[x1, x2])然后創(chuàng)建一個(gè)解釋器,可以在這里指定計(jì)算使用CPU或GPU。當(dāng)使用CPUPlace()時(shí)使用的是CPU,如果是CUDAPlace()使用的是GPU。解析器是之后使用它來進(jìn)行計(jì)算過的,比如在執(zhí)行計(jì)算之前我們要先執(zhí)行參數(shù)初始化的program也是要使用到解析器的,因?yàn)橹挥薪馕銎鞑拍軋?zhí)行program。
# 創(chuàng)建一個(gè)使用CPU的解釋器 place = fluid.CPUPlace() exe = fluid.executor.Executor(place) # 進(jìn)行參數(shù)初始化 exe.run(fluid.default_startup_program())最后執(zhí)行計(jì)算,program的參數(shù)值是主程序,不是上一步使用的是初始化參數(shù)的程序,program默認(rèn)一共有兩個(gè),分別是default_startup_program()和default_main_program()。fetch_list參數(shù)的值是在解析器在run之后要輸出的值,我們要輸出計(jì)算加法之后輸出結(jié)果值。最后計(jì)算得到的也是一個(gè)張量。
# 進(jìn)行運(yùn)算,并把y的結(jié)果輸出 result = exe.run(program=fluid.default_main_program(),fetch_list=[y1]) print(result)計(jì)算結(jié)果為:[array([[2, 2], [2, 2]])]
計(jì)算變量的加法:1+1
上面計(jì)算的是張量常量的1+1,并不能隨意修改常量的值,所以下面我們要編寫一個(gè)使用張量變量作為乘數(shù)的程序,類似是一個(gè)占位符,等到將要計(jì)算時(shí),再把要計(jì)算的值添加到占位符中進(jìn)行計(jì)算。
導(dǎo)入PaddlePaddle庫和numpy的庫。
import paddle.fluid as fluid import numpy as np定義兩個(gè)張量,并不指定該張量的形狀和值,它們是之后動(dòng)態(tài)賦值的。這里只是指定它們的類型和名字,這個(gè)名字是我們之后賦值的關(guān)鍵。
# 定義兩個(gè)張量 a = fluid.layers.create_tensor(dtype='int64', name='a') b = fluid.layers.create_tensor(dtype='int64', name='b')使用同樣的方式,定義這個(gè)兩個(gè)張量的加法操作。
# 將兩個(gè)張量求和 y = fluid.layers.sum(x=[a, b])這里我們同樣是創(chuàng)建一個(gè)使用CPU的解析器,和進(jìn)行參數(shù)初始化。
# 創(chuàng)建一個(gè)使用CPU的解釋器 place = fluid.CPUPlace() exe = fluid.executor.Executor(place) # 進(jìn)行參數(shù)初始化 exe.run(fluid.default_startup_program())然后使用numpy創(chuàng)建兩個(gè)張量值,之后我們要計(jì)算的就是這兩個(gè)值。
# 定義兩個(gè)要計(jì)算的變量 a1 = np.array([3, 2]).astype('int64') b1 = np.array([1, 1]).astype('int64')這次exe.run()的參數(shù)有點(diǎn)不一樣了,多了一個(gè)feed參數(shù),這個(gè)就是要對(duì)張量變量進(jìn)行賦值的。賦值的方式是使用了鍵值對(duì)的格式,key是定義張量變量是指定的名稱,value就是要傳遞的值。在fetch_list參數(shù)中,筆者希望把a(bǔ), b, y的值都輸出來,所以要使用3個(gè)變量來接受返回值。
# 進(jìn)行運(yùn)算,并把y的結(jié)果輸出 out_a, out_b, result = exe.run(program=fluid.default_main_program(),feed={'a': a1, 'b': b1},fetch_list=[a, b, y]) print(out_a, " + ", out_b," = ", result)計(jì)算結(jié)果為:[3 2] + [1 1] = [4 3]
使用PaddlePaddle做線性回歸
在上面的教學(xué)中,教大家學(xué)會(huì)用PaddlePaddle做基本的算子運(yùn)算,下面來教大家如何用PaddlePaddle來做簡單的線性回歸,包括從定義網(wǎng)絡(luò)到使用自定義的數(shù)據(jù)進(jìn)行訓(xùn)練,最后驗(yàn)證我們網(wǎng)絡(luò)的預(yù)測(cè)能力。
首先導(dǎo)入PaddlePaddle庫和一些工具類庫。
import paddle.fluid as fluid import paddle import numpy as np定義一個(gè)簡單的線性網(wǎng)絡(luò),這個(gè)網(wǎng)絡(luò)非常簡單,結(jié)構(gòu)是:輸出層–>>隱層–>>輸出層__,這個(gè)網(wǎng)絡(luò)一共有2層,因?yàn)檩斎雽硬凰憔W(wǎng)絡(luò)的層數(shù)。更具體的就是一個(gè)大小為100,激活函數(shù)是ReLU的全連接層和一個(gè)輸出大小為1的全連接層,就這樣構(gòu)建了一個(gè)非常簡單的網(wǎng)絡(luò)。這里使用輸入fluid.layers.data()定義的輸入層類似fluid.layers.create_tensor(),也是有name屬性,之后也是根據(jù)這個(gè)屬性來填充數(shù)據(jù)的。這里定義輸入層的形狀為13,這是因?yàn)椴ㄊ款D房價(jià)數(shù)據(jù)集的每條數(shù)據(jù)有13個(gè)屬性,我們之后自定義的數(shù)據(jù)集也是為了符合這一個(gè)維度。
# 定義一個(gè)簡單的線性網(wǎng)絡(luò) x = fluid.layers.data(name='x', shape=[13], dtype='float32') hidden = fluid.layers.fc(input=x, size=100, act='relu') net = fluid.layers.fc(input=hidden, size=1, act=None)接著定義神經(jīng)網(wǎng)絡(luò)的損失函數(shù),這里同樣使用了fluid.layers.data()這個(gè)接口,這個(gè)可以理解為數(shù)據(jù)對(duì)應(yīng)的結(jié)果,上面name為x的fluid.layers.data()為屬性數(shù)據(jù)。這里使用了平方差損失函數(shù)(square_error_cost),PaddlePaddle提供了很多的損失函數(shù)的接口,比如交叉熵?fù)p失函數(shù)(cross_entropy)。因?yàn)楸卷?xiàng)目是一個(gè)線性回歸任務(wù),所以我們使用的是平方差損失函數(shù)。因?yàn)閒luid.layers.square_error_cost()求的是一個(gè)Batch的損失值,所以我們還要對(duì)他求一個(gè)平均值。
# 定義損失函數(shù) y = fluid.layers.data(name='y', shape=[1], dtype='float32') cost = fluid.layers.square_error_cost(input=net, label=y) avg_cost = fluid.layers.mean(cost)定義損失函數(shù)之后,可以在主程序(fluid.default_main_program)中克隆一個(gè)程序作為預(yù)測(cè)程序,用于訓(xùn)練完成之后使用這個(gè)預(yù)測(cè)程序進(jìn)行預(yù)測(cè)數(shù)據(jù)。這個(gè)定義的順序不能錯(cuò),因?yàn)槲覀兌x的網(wǎng)絡(luò)結(jié)構(gòu),損失函數(shù)等等都是更加順序記錄到PaddlePaddle的主程序中的。主程序定義了神經(jīng)網(wǎng)絡(luò)模型,前向反向計(jì)算,以及優(yōu)化算法對(duì)網(wǎng)絡(luò)中可學(xué)習(xí)參數(shù)的更新,是我們整個(gè)程序的核心,這個(gè)是PaddlePaddle已經(jīng)幫我們實(shí)現(xiàn)的了,我們只需注重網(wǎng)絡(luò)的構(gòu)建和訓(xùn)練即可。
# 復(fù)制一個(gè)主程序,方便之后使用 test_program = fluid.default_main_program().clone(for_test=True)接著是定義訓(xùn)練使用的優(yōu)化方法,這里使用的是隨機(jī)梯度下降優(yōu)化方法。PaddlePaddle提供了大量的優(yōu)化函數(shù)接口,除了本項(xiàng)目使用的隨機(jī)梯度下降法(SGD),還有Momentum、Adagrad、Adagrad等等,讀者可以更加自己項(xiàng)目的需求使用不同的優(yōu)化方法。
# 定義優(yōu)化方法 optimizer = fluid.optimizer.SGDOptimizer(learning_rate=0.01) opts = optimizer.minimize(avg_cost)然后是創(chuàng)建一個(gè)解析器,我們同樣是使用CPU來進(jìn)行訓(xùn)練。創(chuàng)建解析器之后,使用解析器來執(zhí)行fluid.default_startup_program()初始化參數(shù)。
# 創(chuàng)建一個(gè)使用CPU的解釋器 place = fluid.CPUPlace() exe = fluid.Executor(place) # 進(jìn)行參數(shù)初始化 exe.run(fluid.default_startup_program())我們使用numpy定義一組數(shù)據(jù),這組數(shù)據(jù)的每一條數(shù)據(jù)有13個(gè),這是因?yàn)槲覀冊(cè)诙x網(wǎng)絡(luò)的輸入層時(shí),shape是13,但是每條數(shù)據(jù)的后面12個(gè)數(shù)據(jù)是沒意義的,因?yàn)楣P者全部都是使用0來填充,純粹是為了符合數(shù)據(jù)的格式而已。這組數(shù)據(jù)是符合y = 2 * x + 1,但是程序是不知道的,我們之后使用這組數(shù)據(jù)進(jìn)行訓(xùn)練,看看強(qiáng)大的神經(jīng)網(wǎng)絡(luò)是否能夠訓(xùn)練出一個(gè)擬合這個(gè)函數(shù)的模型。最后定義了一個(gè)預(yù)測(cè)數(shù)據(jù),是在訓(xùn)練完成,使用這個(gè)數(shù)據(jù)作為x輸入,看是否能夠預(yù)測(cè)于正確值相近結(jié)果。
# 定義訓(xùn)練和測(cè)試數(shù)據(jù) x_data = np.array([[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]).astype('float32') y_data = np.array([[3.0], [5.0], [7.0], [9.0], [11.0]]).astype('float32') test_data = np.array([[6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]).astype('float32')定義數(shù)據(jù)之后,我們就可以使用數(shù)據(jù)進(jìn)行訓(xùn)練了。我們這次訓(xùn)練了10個(gè)pass,讀者可根據(jù)情況設(shè)置更多的訓(xùn)練輪數(shù),通常來說訓(xùn)練的次數(shù)越多,模型收斂的越好。同樣我們使用的時(shí)profram是fluid.default_main_program(),feed中是在訓(xùn)練時(shí)把數(shù)據(jù)傳入fluid.layers.data()定義的變量中,及那個(gè)鍵值對(duì)的key對(duì)用的就是fluid.layers.data()中的name的值。我們讓訓(xùn)練過程中輸出avg_cost的值。
在訓(xùn)練過程中,我們可以看到輸出的損失值在不斷減小,證明我們的模型在不斷收斂。
# 開始訓(xùn)練10個(gè)passfor pass_id in range(10):train_cost = exe.run(program=fluid.default_main_program(),feed={'x': x_data, 'y': y_data},fetch_list=[avg_cost])print("Pass:%d, Cost:%0.5f" % (pass_id, train_cost[0]))訓(xùn)練完成之后,我們使用上面克隆主程序得到的預(yù)測(cè)程序了預(yù)測(cè)我們剛才定義的預(yù)測(cè)數(shù)據(jù)。預(yù)測(cè)數(shù)據(jù)同樣作為x在feed輸入,在預(yù)測(cè)時(shí),理論上是不用輸入y的,但是要符合輸入格式,我們模擬一個(gè)y的數(shù)據(jù)值,這個(gè)值并不會(huì)影響我們的預(yù)測(cè)結(jié)果。fetch_list的值,也就是我們執(zhí)行預(yù)測(cè)之后要輸出的結(jié)果,這是網(wǎng)絡(luò)的最后一層,而不是平均損失函數(shù)(avg_cost),因?yàn)槲覀兪窍胍A(yù)測(cè)程序輸出預(yù)測(cè)結(jié)果。根據(jù)我們上面定義數(shù)據(jù)時(shí),滿足規(guī)律y = 2 * x + 1,所以當(dāng)x為6時(shí),y應(yīng)該時(shí)13,最后輸出的結(jié)果也是應(yīng)該接近13的。
# 開始預(yù)測(cè) result = exe.run(program=test_program,feed={'x': test_data, 'y': np.array([[0.0]]).astype('float32')},fetch_list=[net]) print("當(dāng)x為6.0時(shí),y為:%0.5f" % result[0][0][0])預(yù)測(cè)結(jié)果:當(dāng)x為6.0時(shí),y為:13.23625
總結(jié)
以上是生活随笔為你收集整理的新手第四课-PaddlePaddle快速入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新手第一课-什么是深度学习
- 下一篇: Day01-图像处理原理与深度学习入门