paddlepaddle環(huán)境搭建及簡(jiǎn)單使用

1.paddlepaddle平臺(tái)簡(jiǎn)介

PaddlePaddle (PArallel Distributed Deep LEarning)是一個(gè)易用、高效、靈活、可擴(kuò)展的深度學(xué)習(xí)框架。其特點(diǎn)如下:
-同時(shí)支持動(dòng)態(tài)圖和靜態(tài)圖,兼顧靈活性和高性能
-源于實(shí)際業(yè)務(wù)淬煉,提供應(yīng)用效果領(lǐng)先的官方模型
-源于產(chǎn)業(yè)實(shí)踐,輸出業(yè)界領(lǐng)先的超大規(guī)模并行深度學(xué)習(xí)平臺(tái)能力

2.環(huán)境搭建

1.選擇macOS下安裝

image.png

2.檢查環(huán)境
查看MacOS版本
mac系統(tǒng)詳情.png

根據(jù)Python版本安裝pip3

python3 -m ensurepip
python3 -m pip --version

pip3安裝完成.png

安裝paddlepaddle

python3 -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
安裝截圖.png

驗(yàn)證安裝
安裝完成后您可以使用 python 或 python3 進(jìn)入python解釋器,輸入import paddle.fluid as fluid ,再輸入 fluid.install_check.run_check()

安裝成功.png

3.基本術(shù)語(yǔ)及使用

數(shù)據(jù)的表示和定義
Paddle和其他主流框架一樣,使用Tensor數(shù)據(jù)結(jié)構(gòu)來承載數(shù)據(jù),包括模型中的可學(xué)習(xí)參數(shù)(如網(wǎng)絡(luò)權(quán)重、偏置等), 網(wǎng)絡(luò)中每一層的輸入輸出數(shù)據(jù),常量數(shù)據(jù)等。
Tensor可以簡(jiǎn)單理解成一個(gè)多維數(shù)組,一般而言可以有任意多的維度。 不同的Tensor可以具有自己的數(shù)據(jù)類型和形狀,同一Tensor中每個(gè)元素的數(shù)據(jù)類型是一樣的, Tensor的形狀就是Tensor的維度。關(guān)于Tensor的詳細(xì)介紹請(qǐng)參閱:Tensor 。
在Paddle中我們使用 fluid.data 來創(chuàng)建數(shù)據(jù)變量, fluid.data 需要指定Tensor的形狀信息和數(shù)據(jù)類型, 當(dāng)遇到無(wú)法確定的維度時(shí),可以將相應(yīng)維度指定為None,如下面的代碼片段所示:

import paddle.fluid as fluid

# 定義一個(gè)數(shù)據(jù)類型為int64的二維數(shù)據(jù)變量x,x第一維的維度為3,第二個(gè)維度未知,要在程序執(zhí)行過程中才能確定,因此x的形狀可以指定為[3, None]
x = fluid.data(name="x", shape=[3, None], dtype="int64")

# 大多數(shù)網(wǎng)絡(luò)都會(huì)采用batch方式進(jìn)行數(shù)據(jù)組織,batch大小在定義時(shí)不確定,因此batch所在維度(通常是第一維)可以指定為None
batched_x = fluid.data(name="batched_x", shape=[None, 3, None], dtype='int64')

fluid.data 之外,我們還可以使用 fluid.layers.fill_constant 來創(chuàng)建常量, 如下代碼將創(chuàng)建一個(gè)維度為[3, 4], 數(shù)據(jù)類型為int64的Tensor,其中所有元素均為16(value參數(shù)所指定的值)。

import paddle.fluid as fluid
data = fluid.layers.fill_constant(shape=[3, 4], value=16, dtype='int64')

以上例子中,我們只使用了一種數(shù)據(jù)類型"int64",即有符號(hào)64位整數(shù)數(shù)據(jù)類型,更多Paddle目前支持的數(shù)據(jù)類型請(qǐng)查看:支持的數(shù)據(jù)類型

