Torch学习笔记

Torch笔记 (四)DNN训练方法

神经网络训练在torch中是比较固定的模式,在torch中都比较简单,torch就好像一个计算机硬件供应商,已经生产好了CPU、显卡、内存条、硬盘等等核心部件,咱们使用torch就是在组装电脑,按照不同的需求组装不同的电脑,不用自己造轮子,组装起来就快的多了,降低使用门槛,让大家都来玩玩现在红的发紫的深度学习。
言归正传,训练方法常用的有两种,一种是使用for循环手动训练,另外一种是使用optim包进行训练。
这里以简单的异或问题为例说明,例子太简单了,不过重点在训练流程上面。

-- 创建网络
require "nn"
mlp = nn.Sequential(); 
inputs = 2; outputs = 1; hiddens = 20;
mlp:add(nn.Linear(inputs, hiddens ))
mlp:add(nn.Tanh())
mlp:add(nn.Linear(hiddens , outputs))

-- 定义损失函数
criterion = nn.MSECriterion()

-- 开始训练
for i = 1,2500 do
  -- random sample
  local input= torch.randn(2);    
  local output= torch.Tensor(1);
  if input[1]*input[2] > 0 then 
    output[1] = -1
  else
    output[1] = 1
  end

  -- 前向过程
  criterion:forward(mlp:forward(input), output)

  -- 这里一般是固定的三步
  -- (1) 梯度清零,不然会累加
  mlp:zeroGradParameters()
  -- (2) 计算各梯度
  mlp:backward(input, criterion:backward(mlp.output, output))
  -- (3) 以学习率为0.01的速率来更新参数
  mlp:updateParameters(0.01)
end

-- 简单测试
x = torch.Tensor(2)
x[1] =  0.5; x[2] =  0.5; print(mlp:forward(x))
x[1] =  0.5; x[2] = -0.5; print(mlp:forward(x))
x[1] = -0.5; x[2] =  0.5; print(mlp:forward(x))
x[1] = -0.5; x[2] = -0.5; print(mlp:forward(x))

-- 结果
> x = torch.Tensor(2)
> x[1] =  0.5; x[2] =  0.5; print(mlp:forward(x))
-0.6140
[torch.Tensor of dimension 1]
> x[1] =  0.5; x[2] = -0.5; print(mlp:forward(x))
 0.8878
[torch.Tensor of dimension 1]
> x[1] = -0.5; x[2] =  0.5; print(mlp:forward(x))
 0.8548
[torch.Tensor of dimension 1]
> x[1] = -0.5; x[2] = -0.5; print(mlp:forward(x))
-0.5498
[torch.Tensor of dimension 1]

另外一种使用optim包来训练

-- 创建网络
require "nn"
mlp = nn.Sequential(); 
inputs = 2; outputs = 1; hiddens = 20;
mlp:add(nn.Linear(inputs, hiddens ))
mlp:add(nn.Tanh())
mlp:add(nn.Linear(hiddens , outputs))

-- 定义损失函数
criterion = nn.MSECriterion()

-- 数据准备
-- 当数据量很大时,需要分成多个batchsize来进行训练
local batchSize = 128
local batchInputs = torch.Tensor(batchSize, inputs)
local batchLabels = torch.DoubleTensor(batchSize)

for i=1,batchSize do
  local input = torch.randn(2)   
  local label = 1
  if input[1]*input[2]>0 then   
    label = -1;
  end
  batchInputs[i]:copy(input)
  batchLabels[i] = label
end

-- 训练
-- 这里使用sgd训练,还可以用lbfgs、adadelta、adagrad、adam、adamax、FistaLS、rprop、cmaes等很多优化算法
-- 使用这些算法时,形式基本都是一样的,以sgd为例,sgd(opfunc, x[, config][, state]) opfunc是只含有一个输入
-- 参数x的函数,返回f(X) and和df/dX。config是包含算法的参数配置的table,有config.learningRate即学习率,
-- config.learningRateDecay学习衰减,config.weightDecay权重衰减,config.weightDecays多个权重的衰减,
-- config.momentum是算法中的动量,config.dampening是dampening 动量,config.nesterov是Nesterov 动量,
-- state包含算法状态的table,当然这么多参数不一定全用,根据实际来选取使用。

-- 设置算法参数
local optimState = {learningRate=0.01}

require 'optim'

for epoch=1,50 do
  local function feval(params)
    gradParams:zero()

    local outputs = model:forward(batchInputs)
    local loss = criterion:forward(outputs, batchLabels)
    local dloss_doutput = criterion:backward(outputs, batchLabels)
    model:backward(batchInputs, dloss_doutput)

    return loss,gradParams
  end
  optim.sgd(feval, params, optimState)
end

-- 测试
x = torch.Tensor(2)
x[1] =  0.5; x[2] =  0.5; print(model:forward(x))
x[1] =  0.5; x[2] = -0.5; print(model:forward(x))
x[1] = -0.5; x[2] =  0.5; print(model:forward(x))
x[1] = -0.5; x[2] = -0.5; print(model:forward(x))

-- 结果
> x = torch.Tensor(2)
> x[1] =  0.5; x[2] =  0.5; print(model:forward(x))
-0.3490
[torch.Tensor of dimension 1]
> x[1] =  0.5; x[2] = -0.5; print(model:forward(x))
 1.0561
[torch.Tensor of dimension 1]
> x[1] = -0.5; x[2] =  0.5; print(model:forward(x))
 0.8640
[torch.Tensor of dimension 1]
> x[1] = -0.5; x[2] = -0.5; print(model:forward(x))
-0.2941
[torch.Tensor of dimension 1]

下一次将介绍用DNN实现多分类

你可能感兴趣的:(机器学习,深度学习,torch,神经网络)