续集写作缘由
好吧,无语了,又开始写Torch7了。前面写的Torch入门,貌似都没什么人看,可能是该框架用的还是比较小众,应该大部分人用Caffe,Tensorflow, mxnet之类了吧。无所谓了,主要是貌似我研究的方向作者的代码基本上还是Torch啊,没法子。那我为什么要写续集呢?主要是发现以前写的Torch7学入门专栏还是基本的,入门可能够了,一些技巧和强大的函数,记录一下,总有好处。
续集写作原则
这里只写出我认为常见的重要的东西,有一些会和以前写的有重复,不过无所谓了。有一些默认大家都知道了,也就不怎么提。简单一句话,只写我认为该写的!
续集写作目的
- 更加好的掌握Torch已有的强大函数
续集教程指的是除了基本的使用方式外,如何能使用内置的函数完成更多的任务,这才是这篇系列写作的原因。举个栗子,比如我要在一个Tensor加入padding,并且是“对称型”的padding,然后再进行其他操作。然后自己写了个函数,这里默认输入的是三维的Tensor
function ex_tensor(input, pad, method)
-- mirror and zero
assert((pad-1)%2 == 0, 'pad should be odd number!')
local padding = (pad-1)/2
local method = method or 'mirror'
local k = input:size()
local output = torch.Tensor(k[1], k[2]+padding*2, k[3]+padding*2):typeAs(input):zero()
output[{
{},{padding+1, -padding-1},{padding+1, -padding-1}}] = input:clone()
if method == 'mirror' then
for i = 1, padding do
output[{
{},{i},{padding+1, -padding-1}}] = output[{
{},{padding*2+1-i},{padding+1, -padding-1}}] -- up
output[{
{},{-i},{padding+1, -padding-1}}] = output[{
{},{-padding*2-1+i},{padding+1, -padding-1}}] --down
output[{
{},{padding+1, -padding-1},{i}}] = output[{
{},{padding+1, -padding-1},{padding*2+1-i}}] --left
output[{
{},{padding+1, -padding-1},{-i}}] = output[{
{},{padding+1, -padding-1},{-padding*2-1+i}}] --right
end
for i = 1, padding do
output[{
{},{
1, padding},{i}}] = output[{
{},{
1, padding},{padding*2+1-i}}] --left_up
output[{
{},{-padding,-1},{i}}] = output[{
{},{-padding,-1},{padding*2+1-i}}] --left_down
output[{
{},{
1, padding},{-i}}] = output[{
{},{
1, padding},{-padding*2-1+i}}] --right_up
output[{
{},{-padding,-1},{-i}}] = output[{
{},{-padding, -1},{-padding*2-1+i}}] --right_down
end
else
-- done
end
return output
end
是不是感觉很麻烦。。后来才发现Torch内部 nn.SpatialReplicationPadding 就可以完成这个任务。知道真相的我眼泪掉下来。。
2. 学习他人写torch的技巧
随时记录一些好的技巧,可能以后会用到。
3. 读N遍文档
这个很重要!这个也是续集的重点,着重读重要的文档!
再探Tensor
Tensor的内部存储
Tensor的同一维度的每个元素之间的步长是一样的,第i个维度的步长为stride(i)。Tensor的首地址可以用storageOffset()来获得。因此:
x = torch.Tensor(4,5)
s = x:storage()
for i=1,s:size() do -- fill up the Storage
s[i] = i
end
> x -- s is interpreted by x as a 2D matrix
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
[torch.DoubleTensor of dimension 4x5]
由于stride(i)不为1时,该Tensor的内存空间就是不连续的。但是最后一个维度是连续的。
x = torch.Tensor(4,5)
i = 0
x:apply(function()