itorch无监督聚类

cmd = torch.CmdLine()
cmd:text()

cmd:text()用来在terminal上显示运行信息

cmd:option(‘-dir‘, ‘outputs‘, ‘subdirectory to save experiments in‘)

cmd:option用来接受运行时的参数,第一个是参数名称,第二个是默认输入参数,第三个是备注。

1. 处理数据:

dofile ‘1_data.lua‘

dofile和require的功能差不多,不过require不会重新加载,dofile会,于是能够实现动态更新。

require只需要模块名,而dofile由于能动态更新一个模块,所以需要指定路径。

本例之中的数据是以ascii格式的文件。

由于1_data.lua只是简单的对数据进行处理,分块,所以没有写运行函数,所以在dofile之后,还需要调用之中的函数。

filename = paths.basename(params.datafile)
if not paths.filep(filename) then
   os.execute(‘wget ‘ .. params.datafile)
end
dataset = getdata(filename, params.inputsize)

if params.display then
   displayData(dataset, 100, 10, 2)
end

2:建立模型(无监督聚类的精华)

模型的类型可以进行选择,在参数设置时可以调:

已经提供了几种模型进行选择:

auto-encoder class: linear | linear-psd | conv | conv-psd

这之中使用的无监督聚类,就是使用的autoencoding方法。

autoencoding是一个self-training方法。

比较编码前后数据的相似度,降低数据的维度,但是并没有对原有的数据进行分析处理。

(encoder只是网络的名字而已,不要想太多)

encoder = nn.Sequential()
   encoder:add(nn.Linear(inputSize,outputSize))
   encoder:add(nn.Tanh())
   encoder:add(nn.Diag(outputSize))

还有解码层:

decoder = nn.Sequential()
   decoder:add(nn.Linear(outputSize,inputSize))

整合两个网络:(一直不知道如何整合两个网络,打开了思路,不过实在不知道为什么autoencoder需要写成两个网络?)

unsup.AutoEncoder(encoder, decoder, params.beta)

然后把autoencoder源代码,如下:

local AutoEncoder = torch.class(‘unsup.AutoEncoder‘,‘unsup.UnsupModule‘)

function AutoEncoder:__init(encoder, decoder, beta, loss, lambda, codeloss)--初始化
   self.encoder = encoder
   self.decoder = decoder
   self.beta = beta
   if loss then
      self.loss = loss
   else
      self.loss = nn.MSECriterion()
      self.loss.sizeAverage = false
   end
   if lambda and codeloss then
      self.codecost = codeloss
      self.lambda = lambda
   end
end

function AutoEncoder:parameters()
   local seq = nn.Sequential()
   seq:add(self.encoder)
   seq:add(self.decoder)
   return seq:parameters()
end

function AutoEncoder:initDiagHessianParameters()
   self.encoder:initDiagHessianParameters()
   self.decoder:initDiagHessianParameters()
end

function AutoEncoder:reset(stdv)
   self.decoder:reset(stdv)
   self.encoder:reset(stdv)
end

function AutoEncoder:updateOutput(input,target)
   self.encoder:updateOutput(input)
   self.decoder:updateOutput(self.encoder.output)
   self.output = self.beta * self.loss:updateOutput(self.decoder.output, target)
   if self.lambda then
      self.output = self.output + self.lambda * self.codecost(self.encoder.output)
   end
   return self.output
end

function AutoEncoder:updateGradInput(input,target)
   self.loss:updateGradInput(self.decoder.output, target)
   self.loss.gradInput:mul(self.beta)

   if self.lambda then
      self.codecost:updateGradInput(self.encoder.output)
      self.codecost.gradInput:mul(self.lambda)
   end

   self.decoder:updateGradInput(self.encoder.output, self.loss.gradInput)

   -- accumulate gradients from code cost
   if self.lambda then
      self.decoder.gradInput:add(self.codecost.gradInput)
   end

   self.encoder:updateGradInput(input, self.decoder.gradInput)
   self.gradInput = self.encoder.gradInput
   return self.gradInput
end

function AutoEncoder:accGradParameters(input,target)
   self.decoder:accGradParameters(self.encoder.output, self.loss.gradInput)
   self.encoder:accGradParameters(input, self.decoder.gradInput)
end

function AutoEncoder:zeroGradParameters()
   self.encoder:zeroGradParameters()
   self.decoder:zeroGradParameters()
end

