使用GPU和Theano加速深度學習

2021-02-13 CSDN

摘要:Theano是主流的深度學習Python庫之一,亦支持GPU,然而Theano入門較難,Domino的這篇博文介紹了如何使用GPU和Theano加速深度學習,教程從多層感知器到卷積神經網絡,由淺入深,是不錯的入門資料。

【編者按】GPU因其浮點計算和矩陣運算能力有助於加速深度學習是業界的共識,Theano是主流的深度學習Python庫之一,亦支持GPU,然而Theano入門較難,Domino的這篇博文介紹了如何使用GPU和Theano加速深度學習,使用更簡單的基於Theano的 Nolearn庫。教程由多層感知器及卷積神經網絡,由淺入深,是不錯的入門資料。

基於Python的深度學習

實現神經網絡算法的Python庫中,最受歡迎的當屬Theano。然而,Theano並不是嚴格意義上的神經網絡庫,而是一個Python庫,它可以實現各種各樣的數學抽象。正因為如此,Theano有著陡峭的學習曲線,所以我將介紹基於Theano構建的有更平緩的學習曲線的兩個神經網絡庫。

第一個庫是 Lasagne。該庫提供了一個很好的抽象,它允許你構建神經網絡的每一層,然後堆疊在彼此的頂部來構建一個完整的模型。儘管這比Theano顯得更好,但是構建每一層,然後附加在彼此頂部會顯得有些冗長乏味,所以我們將使用 Nolearn庫,它在Lasagne庫上提供了一個類似 Scikit-Learn風格的API,能夠輕鬆地構建多層神經網絡。

延伸閱讀: 從Theano到Lasagne:基於Python的深度學習的框架和庫

由於這些庫默認使用的不是Domino硬體,所以你需要創建一個requirements.txt文件,該文件內容如下:

配置Theano

-e git://github.com/Theano/Theano.git#egg=Theano-e git://github.com/lasagne/lasagne.git#egg=lasagnenolearn==0.5.0  


現在,在我們導入Lasagne庫和Nolearn庫之前,首先我們需要配置Theano,使其可以使用GPU硬體。要做到這一點,我們需要在我們的工程目錄中新建一個.theanorc文件,該文件內容如下:

[global] device = gpu floatX = float32 [nvcc] fastmath = True

這個.theanorc文件必須放置在主目錄中。在你的本地計算機上,這個操作可以手工完成,但我們不能直接訪問Domino機器的主目錄,所以我們需要使用下面的代碼將文件移到它的主目錄中:

import os import shutil destfile = "/home/ubuntu/.theanorc" open(destfile,        'a').close() shutil.copyfile(".theanorc", destfile)

上面的代碼會在主目錄創建了一個空的.theanorc文件,然後複製我們項目目錄下的.theanorc文件內容到該文件中。

將硬體切換到GPU後,我們可以來做一下測試,使用Theano文檔中提供的測試代碼來看看Theano是否能夠檢測到GPU。

from theano import function, config, shared, sandbox  import theano.tensor as T  import numpy  import timevlen = 10 * 30 * 768  # 10 x #cores x # threads per core  iters = 1000rng = numpy.random.RandomState(22)  x = shared(numpy.asarray(rng.rand(vlen), config.floatX))  f = function([], T.exp(x))  print f.maker.fgraph.toposort()  t0 = time.time()  for i in xrange(iters):      r = f()t1 = time.time()  print 'Looping %d times took' % iters, t1 - t0, 'seconds'  print 'Result is', r  if numpy.any([isinstance(x.op, T.Elemwise) for x in f.maker.fgraph.toposort()]):      print 'Used the cpu'else:      print 'Used the gpu'

如果Theano檢測到GPU,上面的函數運行時間應該需要0.7秒,並且輸出「Used the gpu」。否則,整個過程將需要2.6秒的運行時間,同時輸出「Used the cpu」'。如果輸出的是後一個,那麼你肯定是忘記將硬體切換到GPU了。

數據集

對於這個項目,我們將使用CIFAR-10圖像數據集,它來自10個不同的類別,包含了60000個32x32大小的彩色圖像。

幸運的是,這些數據屬於 pickled格式,所以我們可以使用輔助函數來加載數據,將每個文件加載到NumPy數組中並返回訓練集(Xtr),訓練集標籤(Ytr),測試集(Xte)以及測試集標籤(Yte)。下列代碼歸功於 Stanford's CS231n課程的工作人員。

