本文主要講解如何在windows平臺配置python深度學習框架,花了3-4天才完全配置好了python+theano,一定得好好地寫一下。
關於python的強大,我就不說了,自己體會吧,我也正在體會中。首先極力推薦使用它anaconda,anaconda內置地包含了numpy等各種各樣科學計算所需要的開源庫,省掉了很多時間去獨自配置這些東西。好吧,廢話不多說了,現在開始。
第一步 下載anaconda
在這裏請注意,先看好你的電腦室32的還是64的,請下對應的版本。我的是win7 64位的所以下載的就是
這裏需要說一下,我剛開始下載的是PYTHON3.5的版本,這兩個版本都是不包含mingw和libpython包的,需要自己進行安裝,但是後來悲劇了,3.5版本死活安裝不了libpython,提示libpython與PYTHON3.5有衝突,沒辦法安裝,我查了好長時間,也沒有解決,這點還要靠大家自己去查,看看是什麼情況。所以最後我沒辦法了,就重新下載了PYTHON2.7版本的進行安裝配置,居然成功了。所以這裏極力推薦大家下載2.7版本的,也就是上圖畫紅色圈的那個。
第二部安裝anaconda
這不基本上是無腦操作,下載好anaconda(python2.7)後,進行安裝,安裝過程中會提,將默認添加環境變量欄目點上,省掉一些自己配置的步驟。安裝在哪個盤其實無所謂了,看你個人的情況了,但是請記得你的安裝位置,後邊要配置環境變量。
第三部配置mingw和libpython
安裝完anaconda後打開 anaconda prompt,輸入conda list,會顯示現在的已經安裝好的開源包。
往下拉,會發現沒有mingw包和libpython包,所以需要自己進行配置。沒有這兩個包theano是沒辦法使用的,會報錯。所以先安裝mingw和libpython,點擊開始-cmd,輸入conda install mingw libpython,將會自動安裝mingw和libpython(請注意這裏對於python2.7的是可以正確無誤安裝的,但是對於python3.5會提示libpython與python3.5衝突沒法安裝,所以建議下載anaconda的時候下載PYTHON2.7的)。安裝完後進入下一步。
第四部環境配置
網上查閱的環境配置基本相同,但是裏邊還是有少許問題的,我的配置是直接在環境變量中的系統變量path中加入
D:\Anaconda2;
D:\Anaconda2\Library\bin;
D:\Anaconda2\MinGW\bin;
D:\Anaconda2\MinGW\x86_64-w64-mingw32\lib;
D:\Anaconda2\Scripts;
(注意改成你自己的anaconda所在的位置)
網上還有的教程說要在用戶變量中添加PYTHONPATH變量,剛開始我也是按照網上說的這麼來的,可是發現添加PYTHONPATH變量後spyder打不開了,然後我直接刪除了PYTHONPATH這個用戶變量,可以正常使用spyder了。
然後在cmd的home目錄中新建.theanorc.txt文件,這裏有些人不知道什麼是home文件,我剛開始也不明白,後來知道了就是你點開始-cmd,進入命令行後的當前目錄,我的是進入該目錄後,新建
.theanorc.txt文件,這兩個點都不能少,然後在該文件中鍵入
[global]
openmp=False
[blas]
ldflags=
[gcc]
cxxflags=-ID:\Anaconda3\MinGW
請將紅色的部分改成你自己的安裝目錄。現在這樣的寫法是沒有配置gpu的,配置gpu的後邊會講到。
這些弄完之後,最好重啓下電腦,或者註銷下,我是註銷了。
第五部安裝theano
現在安裝theano的前提條件都已經完成了,可以開始安裝theano,最簡單快捷的方法就是進入cmd,輸入pip install theano,便會開始安裝。
這些都弄完後,沒有錯誤了,就可以試試是否可以用了,在cmd 下進入python,輸入import theano沒有報錯,在輸入theano.test() 出現
後邊有一大堆的信息,至於是什麼,自己以後慢慢理解,現在我也不太清楚。
這樣theano就安裝完畢了,可以寫一個cnn的例子來試下效果了
import theano
import numpy
import pylab
from theano import tensor as T
from theano.tensor.nnet import conv
from PIL import Image
# 生成一個隨機數生成類rng,其seed爲23455(隨機數種子)。
rng = numpy.random.RandomState(23455)
# 實例化一個4D的輸入tensor,是一個象徵性的輸入,相當於形參,需要調用時傳入一個實參
input = T.tensor4(name='input')
# 權值數組的shape(可以理解爲權值的數組大小),用來確定需要產生的隨機數個數,
#(該大小可以理解爲是一個 2行3列 的矩陣,其中每個矩陣元素又是一個 9行9列的 矩陣)
w_shp = (2, 3, 9, 9)
# 每個權值的邊界,用來確定需要產生的每個隨機數的範圍。
w_bound = numpy.sqrt(3 * 9 * 9)
# rng.uniform(low,hign,size)的作用是產生一個shape爲size的均勻分佈數組,每個數的範圍爲(low,high)
# numpy.asarray(a)的作用是將 類數組a 轉化爲array類型
# theano.shared()實例化一個權值變量(只是爲了進行GPU加速時用),可以調用W.get_value()查看其value
W = theano.shared( numpy.asarray(
rng.uniform(
low=-1.0 / w_bound,
high=1.0 / w_bound,
size=w_shp),
dtype=input.dtype), name ='W')
# 下面是用同樣的方法初始化一個偏置值b,b通常被初始化爲0,因爲它在算法中會有一個被學習的過程;
# 但是此處是需要直接用它來計算,所以用隨機值給它初始化,就當做是已經經過學習後的值了。
b_shp = (2,)
b = theano.shared(numpy.asarray(
rng.uniform(low=-.5, high=.5, size=b_shp),
dtype=input.dtype), name ='b')
# conv.conv2d(input,filter) 需要2個輸入,一個是input,一個是filter。
# input就是上文中的4D張量,每個張量分別代表[mini-batch size,特徵圖的數量,圖像高度,圖像寬度]。
# filter就是上文中的W。也是一個4D張量,分別代表[m層特徵圖數量,m-1層特徵圖數量,過濾器高度,過濾器寬度]。
#
# 當其他函數需要用到變量conv_out時,會先把實參input傳入conv2d()中,再計算出conv_out
#
conv_out = conv.conv2d(input, W)
# dimshuffle是一個很強大的能輕鬆改變一個張量結構的工具。b.dimshuffle('x', 0, 'x', 'x')
# 就是把b的原始的第0列向量的左側添加一個維度,在其右側添加兩個維度。
# b原來是個一維數據(2),經過dimshuffle之後,則變成了一個四維數據(1*2*1*1)。
# dimshuffle具體的操作,參見文章一開始。
output = T.nnet.sigmoid(conv_out + b.dimshuffle('x', 0, 'x', 'x'))
# 創建一個用來過濾圖像的theano.function(可以把f編譯爲c,然後就可以隨時拿來用了。)
#
# 當其他函數需要調用f時(調用形式爲f(input)),需要傳入實參input,然後將計算結果存入output中。
#
f = theano.function([input], output)
# 下面開始處理幾幅圖片來看一下效果
# 打開一幅圖片,源代碼中有2個"open",應該是在linux中的語法,我是在windows上運行的,所以改成1個open
img = Image.open('e:\\parker.jpg')
# 得到圖片的寬度和高度(注意,順序一定不要弄反)
img_w, img_h = img.size
# 將圖片像素按照(高度,寬度,通道數量)格式化爲array數組
# 其實就是將圖片數據格式化爲一個數組,因爲每個像素點包括3個字節,B,G,R,且其範圍爲0-255,
# 這個地方最後將其除以256是爲了歸一化,歸一化後的數據是float64類型
img = numpy.asarray(img, dtype='float32') / 256.
# 圖片的原始數據是一個3D數據【高,寬,通道數量】,
# 經過數據置換(transpose(2,0,1))之後,變成了【通道數量,高,寬】,
# 因爲f中傳入參數需要4D,因此需要將圖片數據reshape成爲一個【1, 通道數量, 高, 寬】這樣的4D張量,
# reshape的參數一定要注意,1就是最外的那一維度,3就是通道數量,然後是【高】和【寬】,
# 這樣結果的 img_.shape =【1, 3, 寬, 高】
#
# 爲什麼reshape爲這樣的size呢?因爲調用f時需要傳入一個input,而這個input就是4D,最終的這個input是傳入到
# conv2d中的第一個參數,而那個參數的格式是什麼呢?[mini-batch size,特徵圖的數量,圖像高度,圖像寬度]
# 這樣就串起來了吧,第一個參數是batch size,據我所知應該是指卷積核的數量吧,但是不知道爲什麼這裏是1?
# 第二個參數代表輸入層的特徵圖數量,這個地方是3,其實就是把一張彩色圖片按照3個通道作爲3個特徵圖進行輸入;
# 最後兩個是圖像的高度和寬度,正好一一對應。
#
img_ = img.transpose(2, 0, 1).reshape(1, 3, img_h, img_w)
# 將img_作爲f的參數,經過計算得到輸出
filtered_img = f(img_)
# 將原始圖片顯示出來
pylab.subplot(1, 3, 1); pylab.axis('off'); pylab.imshow(img)
# 圖片灰度化
pylab.gray();
# 分別顯示不同處理後的圖片
pylab.subplot(1, 3, 2); pylab.axis('off'); pylab.imshow(filtered_img[0, 0, :, :])
pylab.subplot(1, 3, 3); pylab.axis('off'); pylab.imshow(filtered_img[0, 1, :, :])
pylab.show()
結果圖,原圖,特徵圖
第六步 安裝cuda
安裝的前提是你自己的電腦已有GPU,可以上官網上查查自己顯卡對應支持的cuda,然後選擇對應支持的cuda進行下載。我的顯卡是gt705,我下載的是cuda7.5的版本。此外安裝cuda之前要先安裝vs編譯器,網上推薦的是vs2010-2014,我的是vs2013。大家自己選擇吧。先安裝vs在安裝cuda。
無腦進行安裝後進入到下一步。安裝完cuda後,系統會自動添加環境變量CUDA_PATH和CUDA_PATH_V7_5。
[global]
openmp=False
device=gpu
floatX=float32
allow_input_downcast=True
[blas]
ldflags=
[gcc]
cxxflags=-ID:\Anaconda3\MinGW
[nvcc]
flags = -LD:\Anaconda2\libs
compiler_bindir = D:\Microsoft Visual Studio 12.0\VC\bin
fastmath = True
flags=-arch=sm_30
紅色部分是在原來的基礎上新添加的,黃色部分是你自己對應的anaconda目錄,vs編譯器的vc主目錄。
注意很多博客和資料上都是到這一步就結束了,其實我自己安裝的時候,並不是這樣,還需要自己手動配置一些環境變量來完成cuda配置。
首先再系統環境變量中加入
CUDA_SDK_PATH:C:\ProgramData\NVIDIA Corporation\CUDA Samples\v7.5(注意這個填寫你自己的cuda位置,版本不同但是默認安裝的都在C:\ProgramData\NVIDIA Corporation下面,自己找下。)
然後加入CUDA_BIN_PATH:%CUDA_PATH%\bin
CUDA_LIB_PATH:%CUDA_PATH%\lib\x64(這裏注意根據自己的系統以及安裝的cuda來選擇,有32位和64位的,我的是64的)
加入 CUDA_SDK_BIN_PATH:%CUDA_SDK_PATH%\bin\x64(同上我的是64位的)
加入 CUDA_SDK_LIB_PATH:%CUDA_SDK_PATH%\common\lib\x64(同上我的是64位的)
ok到這基本上結束了,打開cmd,輸入python,然後import theano會出現(我的顯卡是gt705的,不是特別好.......)
有些童鞋可能還會出現一些警告,和debug信息,其實沒什麼關係,google了一下說是優化忽略之類的問題,不影響使用,ok現在再來跑cuda的測試程序
"""
Created on Tue Mar 15 23:44:52 2016
@author: Administrator
"""
from theano import function, config, shared, sandbox
import theano.tensor as T
import numpy
import time
vlen = 10 * 30 * 768 # 10 x #cores x # threads per core
iters = 1000
rng = 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 range(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')
會出現如下結果:
ok,我們看見已經開始使用gpu了,可是有兩個警告,但是繼續往後看,裏面寫着你可以忽略他
reference:
http://blog.csdn.net/niuwei22007/article/details/47684673
http://blog.sina.com.cn/s/blog_990865340101hvuq.html
http://blog.csdn.net/abcjennifer/article/details/25912675