function AutoEncoder:updateDiagHessianInput(input, diagHessianOutput)
   self.loss:updateDiagHessianInput(self.decoder.output, target)
   self.loss.diagHessianInput:mul(self.beta)

   if self.lambda then
      self.codecost:updateDiagHessianInput(self.encoder.output)
      self.codecost.diagHessianInput:mul(self.lambda)
   end

   self.decoder:updateDiagHessianInput(self.encoder.output, self.loss.diagHessianInput)

   -- accumulate gradients from code cost
   if self.lambda then
      self.decoder.diagHessianInput:add(self.codecost.diagHessianInput)
   end

   self.encoder:updateDiagHessianInput(input, self.decoder.diagHessianInput)

   self.diagHessianInput = self.encoder.diagHessianInput
   return self.diagHessianInput
end

function AutoEncoder:accDiagHessianParameters(input, diagHessianOutput)
   self.decoder:accDiagHessianParameters(self.encoder.output, self.loss.diagHessianInput)
   self.encoder:accDiagHessianParameters(input, self.decoder.diagHessianInput)
end

function AutoEncoder:updateParameters(learningRate)
   local eta = {}
   if type(learningRate) ~= ‘number‘ then
      eta = learningRate
   else
      eta[1] = learningRate
      eta[2] = learningRate
   end
   self.encoder:updateParameters(eta[1])
   self.decoder:updateParameters(eta[2])
end

function AutoEncoder:normalize()
   if not self.normalized then return end
   -- normalize the dictionary
   local w = self.decoder.weight
   if not w or w:dim() < 2 then return end

   if w:dim() == 5 then
      for i=1,w:size(1) do
         local keri = w:select(1,i)
         for j=1,w:size(2) do
            local kerj = keri:select(1,j)
            for k=1,w:size(3) do
               local ker = kerj:select(1,k)
               ker:div(ker:norm()+1e-12)
            end
         end
      end
   elseif w:dim() == 4 then
      for i=1,w:size(1) do
         for j=1,w:size(2) do
            local k=w:select(1,i):select(1,j)
            k:div(k:norm()+1e-12)
         end
      end
   elseif w:dim() == 3 then
      for i=1,w:size(1) do
         local k=w:select(1,i)
         k:div(k:norm()+1e-12)
      end
   elseif w:dim() == 2 then
      for i=1,w:size(2) do
         local k=w:select(2,i)
         k:div(k:norm()+1e-12)
      end
   else
      error(‘I do not know what kind of weight matrix this is‘)
   end

end

3:训练模型

使用刚才弄出来的model来进行训练。

初始化:(调用unsup中的函数)

initDiagHessianParameters

autoencoder的参数在作者之中变为了hessian矩阵

更新网络:

module:updateGradInput(input, target)
         module:accGradParameters(input, target)

更新hessian矩阵:

-- hessian
         ddl_ddx:zero()
         module:updateDiagHessianInput(input, target)
         module:accDiagHessianParameters(input, target)

updategradinput函数:

两个网络分别进行迭代

function AutoEncoder:updateGradInput(input,target)
   self.loss:updateGradInput(self.decoder.output, target)
   self.loss.gradInput:mul(self.beta)

   if self.lambda then
      self.codecost:updateGradInput(self.encoder.output)
      self.codecost.gradInput:mul(self.lambda)
   end

   self.decoder:updateGradInput(self.encoder.output, self.loss.gradInput)

   -- accumulate gradients from code cost
   if self.lambda then
      self.decoder.gradInput:add(self.codecost.gradInput)
   end

   self.encoder:updateGradInput(input, self.decoder.gradInput)
   self.gradInput = self.encoder.gradInput
   return self.gradInput
end

accGradParameters函数:

function AutoEncoder:accGradParameters(input,target)
   self.decoder:accGradParameters(self.encoder.output, self.loss.gradInput)
   self.encoder:accGradParameters(input, self.decoder.gradInput)
end

updateDiagHessianInput函数:

function AutoEncoder:updateDiagHessianInput(input, diagHessianOutput)
   self.loss:updateDiagHessianInput(self.decoder.output, target)
   self.loss.diagHessianInput:mul(self.beta)

   if self.lambda then
      self.codecost:updateDiagHessianInput(self.encoder.output)
      self.codecost.diagHessianInput:mul(self.lambda)
   end

   self.decoder:updateDiagHessianInput(self.encoder.output, self.loss.diagHessianInput)

   -- accumulate gradients from code cost
   if self.lambda then
      self.decoder.diagHessianInput:add(self.codecost.diagHessianInput)
   end

   self.encoder:updateDiagHessianInput(input, self.decoder.diagHessianInput)

   self.diagHessianInput = self.encoder.diagHessianInput
   return self.diagHessianInput