需要注意的是,在靜態(tài)圖編程方式中,上述定義的Tensor并不具有值(即使創(chuàng)建常量的時(shí)候指定了value), 它們僅表示將要執(zhí)行的操作,在網(wǎng)絡(luò)執(zhí)行時(shí)(訓(xùn)練或者預(yù)測(cè))才會(huì)進(jìn)行真正的賦值操作, 如您直接打印上例代碼中的data將會(huì)得對(duì)其信息的描述:

print data

輸出結(jié)果:

name: "fill_constant_0.tmp_0"
type {
    type: LOD_TENSOR
    lod_tensor {
        tensor {
            data_type: INT64
            dims: 3
            dims: 4
        }
    }
}
persistable: false

在網(wǎng)絡(luò)執(zhí)行過程中,獲取Tensor數(shù)值有兩種方式:方式一是利用 paddle.fluid.layers.Print 創(chuàng)建一個(gè)打印操作, 打印正在訪問的Tensor。方式二是將Variable添加在fetch_list中。

方式一的代碼實(shí)現(xiàn)如下所示:


data = fluid.layers.fill_constant(shape=[3, 4], value=16, dtype='int64')
data = fluid.layers.Print(data, message="Print data:")

place = fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())

ret = exe.run()

運(yùn)行時(shí)的輸出結(jié)果:

1571742368    Print data:    The place is:CPUPlace
Tensor[fill_constant_0.tmp_0]
    shape: [3,4,]
    dtype: x
    data: 16,16,16,16,16,16,16,16,16,16,16,16,

數(shù)據(jù)讀取
使用 fluid.data 創(chuàng)建數(shù)據(jù)變量之后,我們需要把網(wǎng)絡(luò)執(zhí)行所需要的數(shù)據(jù)讀取到對(duì)應(yīng)變量中, 具體的數(shù)據(jù)準(zhǔn)備過程,請(qǐng)閱讀準(zhǔn)備數(shù)據(jù)
組建網(wǎng)絡(luò)
在Paddle中,數(shù)據(jù)計(jì)算類API統(tǒng)一稱為Operator(算子),簡(jiǎn)稱OP,大多數(shù)OP在 paddle.fluid.layers 模塊中提供。
例如用戶可以利用 paddle.fluid.layers.elementwise_add() 實(shí)現(xiàn)兩個(gè)輸入Tensor的加法運(yùn)算:

# 定義變量
import paddle.fluid as fluid
a = fluid.data(name="a", shape=[None, 1], dtype='int64')
b = fluid.data(name="b", shape=[None, 1], dtype='int64')

# 組建網(wǎng)絡(luò)(此處網(wǎng)絡(luò)僅由一個(gè)操作構(gòu)成,即elementwise_add)
result = fluid.layers.elementwise_add(a,b)

# 準(zhǔn)備運(yùn)行網(wǎng)絡(luò)
cpu = fluid.CPUPlace() # 定義運(yùn)算設(shè)備,這里選擇在CPU下訓(xùn)練
exe = fluid.Executor(cpu) # 創(chuàng)建執(zhí)行器
exe.run(fluid.default_startup_program()) # 網(wǎng)絡(luò)參數(shù)初始化

# 讀取輸入數(shù)據(jù)
import numpy
data_1 = int(input("Please enter an integer: a="))
data_2 = int(input("Please enter an integer: b="))
x = numpy.array([[data_1]])
y = numpy.array([[data_2]])

# 運(yùn)行網(wǎng)絡(luò)
outs = exe.run(
    feed={'a':x, 'b':y}, # 將輸入數(shù)據(jù)x, y分別賦值給變量a,b
    fetch_list=[result] # 通過fetch_list參數(shù)指定需要獲取的變量結(jié)果
    )

# 輸出計(jì)算結(jié)果
print "%d+%d=%d" % (data_1,data_2,outs[0][0])

輸出結(jié)果:

Please enter an integer: a=7
Please enter an integer: b=3
7+3=10