import cPickle as pickle  import numpy as np  import osdef load_CIFAR_file(filename):      '''Load a single file of CIFAR'''    with open(filename, 'rb') as f:        datadict= pickle.load(f)        X = datadict['data']        Y = datadict['labels']        X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype('float32')        Y = np.array(Y).astype('int32')        return X, Ydef load_CIFAR10(directory):      '''Load all of CIFAR'''    xs = []    ys = []    for k in range(1,6):        f = os.path.join(directory, "data_batch_%d" % k)        X, Y = load_CIFAR_file(f)        xs.append(X)        ys.append(Y)    Xtr = np.concatenate(xs)    Ytr = np.concatenate(ys)    Xte, Yte = load_CIFAR_file(os.path.join(directory, 'test_batch'))    return Xtr, Ytr, Xte, Yte

多層感知器

多層感知器是一種最簡單的神經網絡模型。該模型包括一個輸入層數據,一個施加一些數學變換的隱藏層,以及一個輸出層用來產生一個標籤(不管是分類還是回歸,都一樣)。

圖片來源:http://dms.irb.hr/tutorial/tut_nnets_short.php

在我們使用訓練數據之前,我們需要把它的灰度化,把它變成一個二維矩陣。此外,我們將每個值除以255然後減去0.5。當我們對圖像進行灰度化時,我們將每一個(R,G,B)元組轉換成0到255之間的浮點值)。通過除以255,可以標準化灰度值映射到[0,1]之間。接下來,我們將所有的值減去0.5,映射到區間[ -0.5,0.5 ]上。現在,每個圖像都由一個1024維的數組表示,每一個值都在- 0.5到0.5之間。在訓練分類網絡時,標準化你的輸入值在[-1,1]之間是個很常見的做法。

X_train_flat = np.dot(X_train[...,:3], [0.299, 0.587, 0.114]).reshape(X_train.shape[0],-1).astype(np.float32)  X_train_flat = (X_train_flat/255.0)-0.5  X_test_flat = np.dot(X_test[...,:3], [0.299, 0.587, 0.114]).reshape(X_test.shape[0],-1).astype(np.float32)  X_test_flat = (X_test_flat/255.0)-.5  

使用nolearn的API,我們可以很容易地創建一個輸入層,隱藏層和輸出層的多層感知器。hidden_num_units = 100表示我們的隱藏層有100個神經元,output_num_units = 10則表示我們的輸出層有10個神經元,並與標籤一一對應。輸出前,網絡使用 softmax函數來確定最可能的標籤。迭代50次並且設置verbose=1來訓練模型,最後會輸出每次迭代的結果及其需要的運行時間。

