shamangary's Blog

Torch Tricks about 'cudnn', 'output size', and 'clearState()' with 'model size' (Torch 小技巧)

| Comments

1. 我的電腦只有CPU而沒有GPU,cudnn和nn能互相轉換嗎?

可以轉換,不過你要先安裝cudnn才可以,然而你通常需要有GPU的電腦才能安裝cudnn......你可能需要請你朋友幫忙:P

require('nn')
require('cudnn')

cudnn.convert(model,nn)       --=> convert to nn
cudnn.convert(model,cudnn)    --=> convert to cudnn

2. 我在跑我的model,但我不太想去算某一層的feature map size是什麼?有沒有辦法告訴我?

有,直接插入一層

model:add(nn.Reshape(1))

因為nn.Reshape()之中有內建在錯誤訊息中告訴你input和output的大小分別是多少,你跑一次後看錯誤訊息後知道大小了,就可以拔掉這層然後加入正確的下層參數了,例如說你的下層可能是nn.Linear(inputSize,outputSize)需要知道上一層的大小才能填入正確的inputSize,這個時候就可以用這個方法來處理了。

注意一件事情,nn.View()和nn.Reshape()能做的事情非常像,但是nn.View()沒有這個功能,所以我通常都用nn.Reshape()。

3. 我想縮小我的model,我已經用了clearState()除掉了暫存的output(也就是feature maps),為何clearState()沒有處理gradWeight和gradBias?

https://github.com/soumith/cudnn.torch/issues/138
理論上來說,如果你做完training了,應該是不需要gradient了,因為你只需要做forward得到結果而已,但是通常我們有時候會想要繼續在已知的model做training,是故如果沒有留下gradWeight和gradBias,之後會很麻煩,所以作者設計上不希望clearState()拿掉它們。

然而有時候我們真的不需要它們兩個,有沒有辦法去除?有人幫寫了
https://github.com/fmassa/optimize-net
乖乖膜拜大神就好(祭拜中

4. 為何我用了clearState()後我的model還是超級大

https://github.com/soumith/cudnn.torch/issues/313
有可能是因為你之前是用cudnn去做training,之後你轉回了nn,然而你發現在nn底下的model就算做了clearState(),容量還是超級大,這是因為好像最新的cudnn加入了input_slice和output_slice這樣的變數,而在nn底下沒辦法處理,是故你應該在cudnn底下做完clearState()後,再轉回nn即可(雖然我覺得這種事情根本就算是bug)。

5. (2017/07/24更新) 有沒有那種在nn有處理,但是cudnn沒有處理的clearState()?

答案是有的......例如說cudnn.SpatialMaxPooling就完全沒有寫clearState(),而在nn底下就有,
如果想要確保都有clear,建議你在cudnn底下做一次clearState(),回到了nn後記得再做一次(天啊。

6. (2017/07/24更新) 如何使用optnet?可以畫出使用記憶體大小的圖解嗎?

require('nn')
require('dpnn')
optnet = require('optnet')


---------------------------------------------
--Optimize the memory by optnet

net = torch.load('model_best.t7')

net:float()
print(net)
input = torch.rand(1,3,55,55):float()
opts = {inplace=true, mode='inference'}
optnet.optimizeMemory(net,input,opts)

net:clearState() -------------------------> You still need to do this...
torch.save('test.t7',net)

---------------------------------------------
--Plot the memory usage
generateGraph = require 'optnet.graphgen'

-- visual properties of the generated graph
-- follows graphviz attributes
graphOpts = {
displayProps =  {shape='ellipse',fontsize=14, style='solid'},
nodeData = function(oldData, tensor)
  return oldData .. '\n' .. 'Size: '.. tensor:numel()
end
}

g = generateGraph(net, input, graphOpts)

graph.dot(g,'test','myTest')
--------------------------------------------

有一次執行失敗是說不要用'th',而要用qlua當作開頭,好像是畫圖需要

qlua compress.lua

但是我後來執行又發現'th'又可以了,不管,反正你就都試試看

th compress.lua

執行完後你會發現你會畫出'myTest.svg'的圖,同樣顏色代表同樣大小,不過好像沒有直接看處哪層比較大的方法,好像只能從相對關係看吧,如果想要縮小你的model就進去找找看有什麼東西是多存的。例如說如果你用了dpnn的東西,optnet未必能移除所有的多餘變數,是故這一步畫圖還蠻重要的。我畫出來才發現optnet似乎沒有移除SpatilMaxPooling的變數,所以要去check。

7. (2017/07/24更新) 用完optnet還需要用clearState()嗎?

竟然是需要的......總之我再用了一次後,竟然又變小了,不知道是殺小。

8. (2017/07/24更新) Summary of compress a torch model

總之下面步驟就是全做最保險

1. clearState() under cudnn

2. convert cudnn to nn

3. clearState() under nn

4. use optnet for inference model

5. clearState() under nn (again)

Comments

comments powered by Disqus