組建更加復(fù)雜的網(wǎng)絡(luò)
某些場(chǎng)景下,用戶需要根據(jù)當(dāng)前網(wǎng)絡(luò)中的某些狀態(tài),來具體決定后續(xù)使用哪一種操作,或者重復(fù)執(zhí)行某些操作。在動(dòng)態(tài)圖中,可以方便的使用Python的控制流語(yǔ)句(如for,if-else等)來進(jìn)行條件判斷,但是在靜態(tài)圖中,由于組網(wǎng)階段并沒有實(shí)際執(zhí)行操作,也沒有產(chǎn)生中間計(jì)算結(jié)果,因此無(wú)法使用Python的控制流語(yǔ)句來進(jìn)行條件判斷,為此靜態(tài)圖提供了多個(gè)控制流API來實(shí)現(xiàn)條件判斷。這里以fluid.layers.while_loop為例來說明如何在靜態(tài)圖中實(shí)現(xiàn)條件循環(huán)的操作。
while_loop API用于實(shí)現(xiàn)類似while/for的循環(huán)控制功能,使用一個(gè)callable的方法cond作為參數(shù)來表示循環(huán)的條件,只要cond的返回值為True,while_loop就會(huì)循環(huán)執(zhí)行循環(huán)體body(也是一個(gè)callable的方法),直到 cond 的返回值為False。對(duì)于while_loop API的詳細(xì)定義和具體說明請(qǐng)參考文檔fluid.layers.while_loop。
下面的例子中,使用while_loop API進(jìn)行條件循環(huán)操作,其實(shí)現(xiàn)的功能相當(dāng)于在python中實(shí)現(xiàn)如下代碼:

i = 0
ten = 10
while i < ten:
    i = i + 1
print('i =', i)

在靜態(tài)圖中使用while_loop API實(shí)現(xiàn)以上代碼的邏輯:

# 該代碼要求安裝飛槳1.7+版本

# 該示例代碼展示整數(shù)循環(huán)+1,循環(huán)10次,輸出計(jì)數(shù)結(jié)果
import paddle.fluid as fluid
import paddle.fluid.layers as layers

# 定義cond方法,作為while_loop的判斷條件
def cond(i, ten):
    return i < ten 

# 定義body方法,作為while_loop的執(zhí)行體,只要cond返回值為True,while_loop就會(huì)一直調(diào)用該方法進(jìn)行計(jì)算
# 由于在使用while_loop OP時(shí),cond和body的參數(shù)都是由while_loop的loop_vars參數(shù)指定的,所以cond和body必須有相同數(shù)量的參數(shù)列表,因此body中雖然只需要i這個(gè)參數(shù),但是仍然要保持參數(shù)列表個(gè)數(shù)為2,此處添加了一個(gè)dummy參數(shù)來進(jìn)行"占位"
def body(i, dummy):
    # 計(jì)算過程是對(duì)輸入?yún)?shù)i進(jìn)行自增操作,即 i = i + 1
    i = i + 1
    return i, dummy

i = layers.fill_constant(shape=[1], dtype='int64', value=0) # 循環(huán)計(jì)數(shù)器
ten = layers.fill_constant(shape=[1], dtype='int64', value=10) # 循環(huán)次數(shù)
out, ten = layers.while_loop(cond=cond, body=body, loop_vars=[i, ten]) # while_loop的返回值是一個(gè)tensor列表,其長(zhǎng)度,結(jié)構(gòu),類型與loop_vars相同

exe = fluid.Executor(fluid.CPUPlace())
res = exe.run(fluid.default_main_program(), feed={}, fetch_list=out)
print(res) #[array([10])]

一個(gè)完整的網(wǎng)絡(luò)示例
一個(gè)典型的模型通常包含4個(gè)部分,分別是:輸入數(shù)據(jù)定義,搭建網(wǎng)絡(luò)(模型前向計(jì)算邏輯),定義損失函數(shù),以及選擇優(yōu)化算法。

下面我們通過一個(gè)非常簡(jiǎn)單的數(shù)據(jù)預(yù)測(cè)網(wǎng)絡(luò)(線性回歸),來完整的展示如何使用Paddle靜態(tài)圖方式完成一個(gè)深度學(xué)習(xí)模型的組建和訓(xùn)練。

問題描述:給定一組數(shù)據(jù) <X,Y>,求解出函數(shù) f,使得 y=f(x),其中X,Y均為一維張量。最終網(wǎng)絡(luò)可以依據(jù)輸入x,準(zhǔn)確預(yù)測(cè)出ypredict。