net1 = NeuralNet( layers = [ ('input', layers.InputLayer), ('hidden',                layers.DenseLayer), ('output', layers.DenseLayer), ], #layers parameters:                input_shape = (None, 1024), hidden_num_units = 100, output_nonlinearity                = softmax, output_num_units = 10, #optimization parameters: update = nesterov_momentum,                update_learning_rate = 0.01, update_momentum = 0.9, regression = False,                max_epochs = 50, verbose = 1, )

從側面來說,這個接口使得它很容易建立深層網絡。如果我們想要添加第二個隱藏層,我們所需要做的就是把它添加到圖層參數中,然後在新增的一層中指定多少個神經元。

net1 = NeuralNet( layers = [ ('input', layers.InputLayer), ('hidden1',                    layers.DenseLayer), ('hidden2', layers.DenseLayer), #Added Layer Here ('output',                    layers.DenseLayer), ], #layers parameters: input_shape = (None, 1024),                    hidden1_num_units = 100, hidden2_num_units = 100, #Added Layer Params Here

現在,正如我前面提到的關於Nolearn類似Scikit-Learn風格的API,我們可以用fit函數來擬合神經網絡。

net1.fit(X_train_flat, y_train)  

當網絡使用GPU訓練時,我們可以看到每次迭代時間通常需要0.5秒。

另一方面,當Domino的硬體參數設置為XX-Large(32 core, 60 GB RAM),每次迭代時間通常需要1.3秒。


通過GPU訓練的神經網絡,我們可以看到在訓練網絡上大約提速了3倍。正如預期的那樣,使用GPU訓練好的神經網絡和使用CPU訓練好的神經網絡產生了類似的結果。兩者產生了相似的測試精度(約為41%)以及相似的訓練損失。

通過下面代碼,我們可以在測試數據上測試網絡:

y_pred1 = net1.predict(X_test_flat)  print "The accuracy of this network is: %0.2f" % (y_pred1 == y_test).mean() 

最後,我們在測試數據上得到的精度為41%。

卷積網絡

卷積神經網絡是一種更為複雜的神經網絡結構,它的一個層中的神經元和上一層的一個子集神經元相連。結果,卷積往往會池化每個子集的輸出。


圖片來源: http://colah.github.io/posts/2014-07-Conv-Nets-Modular/

卷積神經網絡在企業和 Kaggle 競賽中很受歡迎,因為它能靈活地學習不同的問題並且易擴展。

同樣,在我們建立卷積神經網絡之前,我們首先必須對數據進行灰度化和變換。這次我們會保持圖像32x32的大小不變。此外,我已經修改了矩陣的行順序,所以每個圖像現在被表示為(color,x,y)格式。跟之前一樣,我將特徵的每個值除以255,再減去0.5,最後將數值映射到區間(-1,1)。

X_train_2d = np.dot(X_train[...,:3], [0.299, 0.587, 0.114]).reshape(-1,1,32,32).astype(np.float32)  X_train_2d = (X_train_2d/255.0)-0.5  X_test_2d = np.dot(X_test[...,:3], [0.299, 0.587, 0.114]).reshape(-1,1,32,32).astype(np.float32)  X_train_2d = (X_train_2d/255.0)-0.5  

現在我們可以構造卷積神經網絡了。該網絡由輸入層,3個卷積層,3個2x2池化層,200個神經元隱藏層以及最後的輸出層構成。

net2 = NeuralNet(      layers = [        ('input', layers.InputLayer),        ('conv1', layers.Conv2DLayer),        ('pool1', layers.MaxPool2DLayer),        ('conv2', layers.Conv2DLayer),        ('pool2', layers.MaxPool2DLayer),        ('conv3', layers.Conv2DLayer),        ('pool3', layers.MaxPool2DLayer),        ("hidden4", layers.DenseLayer),        ("output", layers.DenseLayer),        ],        #layer parameters:        input_shape = (None, 1, 32, 32),        conv1_num_filters = 16, conv1_filter_size = (3, 3), pool1_pool_size = (2,2),        conv2_num_filters = 32, conv2_filter_size = (2, 2) , pool2_pool_size =  (2,2),        conv3_num_filters = 64, conv3_filter_size = (2, 2), pool3_pool_size = (2,2),        hidden4_num_units = 200,        output_nonlinearity = softmax,        output_num_units = 10,        #optimization parameters:        update = nesterov_momentum,        update_learning_rate = 0.015,        update_momentum = 0.9,        regression = False,        max_epochs = 5,        verbose = 1,        )

接著,我們再次使用fit函數來擬合模型。

net2.fit(X_train_2d, y_train)  

與多層感知器相比,卷積神經網絡的訓練時間會更長。使用GPU來訓練,大多數的迭代需要12.8s來完成,然而,卷積神經網絡驗證損失約為63%,超過了驗證損失為40%的多層感知器。也就是說,通過卷積層和池化層的結合,我們可以提高20%的精度。


在只有Domino的XX-大型硬體層的CPU上,每個訓練周期大概需要177秒完成,接近於3分鐘。也就是說,用GPU訓練,訓練時間提升了大約15倍。


和前面一樣,我們可以看到在CUP上訓練的卷積神經網絡與GPU上訓練的卷積神經網絡有著類似的結果,相似的驗證精度與訓練損失。

此外,當我們在測試數據上測試卷積神經網絡時,我們得到了61%的精度。

y_pred2 = net2.predict(X_test_2d)  print "The accuracy of this network is: %0.2f" % (y_pred2 == y_test).mean()  

建立卷積神經網絡的所有代碼都可以在ConvolutionNN.py這個 文件中找到。

最後,正如你所看到的,使用GPU訓練的深度神經網絡會加快運行加速,在這個項目中它提升的速度在3倍到15倍之間。無論是在工業界還是學術界,我們經常會使用多個GPU,因為這會大大減少深層網絡訓練的運行時間,通常能從幾周下降至幾天。

原文:Faster deep learning with GPUs and Theano(譯者/劉帝偉 審校/劉翔宇、朱正貴 責編/周建丁)

關於譯者:劉帝偉,中南大學軟體學院在讀研究生,關注機器學習、數據挖掘及生物信息領域。

本文為CSDN原創,點擊「閱讀原文」可查看原文並參與討論。

如果您喜歡這篇文章,請點擊右上角「…」將本文分享給你的朋友

相關焦點

  • 【經驗】深度學習如何挑選GPU?
    深度學習是一個對計算有著大量需求的領域,從一定程度上來說,GPU的選擇將從根本上決定深度學習的體驗。
  • 2020年深度學習如何挑選 GPU?這篇 GPU 最全攻略請查收
    深度學習是一個對計算有著大量需求的領域,從一定程度上來說,GPU的選擇將從根本上決定深度學習的體驗。
  • 2020 年深度學習如何挑選 GPU?這篇 GPU 最全攻略請查收
    的選擇將從根本上決定深度學習的體驗。> 16-bit capability > Tensor Cores > FLOPs2 如何選擇NVIDIA/AMD/GoogleNVIDIA的標準庫使在CUDA中建立第一個深度學習庫變得非常容易。
  • 2020年深度學習如何挑選GPU?這篇 GPU 最全攻略請查收
    關注 極市平臺 公眾號 ,回復 加群,立刻申請入群~深度學習是一個對計算有著大量需求的領域,從一定程度上來說,GPU的選擇將從根本上決定深度學習的體驗。因此,選擇購買合適的GPU是一項非常重要的決策。那麼2020年,如何選擇合適的GPU呢?
  • 從零開始:深度學習軟體環境安裝指南
    本文將向你解釋如何在一臺新裝的 Ubuntu 機器上安裝 Python 和 Nvidia 硬體驅動、各類庫和軟體包。為了進行強化學習研究,我最近購置了一臺基於 Ubuntu 和英偉達 GPU 的深度學習機器。儘管目前在網絡中能找到一些環境部署指南,但目前仍然沒有全面的安裝說明。
  • 居然有免費的GPU可以跑深度學習代碼!
    ,深度學習代碼需要設計海量的數據,需要很大很大很大(重要的事情說三遍)的計算量,以至於CPU算不過來,需要通過GPU幫忙,但這必不意味著CPU的性能沒GPU強,CPU是那種綜合性的,GPU是專門用來做圖像渲染的,這我們大家都知道,做圖像矩陣的計算GPU更加在行,應該我們一般把深度學習程序讓GPU來計算,事實也證明GPU的計算速度比CPU塊,但是(但是前面的話都是廢話
  • 深度學習中GPU和顯存分析
    這裡推薦一個好用的小工具:gpustat,直接pip install gpustat即可安裝,gpustat基於nvidia-smi,可以提供更美觀簡潔的展示,結合watch命令,可以動態實時監控GPU的使用情況。watch --color -n1 gpustat -cpu
  • 手把手教你安裝深度學習軟體環境(附代碼)
    本文向你解釋如何在一臺新裝的 Ubuntu 機器上安裝 Python 和 Nvidia 硬體驅動、各類庫和軟體包。為了進行強化學習研究,我最近購置了一臺基於 Ubuntu 和英偉達 GPU 的深度學習機器。儘管目前在網絡中能找到一些環境部署指南,但目前仍然沒有全面的安裝說明。另外,我也不得不閱讀了很多文檔來試圖理解安裝細節——其中的一些並不完整,甚至包含語法錯誤。
  • 深度學習軟體安裝指南
    儘管已經有很多非常棒的關於英偉達驅動和 CUDA 的安裝指南, 但依然沒有詳盡的深度學習環境搭建指南。另外,我需要查閱很多文檔來熟悉細節,其中一些細節還有待完善,甚至還有一些包含語法錯誤。因此我決定把我這段時間查閱的文檔(見參考連結)做個總結。該指南會安裝如下內容下面顯示了每個包的依賴項。Python 深度學習庫只需安裝一個,你可以選擇一個喜歡的進行安裝。
  • 用GPU加速深度學習: Windows安裝CUDA+TensorFlow教程
    背景在Windows上使用GPU進行深度學習一直都不是主流,我們一般都首選Linux作為深度學習作業系統。但很多朋友如果只是想要了解深度學習,似乎沒有必要專門裝雙系統或者改用Linux。現實生活中,很多使用學校或者公司電腦的朋友也沒有操作權限改換系統。
  • 10個深度學習軟體的安裝指南(附代碼)
    由於近期論文的需要,我搭建了一個基於 Ubuntu 和英偉達的深度學習環境。儘管已經有很多非常棒的關於英偉達驅動和 CUDA 的安裝指南, 但依然沒有詳盡的深度學習環境搭建指南。另外,我需要查閱很多文檔來熟悉細節,其中一些細節還有待完善,甚至還有一些包含語法錯誤。因此我決定把我這段時間查閱的文檔(見參考連結)做個總結。
  • 深度學習環境搭建
    0 前言本文作者接觸深度學習2個月後,開始進行目標檢測實踐。本文作者的專題《目標檢測》連結:https://www.jianshu.com/c/fd1d6f784c1f此專題的宗旨是讓基礎較為薄弱的新手能夠順利實現目標檢測,專題內容偏向於掌握技能,學會工具的使用。
  • 深度學習訓練時 GPU 溫度過高?輸入這幾行命令就能迅速降溫
    首先得到知乎上一位朋友的文章啟發:從零開始組裝深度學習平臺(GPU散熱)。  一、如果你有顯示器(X server)可以完全按照上面提到的文章《從零開始組裝深度學習平臺》操作,這裡貼出關鍵步驟為:1.感謝原文知乎作者:張三  二、如果你沒有顯示器一般在ubuntu上搭建完深度學習環境後,許多朋友習慣把ubuntu的X桌面服務禁用掉,然後通過另一臺windows系統的電腦通過ssh來連接GPU機器使用。
  • FB發布PyTorch:一個GPU加速的Python深度學習框架
    PyTorch是一個Python優先的深度學習框架。先來看看推上的評價:● 《Python機器學習》的作者Raschka說:終於發布了!我很好奇。對我來說,PyTorch看起來是目前最棒的深度學習庫,它的「動態」代碼令人印象深刻。
  • 教程 | 如何使用深度學習硬體的空餘算力自動挖礦
    如果沒有 GPU,現代深度學習是不可能發展到今天的水平的。即使是 MNIST 數據集上的簡單示例算法在 GPU 和 CPU 上運行速度的差別也有 10-100 倍。但是,當你沒有優化所有設置時,GPU 空閒的算力該作何用?
  • Pytorch-GPU1.7.1 和 TensorFlow-GPU1.14.0 安裝指南(基於windows10)
    GPU的並行計算能力,在過去幾年裡恰當地滿足了深度學習的需求。AMD的GPU基本沒有什麼支持,可以不用考慮。驅動:沒有顯卡驅動,就不能識別GPU硬體,不能調用其計算資源。CUDA:是顯卡廠商NVIDIA推出的只能用於自家GPU的並行計算框架。只有安裝這個框架才能夠進行複雜的並行計算。主流的深度學習框架也都是基於CUDA進行GPU並行加速的,幾乎無一例外。
  • 使用GPU.js改善JavaScript性能
    在該初學者指南中,我們將演示如何使用GPU.js執行複雜的數學計算並提高JavaScript應用的性能。什麼是GPU.js?GPU.js是一個針對Web和Node.js構建的JavaScript加速庫,用於在圖形處理單元(GPGPU)上進行通用編程,它使你可以將複雜且耗時的計算移交給GPU而不是CPU,以實現更快的計算和操作。
  • 實踐經驗分享:在深度學習中餵飽GPU
    關注 極市平臺 公眾號 ,回復 加群,立刻申請入群~前段時間訓練了不少模型,發現並不是大力出奇蹟,顯卡越多越好,有時候 1 張 v100 和 2 張 v100 可能沒有什麼區別,後來發現瓶頸在其他地方,寫篇文章來總結一下自己用過的一些小 trick,最後的效果就是在 cifar 上面跑 vgg
  • 深度學習筆記15:ubuntu16.04 下深度學習開發環境搭建與配置
    作者:魯偉一個數據科學踐行者的學習日記。
  • 沒有GPU的同學想學習深度學習,可以試試Google Colab Notebooks!
    背景很多同學想學習深度學習,但是無奈自己的機器老舊,要麼顯卡老舊,要麼不是Nvidia的顯卡,有的甚至沒有顯卡。沒有GPU加速,深度學習還怎麼玩?乖乖,怎麼能夠抵擋我成為一名學霸呢。查看gpu信息可以看出GPU是Tesla T4。