end

accDiagHessianParameters函数:

function AutoEncoder:accDiagHessianParameters(input, diagHessianOutput)
   self.decoder:accDiagHessianParameters(self.encoder.output, self.loss.diagHessianInput)
   self.encoder:accDiagHessianParameters(input, self.decoder.diagHessianInput)
end

train中整合decoder和encoder的hessian矩阵:

ddl_ddx_avg:add(1/hessiansamples, ddl_ddx)

由于神经网络训练优化迭代速度的方法就是把训练块减小:(分块多步)

   local example = dataset[t]
   local inputs = {}
   local targets = {}
   for i = t,t+params.batchsize-1 do
      -- load new sample
      local sample = dataset[i]
      local input = sample[1]:clone()
      local target = sample[2]:clone()
      table.insert(inputs, input)
      table.insert(targets, target)
   end

计算每块的f和dx,loss函数自己定义

   local feval = function()
      -- reset gradient/f
      local f = 0
      dl_dx:zero()

      -- estimate f and gradients, for minibatch
      for i = 1,#inputs do
         -- f
         f = f + module:updateOutput(inputs[i], targets[i])

         -- gradients
         module:updateGradInput(inputs[i], targets[i])
         module:accGradParameters(inputs[i], targets[i])
      end

      -- normalize
      dl_dx:div(#inputs)
      f = f/#inputs

      -- return f and df/dx
      return f,dl_dx
   end

使用sgd来计算梯度:

   sgdconf = sgdconf or {learningRate = params.eta,
                         learningRateDecay = params.etadecay,
                         learningRates = etas,
                         momentum = params.momentum}
   _,fs = optim.sgd(feval, x, sgdconf)
   err = err + fs[1]*params.batchsize -- so that err is indep of batch size

均值化参数:

   -- normalize
   if params.model:find(‘psd‘) then
      module:normalize()
   end

normalize函数:

function AutoEncoder:normalize()
   if not self.normalized then return end
   -- normalize the dictionary
   local w = self.decoder.weight
   if not w or w:dim() < 2 then return end

   if w:dim() == 5 then
      for i=1,w:size(1) do
         local keri = w:select(1,i)
         for j=1,w:size(2) do
            local kerj = keri:select(1,j)
            for k=1,w:size(3) do
               local ker = kerj:select(1,k)
               ker:div(ker:norm()+1e-12)
            end
         end
      end
   elseif w:dim() == 4 then
      for i=1,w:size(1) do
         for j=1,w:size(2) do
            local k=w:select(1,i):select(1,j)
            k:div(k:norm()+1e-12)
         end
      end
   elseif w:dim() == 3 then
      for i=1,w:size(1) do
         local k=w:select(1,i)
         k:div(k:norm()+1e-12)
      end
   elseif w:dim() == 2 then
      for i=1,w:size(2) do
         local k=w:select(2,i)
         k:div(k:norm()+1e-12)
      end
   else
      error(‘I do not know what kind of weight matrix this is‘)
   end

end

然后就是显示err

 if iter*params.batchsize >= params.statinterval then

最后保存数据:

      dd = image.toDisplayTensor{input=dweight,
                                 padding=2,
                                 nrow=math.floor(math.sqrt(params.nfiltersout)),
                                 symmetric=true}
      de = image.toDisplayTensor{input=eweight,
                                 padding=2,
                                 nrow=math.floor(math.sqrt(params.nfiltersout)),
                                 symmetric=true}

贴上autoencoder的代码:

local AutoEncoder = torch.class(‘unsup.AutoEncoder‘,‘unsup.UnsupModule‘)

function AutoEncoder:__init(encoder, decoder, beta, loss, lambda, codeloss)
   self.encoder = encoder
   self.decoder = decoder
   self.beta = beta
   if loss then
      self.loss = loss
   else
      self.loss = nn.MSECriterion()
      self.loss.sizeAverage = false
   end
   if lambda and codeloss then
      self.codecost = codeloss
      self.lambda = lambda
   end
end

function AutoEncoder:parameters()
   local seq = nn.Sequential()
   seq:add(self.encoder)
   seq:add(self.decoder)
   return seq:parameters()
end

function AutoEncoder:initDiagHessianParameters()
   self.encoder:initDiagHessianParameters()
   self.decoder:initDiagHessianParameters()
end

function AutoEncoder:reset(stdv)
   self.decoder:reset(stdv)
   self.encoder:reset(stdv)
end

function AutoEncoder:updateOutput(input,target)
   self.encoder:updateOutput(input)
   self.decoder:updateOutput(self.encoder.output)
   self.output = self.beta * self.loss:updateOutput(self.decoder.output, target)
   if self.lambda then
      self.output = self.output + self.lambda * self.codecost(self.encoder.output)
   end
   return self.output
end

function AutoEncoder:updateGradInput(input,target)
   self.loss:updateGradInput(self.decoder.output, target)
   self.loss.gradInput:mul(self.beta)

   if self.lambda then
      self.codecost:updateGradInput(self.encoder.output)
      self.codecost.gradInput:mul(self.lambda)
   end

   self.decoder:updateGradInput(self.encoder.output, self.loss.gradInput)

   -- accumulate gradients from code cost
   if self.lambda then
      self.decoder.gradInput:add(self.codecost.gradInput)
   end

   self.encoder:updateGradInput(input, self.decoder.gradInput)
   self.gradInput = self.encoder.gradInput
   return self.gradInput
end

function AutoEncoder:accGradParameters(input,target)
   self.decoder:accGradParameters(self.encoder.output, self.loss.gradInput)
   self.encoder:accGradParameters(input, self.decoder.gradInput)
end

function AutoEncoder:zeroGradParameters()
   self.encoder:zeroGradParameters()
   self.decoder:zeroGradParameters()
end

function AutoEncoder:updateDiagHessianInput(input, diagHessianOutput)
   self.loss:updateDiagHessianInput(self.decoder.output, target)
   self.loss.diagHessianInput:mul(self.beta)

   if self.lambda then
      self.codecost:updateDiagHessianInput(self.encoder.output)
      self.codecost.diagHessianInput:mul(self.lambda)
   end

   self.decoder:updateDiagHessianInput(self.encoder.output, self.loss.diagHessianInput)

   -- accumulate gradients from code cost
   if self.lambda then
      self.decoder.diagHessianInput:add(self.codecost.diagHessianInput)
   end

   self.encoder:updateDiagHessianInput(input, self.decoder.diagHessianInput)

   self.diagHessianInput = self.encoder.diagHessianInput
   return self.diagHessianInput
end

function AutoEncoder:accDiagHessianParameters(input, diagHessianOutput)
   self.decoder:accDiagHessianParameters(self.encoder.output, self.loss.diagHessianInput)
   self.encoder:accDiagHessianParameters(input, self.decoder.diagHessianInput)
end

function AutoEncoder:updateParameters(learningRate)
   local eta = {}
   if type(learningRate) ~= ‘number‘ then
      eta = learningRate
   else
      eta[1] = learningRate
      eta[2] = learningRate
   end
   self.encoder:updateParameters(eta[1])
   self.decoder:updateParameters(eta[2])
end

function AutoEncoder:normalize()
   if not self.normalized then return end
   -- normalize the dictionary
   local w = self.decoder.weight
   if not w or w:dim() < 2 then return end

   if w:dim() == 5 then
      for i=1,w:size(1) do
         local keri = w:select(1,i)
         for j=1,w:size(2) do
            local kerj = keri:select(1,j)
            for k=1,w:size(3) do
               local ker = kerj:select(1,k)
               ker:div(ker:norm()+1e-12)
            end
         end
      end
   elseif w:dim() == 4 then
      for i=1,w:size(1) do
         for j=1,w:size(2) do
            local k=w:select(1,i):select(1,j)
            k:div(k:norm()+1e-12)
         end
      end
   elseif w:dim() == 3 then
      for i=1,w:size(1) do
         local k=w:select(1,i)
         k:div(k:norm()+1e-12)
      end
   elseif w:dim() == 2 then
      for i=1,w:size(2) do
         local k=w:select(2,i)
         k:div(k:norm()+1e-12)
      end
   else
      error(‘I do not know what kind of weight matrix this is‘)
   end

end
时间: 2025-01-04 11:40:50

itorch无监督聚类的相关文章

【转-知乎】有监督 无监督 标签的解释,对我自己而言,比较容易懂(收藏)

作者:赵杨链接:https://www.zhihu.com/question/23194489/answer/75555668来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 机器(计算机)学习分为有监督和无监督两个类,基本上可以从他们会不会得到一个特定的标签(label)输出来区分.这里标签指的是用来描述某一个物体属性的话语.比如人类有两种,我们要区分这两种人,就根据生理特征,分别对两种人打上标签,一种是[男人],另一种是[女人].有监督学习(Supervised

深度学习之无监督训练

最近看了一下深度学习的表征学习,总结并记录与一下学习笔记. 1.在标签数据集中做的监督学习容易导致过拟合,半监督学习由于可以从无标签数据集中学习,可以有一定概率化解这种情况. 2.深度学习所使用的算法不能太复杂,否则会加大计算复杂度和工作量. 3.逐层贪婪的无监督预训练有这几个特点: (1)贪婪:基于贪婪算法,独立优化问题解的各方面,但是每次只优化一个方面,而不是同时同步全局优化. (2)逐层:各个独立方面可以看做网络的每一层,每次训练的第i层,都会固定前面的所有层. (3)无监督:每次训练都是

无监督算法

无监督算法: KMeans算法: 1. 随机初始化数据集簇的中心,一般从数据集中选择 2. 外循环: 内循环:计算各个数值点到中心的距离,进行聚类 计算每个聚类的平局值,移动聚类中心 PCA算法: 目标:数据压缩和可视化 1. 对样本数据进行去均值和归一化 2. 组建sigma矩阵,然后进行奇异值分解,求的压缩和的结果Z 异常检测算法: 1. 选择可能适应于异常样本的特征 2. 根据样本得到高斯分布的均值和方差 3. 对给定的样本计算其是否为异常样本 异常检测与监督学习: 异常检测:正样本数量较

【转载】 无监督特征学习——Unsupervised feature learning and deep learning

无监督特征学习——Unsupervised feature learning and deep learning 分类: Compression Computer Vision Machine Learning 杂感2012-07-31 15:48 36848人阅读 评论(61) 收藏 举报 目录(?)[+] 无监督学习近年来很热,先后应用于computer vision, audio classification和 NLP等问题,通过机器进行无监督学习feature得到的结果,其accurac

转:Deep learning系列(十五)有监督和无监督训练

http://m.blog.csdn.net/article/details?id=49591213 1. 前言 在学习深度学习的过程中,主要参考了四份资料: 台湾大学的机器学习技法公开课: Andrew NG的深度学习教程: Li feifei的CNN教程: caffe官网的教程: 对比过这几份资料,突然间产生一个困惑:台大和Andrew的教程中用了很大的篇幅介绍了无监督的自编码神经网络,但在Li feifei的教程和caffe的实现中几乎没有涉及.当时一直搞不清这种现象的原因,直到翻阅了深度

极大似然估计(Maximum Likelihood)与无监督

1. 极大似然与最大概率 因为不是科班出身,所以最初接触极大似然的时候,总是很奇怪为什么叫极大似然,而不直接叫做最大概率? 后来才知道极大似然是用来估计未知参数的,而最大概率的表述更适合于已知参数的情况下,求解出现最大概率的变量的,举例如下: Max L(θ) = θ1x1+θ2x2+θ3x3 Max P(x) = θ1x1+θ2x2+θ3x3 Max L(θ)是拥有多组观测样本X时,估计θ参数的方法,而Max P(x)正好相反,是已知θ时,求解什么样的x出现会使得P最大. 2.  极大似然与无

有监督和无监督的特征选择方法

特征选择实质上包括两个部分:特征词的选择和特征词权重的计算. 特征词选择的方法分为有监督的方法和无监督的方法. 有监督的方法包括IG和CHI,无监督的方法包括Document   Frequency (DF),  Term  Strength  (TS)和 Entropy-based  (En). 可以参考https://www.aaai.org/Papers/ICML/2003/ICML03-065.pdf

【转】有监督训练 &amp; 无监督训练

原文链接:http://m.blog.csdn.net/article/details?id=49591213 1. 前言 在学习深度学习的过程中,主要参考了四份资料: 台湾大学的机器学习技法公开课: Andrew NG的深度学习教程: Li feifei的CNN教程: caffe官网的教程: 对比过这几份资料,突然间产生一个困惑:台大和Andrew的教程中用了很大的篇幅介绍了无监督的自编码神经网络,但在Li feifei的教程和caffe的实现中几乎没有涉及.当时一直搞不清这种现象的原因,直到

【Machine Translation】无监督神经机器翻译论述

Unsupervised NMT 概述 神经机器翻译系统取得了很好的翻译水平,但非常依赖于平行语料.目前已经有利用大量单语数据训练模型的研究,这其中包括: 仅仅由两份单语语料(不平行)训练出双语词典.这个的核心是学习一个旋转矩阵W,使得两份语料的词向量空间对齐,再进行一些调整更好的对齐两词向量空间,最后进行单词到单词的翻译,即生成了双语词典. 对偶学习的思想.有些研究里也提出迭代后向翻译,但思想是类似的,即通过翻译模型生成假的平行语料,再利用该平行语料训练模型,迭代此过程. 利用第三种语言.翻译