在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 用卷積神經(jīng)網(wǎng)絡檢測臉部關鍵點的教程(一)

            用卷積神經(jīng)網(wǎng)絡檢測臉部關鍵點的教程(一)

            作者: 時間:2017-10-11 來源:網(wǎng)絡 收藏

            這是一個手把手教你學習深度學校的教程。一步一步,我們將要嘗試去解決Kaggle challenge中的臉部關鍵點的檢測問題。

            本文引用地址:http://www.biyoush.com/article/201710/365583.htm

            這份教程介紹了Lasagne,一個比較新的基于Python和Theano的神經(jīng)網(wǎng)絡庫。我們將用Lasagne去模擬一系列的神經(jīng)網(wǎng)絡結(jié)構(gòu),討論一下數(shù)據(jù)增強(data augmentaTIon)、流失(dropout)、結(jié)合動量(momentum)和預先訓練(pre-training)。這里有很多方法可以將我們的結(jié)果改善不少。

            我假設諸位已經(jīng)知道了一些關于神經(jīng)網(wǎng)絡的只是。所以我們就不介紹神經(jīng)網(wǎng)絡的背景知識了。這里也提供一些好的介紹神經(jīng)網(wǎng)絡的書籍和視頻,如Neural Networks and Deep Learning online book。Alec Radford的演講Deep Learning with Python’s Theano library也是一個快速介紹的好例子。以及ConvNetJS Browser Demos

            預先準備

            如果你只需要看懂的話,則不需要自己寫一個代碼然后去執(zhí)行。這里提供一些安裝的教程給那些配置好CUDA的并且想要運行試驗的那些人。

            我假設你們已經(jīng)安裝了CUDA toolkit, Python 2.7.x, numpy, pandas, matplotlib, 和scikit-learn。安裝剩下的依賴包,比如Lasagne和Theano都可以運行下面的指令
            pip install -r https://raw.githubusercontent.com/dnouri/kfkd-tutorial/master/requiremen...

            注意,為了簡潔起見,我沒有在命令中創(chuàng)建虛擬環(huán)境,但是你需要的。

            譯者:我是在windows10上面配置這個環(huán)境的,安裝anaconda(再用此環(huán)境安裝依賴包)、VS2013(不推薦2015)、CUDA工具即可。

            如果一切都順利的話,你將會在你的虛擬環(huán)境下的src/lasagne/examples/目錄中找到mnist.py并運行MNIST例子。這是一個對于神經(jīng)網(wǎng)絡的“Hello world”程序。數(shù)據(jù)中有十個分類,分別是0~9的數(shù)字,輸入時28&TImes;28的手寫數(shù)字圖片。

            cd src/lasagne/examples/
            python mnist.py

            此命令將在三十秒左右后開始打印輸出。 這需要一段時間的原因是,Lasagne使用Theano做重型起重; Theano反過來是一個“優(yōu)化元編程代碼生成面向數(shù)組的優(yōu)化Python數(shù)學編譯器”,它將生成需要在訓練發(fā)生前編譯的C代碼。 幸運的是,我們組需要在第一次運行時支付這個開銷的價格。

            譯者:如果沒有配置,用的是的話,應該是不用這么久的編譯時間,但是執(zhí)行時間有一些長。如果用GPU,在第一次跑一些程序的時候,會有提示正在編譯的內(nèi)容。

            當訓練開始的時候,你會看到
            Epoch 1 of 500
            training loss: 1.352731
            validaTIon loss: 0.466565
            validaTIon accuracy: 87.70 %
            Epoch 2 of 500
            training loss: 0.591704
            validation loss: 0.326680
            validation accuracy: 90.64 %
            Epoch 3 of 500
            training loss: 0.464022
            validation loss: 0.275699
            validation accuracy: 91.98 %

            如果你讓訓練運行足夠長,你會注意到,在大約75代之后,它將達到大約98%的測試精度。

            如果你用的是GPU,你想要讓Theano去使用它,你要在用戶的主文件夾下面創(chuàng)建一個.theanorc文件。你需要根據(jù)自己安裝環(huán)境以及自己操作系統(tǒng)的配置使用不同的配置信息:
            [global]
            floatX = float32
            device = gpu0

            [lib]
            cnmem = 1

            譯者:這是我的配置文件。

            [cuba]
            root = C:Program FilesNVIDIA GPU Computing ToolkitCUDAv8.0
            [global]
            openmp = False
            device = gpu
            floatX = float32
            allow_input_downcast = True

            [nvcc]
            fastmath = True
            flags = -IC:Anaconda2libs
            compiler_bindir = C:Program Files (x86)Microsoft Visual Studio 12.0VCbin
            base_compiledir = path_to_a_directory_without_such_characters

            [blas]
            ldflags =

            [gcc]
            cxxflags = -IC:Anaconda2MinGW

            數(shù)據(jù)

            面部關鍵點檢測的訓練數(shù)據(jù)集包括7049(96x96)個灰度圖像。 對于每個圖像,我們應該學習找到15個關鍵點的正確位置(x和y坐標),例如
            left_eye_center
            right_eye_outer_corner
            mouth_center_bottom_lip

            一個臉部標記出三個關鍵點的例子。

            數(shù)據(jù)集的一個有趣的變化是,對于一些關鍵點,我們只有大約2,000個標簽,而其他關鍵點有7,000多個標簽可用于訓練。

            讓我們編寫一些Python代碼,從所提供的CSV文件加載數(shù)據(jù)。 我們將編寫一個可以加載訓練和測試數(shù)據(jù)的函數(shù)。 這兩個數(shù)據(jù)集的區(qū)別在于測試數(shù)據(jù)不包含目標值; 這是預測這些問題的目標。 這里是我們的load()函數(shù):
            # file kfkd.py
            import os

            import numpy as np
            from pandas.io.parsers import read_csv
            from sklearn.utils import shuffle

            FTRAIN = ~/data/kaggle-facial-keypoint-detection/training.csv
            FTEST = ~/data/kaggle-facial-keypoint-detection/test.csv

            def load(test=False, cols=None):
            Loads data from FTEST if *test* is True, otherwise from FTRAIN.
            Pass a list of *cols* if youre only interested in a subset of the
            target columns.

            fname = FTEST if test else FTRAIN
            df = read_csv(os.path.expanduser(fname)) # load pandas dataframe

            # The Image column has pixel values separated by space; convert
            # the values to numpy arrays:
            df[Image] = df[Image].apply(lambda im: np.fromstring(im, sep= ))

            if cols: # get a subset of columns
            df = df[list(cols) + [Image]]

            print(df.count()) # prints the number of values for each column
            df = df.dropna() # drop all rows that have missing values in them

            X = np.vstack(df[Image].values) / 255. # scale pixel values to [0, 1]
            X = X.astype(np.float32)

            if not test: # only FTRAIN has any target columns
            y = df[df.columns[:-1]].values
            y = (y - 48) / 48 # scale target coordinates to [-1, 1]
            X, y = shuffle(X, y, random_state=42) # shuffle train data
            y = y.astype(np.float32)
            else:
            y = None

            return X, y

            X, y = load()
            print(X.shape == {}; X.min == {:.3f}; X.max == {:.3f}.format(
            X.shape, X.min(), X.max()))
            print(y.shape == {}; y.min == {:.3f}; y.max == {:.3f}.format(
            y.shape, y.min(), y.max()))

            你沒有必要看懂這個函數(shù)的每一個細節(jié)。 但讓我們看看上面的腳本輸出:
            $ python kfkd.py
            left_eye_center_x 7034
            left_eye_center_y 7034
            right_eye_center_x 7032
            right_eye_center_y 7032
            left_eye_inner_corner_x 2266
            left_eye_inner_corner_y 2266
            left_eye_outer_corner_x 2263
            left_eye_outer_corner_y 2263
            right_eye_inner_corner_x 2264
            right_eye_inner_corner_y 2264

            mouth_right_corner_x 2267
            mouth_right_corner_y 2267
            mouth_center_top_lip_x 2272
            mouth_center_top_lip_y 2272
            mouth_center_bottom_lip_x 7014
            mouth_center_bottom_lip_y 7014
            Image 7044
            dtype: int64
            X.shape == (2140, 9216); X.min == 0.000; X.max == 1.000
            y.shape == (2140, 30); y.min == -0.920; y.max == 0.996

            首先,它打印出了CSV文件中所有列的列表以及每個列的可用值的數(shù)量。 因此,雖然我們有一個圖像的訓練數(shù)據(jù)中的所有行,我們對于mouth_right_corner_x只有個2,267的值等等。

            load()返回一個元組(X,y),其中y是目標矩陣。 y的形狀是n×m的,其中n是具有所有m個關鍵點的數(shù)據(jù)集中的樣本數(shù)。 刪除具有缺失值的所有行是這行代碼的功能:
            df = df.dropna() # drop all rows that have missing values in them

            這個腳本輸出的y.shape == (2140, 30)告訴我們,在數(shù)據(jù)集中只有2140個圖像有著所有30個目標值。

            一開始,我們將僅訓練這2140個樣本。 這使得我們比樣本具有更多的輸入大?。?,216); 過度擬合可能成為一個問題。當然,拋棄70%的訓練數(shù)據(jù)也是一個壞主意。但是目前就這樣,我們將在后面談論。

            第一個模型:一個單隱層

            現(xiàn)在我們已經(jīng)完成了加載數(shù)據(jù)的工作,讓我們使用Lasagne并創(chuàng)建一個帶有一個隱藏層的神經(jīng)網(wǎng)絡。 我們將從代碼開始:
            # add to kfkd.py
            from lasagne import layers
            from lasagne.updates import nesterov_momentum
            from nolearn.lasagne import NeuralNet

            net1 = NeuralNet(
            layers=[ # three layers: one hidden layer
            (input, layers.InputLayer),
            (hidden, layers.DenseLayer),
            (output, layers.DenseLayer),
            ],
            # layer parameters:
            input_shape=(None, 9216), # 96x96 input pixels per batch
            hidden_num_units=100, # number of units in hidden layer
            output_nonlinearity=None, # output layer uses identity function
            output_num_units=30, # 30 target values

            # optimization method:
            update=nesterov_momentum,
            update_learning_rate=0.01,
            update_momentum=0.9,

            regression=True, # flag to indicate were dealing with regression problem
            max_epochs=400, # we want to train this many epochs
            verbose=1,
            )

            X, y = load()
            net1.fit(X, y)

            我們使用相當多的參數(shù)來初始化NeuralNet。讓我們看看他們。首先是三層及其參數(shù):
            layers=[ # 三層神經(jīng)網(wǎng)絡:一個隱層
            (input, layers.InputLayer),
            (hidden, layers.DenseLayer),
            (output, layers.DenseLayer),
            ],
            # 層的參數(shù):
            input_shape=(None, 9216), # 每個批次96x96個輸入樣例
            hidden_num_units=100, # 隱層中的單元數(shù)
            output_nonlinearity=None, # 輸出用的激活函數(shù)
            output_num_units=30, # 30個目標值

            這里我們定義輸入層,隱藏層和輸出層。在層參數(shù)中,我們命名并指定每個層的類型及其順序。參數(shù)input_shape,hidden_??num_units,output_nonlinearity和output_num_units是特定層的參數(shù)。它們通過它們的前綴引用層,使得input_shape定義輸入層的shape參數(shù),hidden_??num_units定義隱藏層的num_units等等。(看起來有點奇怪,我們必須指定像這樣的參數(shù),但結(jié)果是它讓我們對于受使用scikit-learn的管道和參數(shù)搜索功能擁有更好的兼容性。)

            我們將input_shape的第一個維度設置為None。這轉(zhuǎn)換為可變批量大小。如果你知道批量大小的話,也可以設置成固定值,如果為None,則是可變值。

            我們將output_nonlinearity設置為None。因此,輸出單元的激活僅僅是隱藏層中的激活的線性組合。

            DenseLayer使用的默認非線性是rectifier,它其實就是返回max(0, x)。它是當今最受歡迎的激活功能選擇。通過不明確設置hidden_??nonlinearity,我們選擇rectifier作為我們隱藏層的激活函數(shù)。

            神經(jīng)網(wǎng)絡的權重用具有巧妙選擇的間隔的均勻分布來初始化。也就是說,Lasagne使用“Glorot-style”初始化來計算出這個間隔。

            還有幾個參數(shù)。 所有以update開頭的參數(shù)用來表示更新方程(或最優(yōu)化方法)的參數(shù)。 更新方程將在每個批次后更新我們網(wǎng)絡的權重。 我們將使用涅斯捷羅夫動量梯度下降優(yōu)化方法(nesterov_momentum gradient descent optimization method)來完成這項工作。Lasagne實現(xiàn)的其他方法有很多,如adagrad和rmsprop。我們選擇nesterov_momentum,因為它已經(jīng)證明對于大量的問題很好地工作。
            ”’ optimization method: ””
            update=nesterov_momentum,
            update_learning_rate=0.01,
            update_momentum=0.9,

            update_learning_rate定義了梯度下降更新權重的步長。我們稍后討論學習率和momentum參數(shù),現(xiàn)在的話,這種健全的默認值已經(jīng)足夠了。

            上圖是不同的最優(yōu)化方法的對比(animation by?Alec Radford)。星標位置為全局最優(yōu)值。注意到不添加動量的隨機梯度下降是收斂最慢的,我們在教程中從頭到尾都是用Nesterov加速過的梯度下降。

            在我們的NeuralNet的定義中,我們沒有指定一個目標函數(shù)來實現(xiàn)最小化。這里使用的還有一個默認值:對于回歸問題,它是均方誤差(MSE)。

            最后一組參數(shù)聲明我們正在處理一個回歸問題(而不是分類),400是我們愿意訓練的時期數(shù),并且我們想在訓練期間通過設置verbose = 1:
            regression=True, # flag to indicate were dealing with regression problem
            max_epochs=400, # we want to train this many epochs
            verbose=1,

            最后兩行加載了數(shù)據(jù),然后用數(shù)據(jù)訓練了我們的第一個神經(jīng)網(wǎng)絡。
            X, y = load()
            net1.fit(X, y)

            運行這兩行會輸出一個表格,每次完成一代就輸出一行。每一行里,我們可以看到當前的訓練損失和驗證損失(最小二乘損失),以及兩者的比率。NeuroNet將會自動把輸入數(shù)據(jù)X分成訓練集和測試集,用20%的數(shù)據(jù)作驗證。(比率可以通過參數(shù)eval_size=0.2調(diào)整)
            $ python kfkd.py
            ...
            InputLayer (None, 9216) produces 9216 outputs
            DenseLayer (None, 100) produces 100 outputs
            DenseLayer (None, 30) produces 30 outputs

            Epoch | Train loss | Valid loss | Train / Val
            --------|--------------|--------------|----------------
            1 | 0.105418 | 0.031085 | 3.391261
            2 | 0.020353 | 0.019294 | 1.054894
            3 | 0.016118 | 0.016918 | 0.952734
            4 | 0.014187 | 0.015550 | 0.912363
            5 | 0.013329 | 0.014791 | 0.901199
            ...
            200 | 0.003250 | 0.004150 | 0.783282
            201 | 0.003242 | 0.004141 | 0.782850
            202 | 0.003234 | 0.004133 | 0.782305
            203 | 0.003225 | 0.004126 | 0.781746
            204 | 0.003217 | 0.004118 | 0.781239
            205 | 0.003209 | 0.004110 | 0.780738
            ...
            395 | 0.002259 | 0.003269 | 0.690925
            396 | 0.002256 | 0.003264 | 0.691164
            397 | 0.002254 | 0.003264 | 0.690485
            398 | 0.002249 | 0.003259 | 0.690303
            399 | 0.002247 | 0.003260 | 0.689252
            400 | 0.002244 | 0.003255 | 0.689606

            在相對較快的GPU上訓練,我們能夠在1分鐘之內(nèi)完成400個epoch的訓練。注意測試損失會一直減小。(如果你訓練得足夠長時間,它將會有很小很小的改進)

            現(xiàn)在我們有了一個很好的結(jié)果了么?我們看到測試誤差是0.0032,和競賽基準比試一下。記住我們將目標除以了48以將其縮放到-1到1之間,也就是說,要是想計算均方誤差和排行榜的結(jié)果比較,必須把我們上面得到的0.003255還原到原來的尺度。
            >>> import numpy as np
            >>> np.sqrt(0.003255) * 48
            2.7385251505144153

            這個值應該可以代表我們的成績了。當然,這得假設測試集合的數(shù)據(jù)和訓練集合的數(shù)據(jù)符合相同的分布,但事實卻并非如此。

            測試網(wǎng)絡

            我們剛剛訓練的net1對象已經(jīng)保存了訓練時打印在控制臺桌面中的記錄,我們可以獲取這個記錄通過train_history_相關屬性,讓我們畫出這兩個曲線。
            train_loss = np.array([i[train_loss] for i in net1.train_history_])
            valid_loss = np.array([i[valid_loss] for i in net1.train_history_])
            pyplot.plot(train_loss, linewidth=3, label=train)
            pyplot.plot(valid_loss, linewidth=3, label=valid)
            pyplot.grid()
            pyplot.legend()
            pyplot.xlabel(epoch)
            pyplot.ylabel(loss)
            pyplot.ylim(1e-3, 1e-2)
            pyplot.yscale(log)
            pyplot.show()

            我們能夠看到我們的網(wǎng)絡過擬合了,但是結(jié)果還不錯。事實上,我們找不到驗證錯誤開始上升的點,所以那種通常用來避免過擬合的early stopping方法在現(xiàn)在還沒有什么用處。注意我們沒有采用任何正則化手段,除了選擇節(jié)點比較少的隱層——這可以讓過擬合保持在可控范圍內(nèi)。

            那么網(wǎng)絡的預測結(jié)果是什么樣的呢?讓我們選擇一些樣例來看一看。
            def plot_sample(x, y, axis):
            img = x.reshape(96, 96)
            axis.imshow(img, cmap=gray)
            axis.scatter(y[0::2] * 48 + 48, y[1::2] * 48 + 48, marker=x, s=10)

            X, _ = load(test=True)
            y_pred = net1.predict(X)

            fig = pyplot.figure(figsize=(6, 6))
            fig.subplots_adjust(
            left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)

            for i in range(16):
            ax = fig.add_subplot(4, 4, i + 1, xticks=[], yticks=[])
            plot_sample(X[i], y_pred[i], ax)

            pyplot.show()

            第一個模型預測的結(jié)果(從測試集抽出了16個樣例)
            預測結(jié)果看起來還不錯,但是有點時候還是有一點偏。讓我們試著做的更好一些。



            評論


            相關推薦

            技術專區(qū)

            關閉