1.定義數(shù)據(jù)
假設(shè)輸入數(shù)據(jù)X=[1 2 3 4],Y=[2 4 6 8],在網(wǎng)絡(luò)中定義:

# 定義X數(shù)值
train_data=numpy.array([[1.0], [2.0], [3.0], [4.0]]).astype('float32')
# 定義期望預(yù)測(cè)的真實(shí)值y_true
y_true = numpy.array([[2.0], [4.0], [6.0], [8.0]]).astype('float32')

2.搭建網(wǎng)絡(luò)(定義前向計(jì)算邏輯)

接下來需要定義預(yù)測(cè)值與輸入的關(guān)系,本次使用一個(gè)簡(jiǎn)單的線性回歸函數(shù)進(jìn)行預(yù)測(cè):

# 定義輸入數(shù)據(jù)類型
x = fluid.data(name="x", shape=[None, 1], dtype='float32')
y = fluid.data(name="y", shape=[None, 1], dtype='float32')
# 搭建全連接網(wǎng)絡(luò)
y_predict = fluid.layers.fc(input=x, size=1, act=None)

3.添加損失函數(shù)

完成模型搭建后,如何評(píng)估預(yù)測(cè)結(jié)果的好壞呢?我們通常在設(shè)計(jì)的網(wǎng)絡(luò)中添加損失函數(shù),以計(jì)算真實(shí)值與預(yù)測(cè)值的差。

在本例中,損失函數(shù)采用均方差函數(shù)

cost = fluid.layers.square_error_cost(input=y_predict, label=y)
avg_cost = fluid.layers.mean(cost)

4.網(wǎng)絡(luò)優(yōu)化

確定損失函數(shù)后,可以通過前向計(jì)算得到損失值,并根據(jù)損失值對(duì)網(wǎng)絡(luò)參數(shù)進(jìn)行更新,最簡(jiǎn)單的算法是隨機(jī)梯度下降法:w=w?η?g,由 fluid.optimizer.SGD 實(shí)現(xiàn):

sgd_optimizer = fluid.optimizer.SGD(learning_rate=0.01)
sgd_optimizer.minimize(avg_cost)

讓我們的網(wǎng)絡(luò)訓(xùn)練100次,查看結(jié)果:

# 加載庫(kù)
import paddle.fluid as fluid
import numpy

# 定義輸入數(shù)據(jù)
train_data=numpy.array([[1.0],[2.0],[3.0],[4.0]]).astype('float32')
y_true = numpy.array([[2.0],[4.0],[6.0],[8.0]]).astype('float32')

# 組建網(wǎng)絡(luò)
x = fluid.data(name="x",shape=[None, 1],dtype='float32')
y = fluid.data(name="y",shape=[None, 1],dtype='float32')
y_predict = fluid.layers.fc(input=x,size=1,act=None)

# 定義損失函數(shù)
cost = fluid.layers.square_error_cost(input=y_predict,label=y)
avg_cost = fluid.layers.mean(cost)

# 選擇優(yōu)化方法
sgd_optimizer = fluid.optimizer.SGD(learning_rate=0.01)
sgd_optimizer.minimize(avg_cost)

# 網(wǎng)絡(luò)參數(shù)初始化
cpu = fluid.CPUPlace()
exe = fluid.Executor(cpu)
exe.run(fluid.default_startup_program())

# 開始訓(xùn)練,迭代100次
for i in range(100):
    outs = exe.run(
        feed={'x':train_data, 'y':y_true},
        fetch_list=[y_predict, avg_cost])

# 輸出訓(xùn)練結(jié)果
print outs

輸出結(jié)果:

[array([[2.2075021],
        [4.1005487],
        [5.9935956],
        [7.8866425]], dtype=float32), array([0.01651453], dtype=float32)]

運(yùn)行結(jié)果與期望一致:


訓(xùn)練100次結(jié)果.png

讓我們的網(wǎng)絡(luò)訓(xùn)練1000次,輸出結(jié)果:


訓(xùn)練1000次結(jié)果

讓我們的網(wǎng)絡(luò)訓(xùn)練10000次,輸出結(jié)果:
訓(xùn)練10000次結(jié)果.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容