【theano-windows】学习笔记十一——theano中与神经网络相关函数
前言
經(jīng)過softmax和MLP的學習, 我們發(fā)現(xiàn)thenao.tensor中除了之前的博客【theano-windows】學習筆記五——theano中張量部分函數(shù)提到的張量的定義和基本運算外, 還有一個方法稱為nnet, 如果自己實現(xiàn)過前面兩篇博客中的代碼就會發(fā)現(xiàn)用到了theano.tensor.nnet.sigmoid和thenao.tensor.nnet.tanh這兩個神經(jīng)網(wǎng)絡(luò)的激活函數(shù), 那么就應(yīng)該想了, 這個nnet是否對于在theano中實現(xiàn)神經(jīng)網(wǎng)絡(luò)很重要呢?所以我就跑去看了一下官網(wǎng)的介紹了, 感覺有必要摘抄一波.
【注】本次學習只是摘抄點感覺常用的函數(shù), 見到陌生的操作可以再去查官方文檔
進入官方對nnet的介紹的界面時, 可以發(fā)現(xiàn)有五種操作
- conv:卷積神經(jīng)網(wǎng)絡(luò)相關(guān)操作
- nnet:神經(jīng)網(wǎng)絡(luò)相關(guān)操作
- neighbours:卷積網(wǎng)絡(luò)中圖片的處理操作
- bn: 批歸一化batch normalization
- blocksparse: 塊稀疏乘法操作(有g(shù)emv和outer)
國際慣例, 參考博客
Ops related to neural networks
Theano tutorial和卷積神經(jīng)網(wǎng)絡(luò)的Theano實現(xiàn)
卷積相關(guān)操作
2D卷積函數(shù)
theano.tensor.nnet.conv2d(input, filters, input_shape=None, filter_shape=None, border_mode='valid', subsample=(1, 1), filter_flip=True, image_shape=None, **kwargs)#默認翻轉(zhuǎn)卷積核參數(shù)解釋:
- input: 四維張量符號變量, 維度依次代表(批大小, 輸入通道, 輸入行, 輸入列)
- filters: 四維張量符號變量. 維度依次代表(輸出通道, 輸入通道, 濾波器行, 濾波器列)
- input_shape: 可選變量, 可以是None, 也可以是四個整數(shù)或者常量組成的元組或者列表, 代表輸入的大小
- filter_shape: 可選變量, 可以是None, 也可以是四個整數(shù)或者常量組成的元組或者列表, 用于選擇優(yōu)化實現(xiàn), 可以指定列表中某個元素為None, 表示這個元素在編譯的時候是未知的
- border_mode: 字符串, 整型, 或者兩個整型組成的元組-以下任意一種
valid: 輸出大小inputshape?flitershape+1input shape-flitershape+1inputshape?flitershape+1
full: 輸出大小inputshape+filtershape?1inputshape+filtershape-1inputshape+filtershape?1
half: 使用rows//2rows//2rows//2行和colums//2colums//2colums//2列對稱填充輸入邊界,然后執(zhí)行valid
int: 使用指定的全零寬度向量填充輸入的對稱邊界, 然后使用valid
(int1,int2): 使用int1行和int2列填充輸入的對稱邊界, 然后執(zhí)行valid - subsample: 長度為2的元組, 對輸出進行下采樣, 也稱為步長strides
- fliter_flip: 如果為True, 就在滑動卷積窗口前翻轉(zhuǎn)filter, 翻轉(zhuǎn)filter的操作經(jīng)常稱為卷積(convolution),而且這個值經(jīng)常默認為True. 如果設(shè)置為False, 那么就不翻轉(zhuǎn)filter, 這個操作一般叫做互相關(guān)(cross-correlation)
- image_shape: 為None或者四個整型或者常變量組成的元組或者列表, input_shape的別名, 已棄用
- filter_dilation:長度為2的元組, 對輸入進行下采樣, 經(jīng)常稱為空洞卷積(dilation),詳細看知乎的解釋如何理解空洞卷積(dilated convolution)?
- kwargs: 兼容性, 常被忽略
返回值: 一系列的特征圖, 大小是(批大小, 輸出通道, 輸出行, 輸出列)
theano.sandbox.cuda.fftconv.conv2d_fft(input, filters, image_shape=None, filter_shape=None, border_mode='valid', pad_last_dim=False)簡介: 是僅支持GPU的nnet.conv2d是實現(xiàn), 使用了傅里葉變換來實現(xiàn)這個操作, 也會翻轉(zhuǎn)卷積核. 但是conv2d_fft不能被直接使用, 因為沒有提供梯度. 僅僅支持輸入的最后一個維度是偶數(shù), 其它的維度任意, 濾波器可以具有偶數(shù)或者技術(shù)的寬度. 如果你的輸入一定具有奇數(shù)寬度, 那么可以使用填充的方法來解決, 如果你不確定你的輸入倒是是偶數(shù)還是技術(shù), 千萬不要隨便使用填充參數(shù)pad_last_dim, 因為這個參數(shù)是無條件的加接一個維度, 可能會讓偶數(shù)輸入變技術(shù), 導(dǎo)致一些問題的發(fā)生…balabalabala后面一堆, 反正意思就是使用它挺麻煩的, 不如直接用nnet.conv2d了
參數(shù)(在valid模式中輸入必須大于濾波器)與上面的conv2d相同, 就是多了一個不一樣的:
- pad_last_dim: 無條件地對最后一個維度進行填充.返回結(jié)果時會刪除這個填充的部分
3D卷積
theano.tensor.nnet.conv3d(input, filters, input_shape=None, filter_shape=None, border_mode='valid', subsample=(1, 1, 1), filter_flip=True, filter_dilation=(1, 1, 1))參數(shù):
- input: 五維的符號張量. 每個維度分別代表(批大小, 輸入通道, 輸入深度, 輸入行, 輸入列)
- filters: 五維的符號張量. 每個維度分別代表(輸出通道, 輸入通道, 濾波器深度, 濾波器行, 濾波器列)
- input_shape: 輸入?yún)?shù)大小
- filter_shape: 濾波器參數(shù)大小
- border_mode: 字符串, 整型, 或者兩個整型組成的元組-以下任意一種
valid: 輸出大小inputshape?flitershape+1input shape-flitershape+1inputshape?flitershape+1
full: 輸出大小inputshape+filtershape?1inputshape+filtershape-1inputshape+filtershape?1
half: 使用filterrows//2filterrows//2filterrows//2行和filter//columsfilter//columsfilter//colums列對稱填充輸入邊界,然后執(zhí)行valid
int: 使用指定的全零寬度向量填充輸入的對稱邊界, 然后使用valid
(int1,int2,int3): 使用int1、int2和’int3’行填充輸入的對稱邊界, 然后執(zhí)行valid - subsample: 長度為3的元組, 對輸出進行下采樣, 也稱為步長strides
- fliter_flip: 如果為True, 就在滑動卷積窗口前翻轉(zhuǎn)filter的’x,y,z’維度, 翻轉(zhuǎn)filter的操作經(jīng)常稱為卷積(convolution),而且這個值經(jīng)常默認為True. 如果設(shè)置為False, 那么就不翻轉(zhuǎn)filter, 這個操作一般叫做互相關(guān)(cross-correlation)
- filter_dilation:長度為3的元組, 對輸入進行下采樣, 經(jīng)常稱為空洞卷積(dilation)
返回值:卷積得到的特征圖, 維度分別代表(批大小, 輸出通道, 輸出深度, 輸出行, 輸出列)
theano.sandbox.cuda.fftconv.conv3d_fft(input, filters, image_shape=None, filter_shape=None, border_mode='valid', pad_last_dim=False)通過快速傅里葉變換fft執(zhí)行卷積, 僅僅支持輸入的最后一維是偶數(shù). 其它的維度可以任意, 濾波器的最后一維可以是偶數(shù)或者奇數(shù).
最后三個維度的語義并不重要, 只要他們在輸入和濾波器之間的順序是一樣的就行.比如卷積如果是在圖像里面執(zhí)行的, 那么可以是(duration,height,width)也可以是(height,width,duration)…剩下的和conv2d_fft的描述一樣, 就是如果你非要輸入奇數(shù)維度, 請使用填充參數(shù)balabalabala…
theano.tensor.nnet.conv3d2d.conv3d(signals, filters, signals_shape=None, filters_shape=None, border_mode='valid')簡介: conv3d2d是使用conv2加上數(shù)據(jù)reshape實現(xiàn)的三維卷積操作, 某些情況下比conv3d快, 它在GPU上工作, 并且翻轉(zhuǎn)卷積核. 包含視頻的時空卷積
參數(shù):
- signals: 像素具有顏色通道的圖像的時間序列, 形狀是[Ns,Ts,C,Hs,Ws]
- filters: 時空濾波器,維度[Nf, Tf, C, Hf, Wf]
- signals_shape: 信號的維度
- filter_shape: 濾波器的維度
- border_mode: 這個與卷積相同, 有valid,full,half
注: 另一種定義signals的方法是(批, 時間, 輸入通道, 行, 列) ; 另一種定義濾波器的方法(輸出通道, 時間, 輸入通道, 行, 列)
還有一堆其它的函數(shù)懶得貼了, 以后遇到了再說
神經(jīng)網(wǎng)絡(luò)相關(guān)操作
其實就是各種激活函數(shù)之類的:
##sigmoid
sigmoid(x)=11+e?xsigmoid(x)=\frac{1}{1+e^{-x}} sigmoid(x)=1+e?x1?
theano.tensor.nnet.nnet.sigmoid(x) theano.tensor.nnet.nnet.ultra_fast_sigmoid(x) theano.tensor.nnet.nnet.hard_sigmoid(x) ''' hard_sigmoid: 1.0s ultra_fast_sigmoid: 1.3s sigmoid (with amdlibm): 2.3s sigmoid (without amdlibm): 3.7s '''##softplus
softplus(x)=loge(1+ex)softplus(x)=log_e(1+e^x) softplus(x)=loge?(1+ex)
theano.tensor.nnet.nnet.softplus(x) #神經(jīng)網(wǎng)絡(luò)中的用法經(jīng)常如下 x,y,b = T.dvectors('x','y','b') W = T.dmatrix('W') y = T.nnet.softplus(T.dot(W,x) + b)##softsign
softsign=x1+abs(x)softsign=\frac{x}{1+abs(x)} softsign=1+abs(x)x?
theano.tensor.nnet.nnet.softsign(x)##softmax
softmaxij(x)=exij∑kexiksoftmax_{ij}(x)=\frac{e^{x_{ij}}}{\sum_k e^{x_{ik}}} softmaxij?(x)=∑k?exik?exij??
有一個小技巧就是這個softmax的計算是穩(wěn)定的, 因為它采用了如下計算過程:
e_x = exp(x - x.max(axis=1, keepdims=True)) out = e_x / e_x.sum(axis=1, keepdims=True)也就是說先減去了一個最大值, 隨后才采用softmax的標準式子計算屬于每個類別的概率(突然想到, 如果之前層用sigmoid激活, 是不是softmax就不需要減去最大值了么?因為sigmoid使得x∈{0,1}x\in\{0,1\}x∈{0,1},而使用Relu的話, 最好還是減一下, 但是總而言之, 無論是caffe還是theano都進行了減最大值操作). 為什么要減?因為如果上一層輸出xxx很大, 那么編譯器就會發(fā)生上溢出(e1000e^{1000}e1000)或者下溢出(e?1000e^{-1000}e?1000), 那么減去最大值以后肯定不會上溢出了, 即使發(fā)生下溢出, 也會由于取對數(shù)而解決此問題. 詳細原因請戳這里1,這里2
x,y,b = T.dvectors('x','y','b') W = T.dmatrix('W') y = T.nnet.softmax(T.dot(W,x) + b)##Relu
theano.tensor.nnet.relu(x, alpha=0)alpha是負值輸入的斜率,屬于0-1之間, 默認為0(標準的Relu), 如果是1的話, 激活函數(shù)就成線性激活了, 而其它的數(shù)就是傳說中的Leaky Relu
因為這個函數(shù)比較重要, 所以擴展一下說明它的三種形式Relu,LeakyRelu,PRelu,摘自[Caffe]:關(guān)于ReLU、LeakyReLU 、PReLU layer
-
Relu
forwardactivation:f(x)=max?(0,x)backwardgradient:?E?x={0,ifx≤0?E?y,ifx>0forward\ activation:f(x)=\max(0,x)\\ backward\ gradient:\frac{\partial E}{\partial x}=\begin{cases} 0 ,\ if\ x\leq0\\ \frac{\partial E}{\partial y}, if \ x>0 \end{cases} forward?activation:f(x)=max(0,x)backward?gradient:?x?E?={0,?if?x≤0?y?E?,if?x>0? -
Leaky Relu
forwardactivation:f(x)=max(0,x)+negativeslop?min(0,x)backwardgradient:?E?x={v??E?y,ifx≤0?E?x,ifx>0forward\ activation: f(x)=max(0,x)+negativeslop*min(0,x)\\ backward\ gradient:\frac{\partial E}{\partial x}=\begin{cases} v*\frac{\partial E}{\partial y},\ if\ x\leq0\\ \frac{\partial E}{\partial x},\ if\ x>0 \end{cases} forward?activation:f(x)=max(0,x)+negativeslop?min(0,x)backward?gradient:?x?E?={v??y?E?,?if?x≤0?x?E?,?if?x>0? -
Parametric Relu
forwardactivation:f(xi)=max(0,xi)+ai?min(0,xi)backwardactivation:{forxi:?E?xi={ai?E?yi,ifxi≤0?E?yi,ifxi>0forai:?E?ai={∑xixi?E?yi,ifxi≤00,ifxi>0forward\ activation: f(x_i)=max(0,x_i)+a_i*min(0,x_i)\\ backward \ activation: \begin{cases} for\ x_i:\frac{\partial E}{\partial x_i}=\begin{cases} a_i\frac{\partial E}{\partial y_i},\ if \ x_i\leq0\\ \frac{\partial E}{\partial y_i},\ if \ x_i>0 \end{cases}\\ for \ a_i: \frac{\partial E}{\partial a_i}=\begin{cases} \sum_{x_i}x_i\frac{\partial E}{\partial y_i},\ if \ x_i\leq0\\ 0,\ if\ x_i>0 \end{cases} \end{cases} forward?activation:f(xi?)=max(0,xi?)+ai??min(0,xi?)backward?activation:????????????for?xi?:?xi??E?={ai??yi??E?,?if?xi?≤0?yi??E?,?if?xi?>0?for?ai?:?ai??E?={∑xi??xi??yi??E?,?if?xi?≤00,?if?xi?>0??
binary_crossentropy
crossentropy(t,o)=?(t?log?(o)+(1?t)?log?(1?o))crossentropy(t,o)=-(t\cdot \log(o)+(1-t)\cdot \log(1-o)) crossentropy(t,o)=?(t?log(o)+(1?t)?log(1?o))
#theano.tensor.nnet.nnet.binary_crossentropy(output, target) x, y, b, c = T.dvectors('x', 'y', 'b', 'c') W = T.dmatrix('W') V = T.dmatrix('V') h = T.nnet.sigmoid(T.dot(W, x) + b) x_recons = T.nnet.sigmoid(T.dot(V, h) + c) recon_cost = T.nnet.binary_crossentropy(x_recons, x).mean()categorical_crossentropy
返回近似分布和真實分布的交叉熵, 如果編碼方案是基于給定的概率分布q而非真實分布p,那么兩個概率分布之間的交叉熵衡量的就是從一系列的可能性中區(qū)分一個時間所需要的平均編碼長度:
H(p,q)=?∑xp(x)log?(q(x))H(p,q)=-\sum_x p(x)\log(q(x)) H(p,q)=?x∑?p(x)log(q(x))
h_softmax
實現(xiàn)的是兩層層級softmax, 如果輸出的數(shù)目很重要的時候, 此函數(shù)就是softmax的另一個可選項
theano.tensor.nnet.h_softmax(x, batch_size, n_outputs, n_classes, n_outputs_per_class, W1, b1, W2, b2, target=None)參數(shù)說明:
- x:批大小*特征數(shù), 也就是雙層層級softmax的小批輸入
- batch_size: 輸入x的小批大小
- n_outputs: 輸出的個數(shù)
- n_classes:雙層層級softmax的類別數(shù), 對應(yīng)第一個softmax的輸出數(shù)目
- n_outputs_per_class:每一類的輸出個數(shù)
- W1: 輸入x的特征數(shù)*類別數(shù), 第一個softmax的權(quán)重矩陣, 將輸入x映射到類別概率
- b1: 維度就是類別數(shù), 第一個softmax的偏置
- W2:(類別數(shù)*輸入x的特征總數(shù)*n_outputs_per_class, 第二個softmax的權(quán)重矩陣
- b2: 維度是n_classes*n_outputs_per_class,第二個softmax的偏置
- target:維度是(batch_size,)或者(batch_size,1),對于每一個輸入計算對應(yīng)的目標輸出, 如果為None, 那么就計算每個輸入對應(yīng)的所有輸出
返回值: 取決于target, 它有兩種不同大小的輸出. 如果target沒有指定(None)的時候, 那么所有的輸出就被計算出來, 而且返回值大小為(batch_size,n_outputs), 反之, 當target指定以后, 僅僅有對應(yīng)的輸出被返回, 大小是(batch_size,1)
注意: n_output_per_class與n_classes的乘積必須大于或者等于n_outputs,如果嚴格大于, 那么相關(guān)輸出將會被忽略.n_outputs_per_class和n_classes必須與W1,b1,W2和b2的對應(yīng)維度相同。計算效率最高的時候是當n_outputs_per_class和n_classes等于n_outputs的平方根時
【PS】感覺意思就是說返回的是(輸入樣本*預(yù)測出的標簽)或者是(輸入樣本*所有可能標簽的預(yù)測值), 到底是不是, 以后遇到再說.
卷積網(wǎng)絡(luò)中處理圖像的操作
images2neibs
#常用于池化操作 theano.tensor.nnet.neighbours.images2neibs(ten4, neib_shape, neib_step=None, mode='valid')就不翻譯文檔了, 函數(shù)功能大概就是講輸入圖像ten4按照大小為neib_shape的塊滑動從圖像中取塊, 并將每一塊拉成一個向量存著
參數(shù):
- ten4: 輸入圖像, 四維的, (dim1,dim2,row,col)前兩個維度可以是通道和批
- neib_shape: 包含兩個值, 滑動窗口的高寬
- neib_step:滑動的時候跳過的間隔, 類似于卷積的步長, 但是跳過的應(yīng)該是塊, 也就是說如果值為1, 那么每次取得的塊是相鄰但是不想交的, 比如(4,4)就是取行第1-4,5-8,9-12…的塊, 而卷積是取1-4,2-5,3-6的塊,這也就是為什么我們搜這個函數(shù), 在谷歌上展示的都是實現(xiàn)池化操作的原因
- mode:valid需要輸入是池化因子的倍數(shù),ignore_borders: 如果不是倍數(shù), 就忽視邊界
看個例子:
# Defining variables images = T.tensor4('images',dtype= theano.config.floatX) neibs = T.nnet.neighbours.images2neibs(images, neib_shape=(5, 5))# Constructing theano function window_function = theano.function([images], neibs)# Input tensor (one image 10x10) im_val = np.arange(100.,dtype=theano.config.floatX).reshape((1, 1, 10, 10))# Function application neibs_val = window_function(im_val)print im_val print neibs_val可以發(fā)現(xiàn)原始圖像為
[[[[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.][ 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.][ 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.][ 30. 31. 32. 33. 34. 35. 36. 37. 38. 39.][ 40. 41. 42. 43. 44. 45. 46. 47. 48. 49.][ 50. 51. 52. 53. 54. 55. 56. 57. 58. 59.][ 60. 61. 62. 63. 64. 65. 66. 67. 68. 69.][ 70. 71. 72. 73. 74. 75. 76. 77. 78. 79.][ 80. 81. 82. 83. 84. 85. 86. 87. 88. 89.][ 90. 91. 92. 93. 94. 95. 96. 97. 98. 99.]]]]而用[5*5]的塊滑動取值以后變成了
[[ 0. 1. 2. 3. 4. 10. 11. 12. 13. 14. 20. 21. 22. 23.24. 30. 31. 32. 33. 34. 40. 41. 42. 43. 44.][ 5. 6. 7. 8. 9. 15. 16. 17. 18. 19. 25. 26. 27. 28.29. 35. 36. 37. 38. 39. 45. 46. 47. 48. 49.][ 50. 51. 52. 53. 54. 60. 61. 62. 63. 64. 70. 71. 72. 73.74. 80. 81. 82. 83. 84. 90. 91. 92. 93. 94.][ 55. 56. 57. 58. 59. 65. 66. 67. 68. 69. 75. 76. 77. 78.79. 85. 86. 87. 88. 89. 95. 96. 97. 98. 99.]]neibs2images
就是images2neibs的逆操作
theano.tensor.nnet.neighbours.neibs2images(neibs, neib_shape, original_shape, mode='valid')可以把上面的neibs_val還原成原始圖片矩陣
im_new = T.nnet.neighbours.neibs2images(neibs, (5, 5), im_val.shape) # Theano function definition inv_window = theano.function([neibs], im_new) # Function application im_new_val = inv_window(neibs_val) print im_new_val輸出
[[[[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.][ 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.][ 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.][ 30. 31. 32. 33. 34. 35. 36. 37. 38. 39.][ 40. 41. 42. 43. 44. 45. 46. 47. 48. 49.][ 50. 51. 52. 53. 54. 55. 56. 57. 58. 59.][ 60. 61. 62. 63. 64. 65. 66. 67. 68. 69.][ 70. 71. 72. 73. 74. 75. 76. 77. 78. 79.][ 80. 81. 82. 83. 84. 85. 86. 87. 88. 89.][ 90. 91. 92. 93. 94. 95. 96. 97. 98. 99.]]]]Batch Normalization
batch_normalization_train
theano.tensor.nnet.bn.batch_normalization_train(inputs, gamma, beta, axes='per-activation', epsilon=0.0001, running_average_factor=0.1, running_mean=None, running_var=None)簡介: 對于給定輸入計算批歸一化, 使用輸入的均值和方差,下圖摘自論文筆記-Batch Normalization
參數(shù)
- axes: 輸入的需要沿著哪個軸被歸一化,取值為**‘per-activation’**, ‘spatial’ or a tuple of ints, 好像這個取值還會影響最終結(jié)果的好壞, 詳細請戳這里
- gamma: 縮放因子
- beta: 偏置
- epsilon:批歸一化公式中的?\epsilon?,最小1e?51e{-5}1e?5
- running_average_factor: 更新運行時均值和方差使用的更新因子
- running_mean: running_mean * (1 - r_a_factor) + batch mean * r_a_factor
- running_var:running_var * (1 - r_a_factor) + (m / (m - 1)) * batch var * r_a_factor
返回值:
- out: 批歸一化后的輸入
- mean: 沿著歸一化軸的輸入的均值
- invstd: 沿著歸一化軸的輸入的逆標準差
- new_running_mean: 運行時的均值
- new_running_var: 運行時方差
這個函數(shù)的操作等價于:
# for per-activation normalization axes = (0,) # for spatial normalization axes = (0,) + tuple(range(2, inputs.ndim)) mean = inputs.mean(axes, keepdims=True) var = inputs.var(axes, keepdims=True) invstd = T.inv(T.sqrt(var + epsilon)) out = (inputs - mean) * gamma * invstd + betam = T.cast(T.prod(inputs.shape) / T.prod(mean.shape), 'float32') running_mean = running_mean * (1 - running_average_factor) + \mean * running_average_factor running_var = running_var * (1 - running_average_factor) + \(m / (m - 1)) * var * running_average_factorbatch_normalization_test
theano.tensor.nnet.bn.batch_normalization_test(inputs, gamma, beta, mean, var, axes='per-activation', epsilon=0.0001)對給定的輸出使用給定的均值和方差進行批歸一化, 參數(shù)就不說了, 輸出是被歸一化的輸入. 這個操作的等價代碼如下:
# for per-activation normalization axes = (0,) # for spatial normalization axes = (0,) + tuple(range(2, inputs.ndim)) gamma, beta, mean, var = (T.addbroadcast(t, *axes)for t in (gamma, beta, mean, var)) out = (inputs - mean) * gamma / T.sqrt(var + epsilon) + betabatch_normalization
theano.tensor.nnet.bn.batch_normalization(inputs, gamma, beta, mean, std, mode='low_mem')與上面的區(qū)別就是這個函數(shù)雖然使用了GPU, 但是沒有使用cuDNN優(yōu)化,還有其它的暫時也不清楚, 以后遇到再看看具體用法
其它
##SparseBlockGemv
好像就是一個圖像中取出某一塊, 然后將它乘以一個矩陣之類并返回一條向量的操作, 調(diào)用方法不太懂, 是個類方法
class theano.tensor.nnet.blocksparse.SparseBlockGemv(inplace=False)操作類似于這樣
for b in range(batch_size):for j in range(o.shape[1]):for i in range(h.shape[1]):o[b, j, :] += numpy.dot(h[b, i], W[iIdx[b, i], oIdx[b, j]])這個圖解釋的很清楚
也就是按照outputIdx和inputIdx對W進行索引, 然后與h對應(yīng)位置相乘,而且也舉了個例子當outputIdx=1也就是j=3時候的計算方法
make_node(o, W, h, inputIdx, outputIdx)簡介: 計算指定一條向量和矩陣的點乘.
參數(shù):
- o: 輸出向量, 大小為(batch*, oWin, *oSize)
- W: 權(quán)重矩陣, 大小為(iBlocks*, oBlocks, iSize, *oSize)
- h: 低層的輸入, 大小為(batch*, iWin, *iSize)
- inputIdx: 輸入塊的索引, 大小為(batch*, *iWin)
- outputIdx: 輸出塊的索引, 大小為 (batch*, *oWin)
返回值: dot(W[i, j], h[i]) + o[j], 大小為(batch, oWin, oSize)
注意:
- batch:是批大小
- iSize: 是每個輸入塊的大小
- iWin: 是作為輸入的塊的數(shù)目, 這些塊被inputIdx指定
- oBlock: 是可能的輸出塊的數(shù)目
- oSize: 是輸出塊的大小
- oWin是輸出塊的數(shù)目, 可以被計算出來,每塊是通過outputIdx計算的
SparseBlockOuter
class theano.tensor.nnet.blocksparse.SparseBlockOuter(inplace=False)計算兩組向量的外積, 使用結(jié)果更新整個矩陣, 操作類似于
for b in range(batch_size):o[xIdx[b, i], yIdx[b, j]] += (alpha * outer(x[b, i], y[b, j])) make_node(o, x, y, xIdx, yIdx, alpha=None)輸入?yún)?shù):
- o: (xBlocks*, yBlocks, xSize, *ySize)
- x: (batch*, xWin, *xSize)
- y: (batch*, yWin, *ySize)
- xIdx: x塊的索引(batch*, *iWin)
- yIdx: y塊的索引(batch*, *oWin)
返回值:outer(x[i], y[j]) + o[i, j], 大小是(xBlocks, yBlocks, xSize, ySize)
注意
- batch是批大小
- xBlocks是x中的塊的總數(shù)
- xSize是這些x塊中的每一個的大小。
- xWin是將用作x的塊的數(shù)量,將使用哪些塊在xIdx中指定。
- yBlocks是數(shù)字或可能的y塊。
- ySize是這些y塊中的每一個的大小。
- yWin是實際計算的y塊的數(shù)量,將在yIdx中指定要計算的塊。
sparse_block_dot
theano.tensor.nnet.blocksparse.sparse_block_dot(W, h, inputIdx, b, outputIdx)簡介: 計算指定的向量和矩陣的點積(加上偏差)
參數(shù):
- W: 權(quán)重矩陣, 大小為(iBlocks*, oBlocks, iSize, *oSize)
- h: 低層輸入, 大小為(batch*, iWin, *iSize)
- inputIdx: 輸入塊的索引, 大小為 (batch*, *iWin)
- b: 偏置向量, 大小為 (oBlocks*, *oSize)
- outputIdx: 輸出索引, 大小為 (batch*, *oWin)
返回值: dot(W[i, j], h[i]) + b[j], 大小是(batch, oWin, oSize)
注意
- batch是批次大小。
- iBlocks是輸入(來自較低層)中的塊的總數(shù)。
- iSize是每個輸入塊的大小。
- iWin是將用作輸入的塊的數(shù)量,哪些塊將在inputIdx中指定,
- oBlocks是數(shù)字或可能的輸出塊。
- oSize是每個輸出塊的大小。
- oWin1是實際計算的輸出塊數(shù),將在outputIdx中指定要計算哪些塊。
后記
這一次學習比較枯燥, 看了很多函數(shù)都不知道怎么用, 但是知道了里面有很多卷積操作, 提供了一堆激活函數(shù)和損失函數(shù)及其變種, 還可以實現(xiàn)池化操作, 具有batch normalize的實現(xiàn), 還能指定對那一塊進行乘法操作, 然后更新整個矩陣. 厲害了我的theano!!
總結(jié)
以上是生活随笔為你收集整理的【theano-windows】学习笔记十一——theano中与神经网络相关函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工商银行信用卡临时额度有效期多久?到期必
- 下一篇: 【caffe-windows】全卷积网络