Torch7 Scientific Computing For Lua (JIT) (CVPR2015)
Torch7 Scientific Computing For Lua (JIT) (CVPR2015)
Torch7
Scientific computing for Lua(JIT)
www.torch.ch
Ronan Collobert | Koray Kavukcuoglu | Clément Farabet | Soumith Chintala| Dominik Grewe
Torch7 Getting Started
‣ 1: Getting started
➡ Lua: http://www.lua.org
LuaJIT: http://luajit.org/luajit.html
Torch7 A bit of history
‣ Why build Torch around LuaJIT and not simply use Python?
my_table = { 1, 2, 3 }
my_table = { my_var = 'hello', my_other_var = 'bye' }
my_table = { 1, 2, 99, my_var = 'hello' }
my_function = function() print('hello world') end
my_table[my_function] = 'this prints hello world'
my_function()
print(my_table[my_function])
<…>Tensor
IntTensor
FloatTensor
DoubleTensor
Tensor {Storage <ptr>, Offset <N>, Size[N], Stride[N]} N dim arrays
Storage {size <N>, data <ptr>} manages raw mem, resize, size, ….
Memory
Torch7 Numeric library
Lua
nn gnuplot
randomkit cephes qt …
TH Tensor Library luaT
BLAS LAPACK FFTW SSE Lua C API
Torch7 Packages
‣ Package Manager
‣ The nn package
➡ The nn package provides a large set of transfer functions, which all come
with three methods:
➡ upgradeOutput() -- compute the output given the input
➡ upgradeGradInput() -- compute the derivative of the loss wrt input
➡ accGradParameters() -- compute the derivative of the loss wrt weights
➡ The nn package provides a set of common loss functions, which all come
with two methods:
➡ upgradeOutput() -- compute the output given the input
➡ upgradeGradInput() -- compute the derivative of the loss wrt input
Torch7 Efficient backends
‣ Optimized backends
‣ Going Further:
➡ Torch7:
http://www.torch.ch/
https://github.com/torch
‣ 2: Supervised Learning
F6: { } at (xj,yj)
S2: 20x123x123 Nx23x23
Input Image Normalized Image
1x500x500 1x500x500 S4: 20x29x29
{ } at (xk,yk)
C1: 20x494x494 C3: 20x117x117
C5: 200x23x23
Torch7 Examples
➡ step 4/5: define a closure that estimates f(x) and df/dx stochastically
08 -- define a closure, that computes the loss, and dloss/dx
09 feval = function()
10 -- select a new training sample
11 _nidx_ = (_nidx_ or 0) + 1
12 if _nidx_ > (#data)[1] then _nidx_ = 1 end
13
14 local sample = data[_nidx_]
15 local inputs = sample[1]
16 local target = sample[2]
17
18 -- reset gradients (gradients are always accumulated,
19 -- to accomodate batch methods)
20 dl_dx:zero()
21
22 -- evaluate the loss function and its derivative wrt x,
23 -- for that sample
24 local loss_x = criterion:forward(model:forward(inputs), target)
25 model:backward(inputs, criterion:backward(model.output, target))
26
27 -- return loss(x) and dloss/dx
28 return loss_x, dl_dx
29 end
30
Torch7 Examples
Node24
mapindex = {Node26,Node27}
module = nnd.JoinTable
-- The LSTM takes (x, prevRnnState) and computes the new (h, rnnState).
return nn.gModule({x, prevRnnState}, {hOut, nextRnnState}) Node1
mapindex = {Node4,Node5}
end module = nn.CMulTable
Torch7 Examples
01 -- define model
02 model = nn.Sequential()
03 model:add( nn.Linear(100,1000) )
04 model:add( nn.Tanh() )
05 model:add( nn.Linear(1000,10) )
06 model:add( nn.LogSoftMax() )
07
08 -- re-cast model as a CUDA model
09 model:cuda()
10
11 -- define input as a CUDA Tensor
12 input = torch.CudaTensor(100)
13 -- compute model’s output (is a CudaTensor as well)
14 output = model:forward(input)
15
16 -- alternative: convert an existing DoubleTensor to a CudaTensor:
17 input = torch.randn(100):cuda()
18 output = model:forward(input)
Torch7 @Google
‣ x: Torch at Facebook
Torch7 Torch at Facebook
‣ See https://github.com/facebook/fblualib
Torch7 Torch at Facebook
‣ fb.thrift
➡ Thrift serialization for arbitrary Lua objects
➡ Thrift is the multi-platform, multi-language serialization used in production at FB
➡ Built-in optional compression
‣ fb.thrift
➡ Example
‣ fb.debugger
➡ full-featured source-level Lua debugger
➡ does not require Torch
‣ 2 modes of operation
➡ directly within the code
‣ fb.python
➡ bridge between Lua and Python
➡ enables seamless integration between languages
➡ use SciPy with Lua tensors almost as efficiently as with native numpy arrays
➡ on the fly data conversion, use numpy/scipy/matplotlib with Torch tensors
➡ py.exec(code, locals) executes a given Python code string (no return)
➡ py.eval(code, locals) evaluate a given Python code string (and returns a value)
‣ Data model
➡ Lua and Python do not match exactly, need conversion
➡ data transferred between Lua and Python by value
➡ tables are copied deeply
➡ tensors share data but not metadata
➡ opaque references allow user to
Torch7 Torch at Facebook
‣ fb.python
➡ Example
➡ ‘[===[‘ multiline string syntax (python is sensitive to identation)
➡ values converted automatically between Python and Lua
➡ py.eval creates a local Python environment
➡ with value ‘a’ of type ‘Python float’
➡ return value of type ‘Python float’ is converted to ‘Lua int’
➡ Python to Lua and Lua to Python have specific conversion rules
➡ When existing conversion rules are insufficient, opaque references can be used
01 py.exec([=[
02 import numpy as np
03 def foo(x):
04 return x + 1
05 ]=])
06
07 print(py.eval('foo(a) + 10'), {a = 42}) -- prints 53
Torch7 Torch at Facebook
‣ fb.python
➡ opaque references encapsulate any Python object
➡ used in place of Lua values to pass arguments to Python
➡ opaque references support function calls, lookup, arithmetic operations
➡ operations on opaque references always return opaque references
➡ so chaining is possible transparently
➡ need py.eval at the end of an operation chain to convert back to Lua