Torch是一个广泛支持机器学习算法的科学计算框架。易于使用且高效,主要得益于一个简单的和快速的脚本语言LuaJIT,和底层的C / CUDA实现。
核心特征的总结:
1. 一个强大的n维数组
2. 很多实现索引,切片,移调transposing的例程
3. 惊人的通过LuaJIT的C接口
4. 线性代数例程
5. 神经网络,并基于能量的模型
6. 数值优化例程
7. 快速高效的GPU支持
8. 可嵌入,可移植到iOS,Android和FPGA的后台
Torch目标是让你通过极其简单过程、最大的灵活性和速度建立自己的科学算法。Torch有一个在机器学习领域大型生态社区驱动库包,包括计算机视觉软件包,信号处理,并行处理,图像,视频,音频和网络等,基于Lua社区建立。Torch被Facebook人工智能研究实验室和位于伦敦的谷歌DeepMind大量使用。
我最近在学习torch,在学习的过程中,把学习的内容,总结为博客,在方便自己的同时,也能够分享给真正喜欢编程,喜欢计算机视觉的同行。
Tensor 介绍
Tensor是Torch中最基础的类,是网络基本的数据单元。在Torch7中,一个Tensor可以是任意维度的,维度数目可以通过LongStorage来设定,可以通过dim()或者nDimension()方法获取Tensor的维度,可以用size()获取所有的维度。例如:
x=torch.Tensor(1,2,3,2)
s=torch.LongStorage(5)
s[1] = 2 s[2] =2
s[3] = 2 s[4] = 4 s[5] = 1
print(x:nDimension()) # 5
x:size()
2
2
2
4
1
[torch.LongStorage of size 5]
在CNN网络中,Tensor一般来说是一个四维的数组,分别是batchSize, channel,width,height。在Torch中,数组的下标从1开始,到size()结束,这点和c/c++/java这些语言不同。访问Tensor的内容,可以直接使用下标的方式,或者使用Storage()函数。storage是Torch的一种访问内存的基本方式,有点类似C语言的数据类型。相关细节,参考文档here。
以一个三维的Tensor为例:
th> x = torch.Tensor(5,5,5)
[0.0001s]
th> x[3][4][5]
2.1723719562371e-153
[0.0001s]
th> x:storage()[x:storageOffset()+(3-1)*x:stride(1)+(4-1)*x:stride(2)+(5-1)*x:stride(3)]
2.1723719562371e-153
storageOffset返回Tensor第一个位置(1),stride(i)返回第i维的长度。第二种方式,可以这样理解,storage()操作以后,在内存中本质是一维的数组结构,用相对于第一个位置的偏置,进行访问。*注意的是,在Tensor中同一行的元素总是连续的。*Tensor构造函数是不进行初始化值的,需要手动初始化。
th> x=torch.Tensor(4,5) [0.0001s]
th> i = 0 [0.0000s]
th> x:apply(function()
..> i=i+1
..> return i
..> end)
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
[torch.DoubleTensor of size 4x5] [0.0230s]
th> x
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
[torch.DoubleTensor of size 4x5] [0.0002s]
th> x:stride()
5
1
[torch.LongStorage of size 2]
Torch中,Tensor主要有ByteTensor(无符号char),CharTensor(有符号),ShortTensor(shorts), IntTensor(ints), LongTensor(longs), FloatTensor(floats), DoubleTensor(doubles),默认存放为double类型,如果需要特别指出,通过torch.setdefaulttensortype()方法进行设定。例如torch.setdefaulttensortype(‘torch.FloatTensor’)。
在Torch中,所有的Tensor都共享同一个变量的内存,也就是说所有的操作都是在同一块内存上操作,这样的好处就是减少了内存复制所需要的时间,提高了运行速度,缺点也很明显,就是同一块内存的数据不能够持久,如果需要内存复制,可以使用copy()或者clone()方法。从下面的例子,可以看出这点:
th> x=torch.Tensor(2,2)
[0.0001s]
th> i = 0
[0.0000s]
th> x:apply(function()
..> i = i+1
..> return i
..> end)
1 2
3 4
[torch.DoubleTensor of size 2x2]
[0.0002s]
th> y = torch.Tensor(x)
[0.0001s]
th> y
1 2
3 4
[torch.DoubleTensor of size 2x2]
[0.0002s]
th> y:zero()
0 0
0 0
[torch.DoubleTensor of size 2x2]
[0.0202s]
th> x
0 0
0 0
[torch.DoubleTensor of size 2x2]
Tensor 基本函数
构造函数
Tensor构造函数,创建新的tensor,分配内存,但是不进行初始化值,tensor的值是随机产生的。Tensor主要有以下几种构造函数:
- torch.Tensor() 空构造函数
- torch.Tensor(tensor) 拷贝构造函数,但是这里共享了同一块内存。
- torch.Tensor(sz1[,sz2[, sz3[, sz4]]]]) 创建4维的Tensor
- torch.Tensor(sizes,[strides]) 使用longStorage方法创建任意维度的Tensor 。x=torch.Tensor(torch.LongStorage({4,4,3,2}))
- torch.Tensor(table) torch.Tensor({ {1,2,3,4}, {5,6,7,8}})。
- torch.Tensor(storage, [storageOffset, sizes, [strides]])
t