深度学习:自动编码器基础和类型

域名2025-11-05 13:44:416293

很显然,深度深度学习即将对我们的学习社会产生重大显著的影响。Mobibit 创始人兼 CEO Pramod Chandrayan 近日在 codeburst.io 上发文对自动编码器的自动基础知识和类型进行了介绍并给出了代码实例。

继续我之前的编码文章《深度学习:什么&为什么?》(https://goo.gl/Ka3YoF),今天我们将进一步了解深度学习的器基架构类型,并详细讨论自动编码器。础和

当人类大脑与深度学习机器合作时:

在我们开始揭秘深度网络之前,类型让我们先定义一下深度学习。深度根据我的学习理解:

深度学习是一种先进的机器学习技术,其中存在多个彼此通信的自动抽象层,每一层都与前一层深度相连,编码并根据前一层馈送的器基输出进行决策。

Investopedia 将深度学习定义成:

深度学习是础和人工智能(AI)领域中机器学习中的一个子集,其有网络状的类型结构,可以从非结构化或无标记的深度数据中以无监督的方式学习。也被称为深度神经学习或深度神经网络。

今天我们将深入解读无监督预训练网络(Unsupervised Pertained Networks)的工作方式。

UPN:无监督预训练网络

这种无监督学习网络可以进一步分类成

自动编码器 深度信念网络(DBN) 生成对抗网络(GAN)

自动编码器是免费源码下载一种有三层的神经网络:输入层、隐藏层(编码层)和解码层。该网络的目的是重构其输入,使其隐藏层学习到该输入的良好表征。

自动编码器神经网络是一种无监督机器学习算法,其应用了反向传播,可将目标值设置成与输入值相等。自动编码器的训练目标是将输入复制到输出。在内部,它有一个描述用于表征其输入的代码的隐藏层。

自动编码器的目标是学习函数 h(x)≈x。换句话说,它要学习一个近似的恒等函数,使得输出 x^ 近似等于输入 x。自动编码器属于神经网络家族,但它们也和 PCA(主成分分析)紧密相关。

关于自动编码器的一些关键事实:

它是一种类似于 PCA 的无监督机器学习算法 它要最小化和 PCA 一样的源码库目标函数 它是一种神经网络 这种神经网络的目标输出就是其输入

尽管自动编码器与 PCA 很相似,但自动编码器比 PCA 灵活得多。在编码过程中,自动编码器既能表征线性变换,也能表征非线性变换;而 PCA 只能执行线性变换。因为自动编码器的网络表征形式,所以可将其作为层用于构建深度学习网络。

自动编码器的类型:

去噪自动编码器 稀疏自动编码器 变分自动编码器(VAE) 收缩自动编码器(CAE/contractive autoencoder)

A. 去噪自动编码器

这是最基本的一种自动编码器,它会随机地部分采用受损的输入来解决恒等函数风险,使得自动编码器必须进行恢复或去噪。

这项技术可用于得到输入的良好表征。良好的表征是指可以从受损的输入稳健地获得的表征,该表征可被用于恢复其对应的无噪声输入。

去噪自动编码器背后的思想很简单。为了迫使隐藏层发现更加稳健的特征并且为了防止其只是学习其中的恒等关系,服务器托管我们在训练自动编码器时会让其从受损的版本中重建输入。

应用在输入上的噪声量以百分比的形式呈现。一般来说,30% 或 0.3 就很好,但如果你的数据非常少,你可能就需要考虑增加更多噪声。

堆叠的去噪自动编码器(SDA):

这是一种在层上使用了无监督预训练机制的去噪自编码器,其中当一层被预训练用于在之前层的输入上执行特征选择和特征提取后,后面会跟上一个监督式的微调(fine-tuning)阶段。SDA 只是将很多个去噪自动编码器融合在了一起。一旦前面 k 层训练完成,我们就可以训练第 k+1 层,因为我们现在可以根据下面的层计算代码或隐含表征。

一旦所有层都预训练完成,网络就会进入一个被称为微调的阶段。在这里我们会为微调使用监督学习机制,以最小化被监督任务上的预测误差。然后,我们以训练多层感知器的方式训练整个网络。在这个阶段,我们仅考虑每个自动编码器的编码部分。这个阶段是有监督的,自此以后我们就在训练中使用目标类别了。

使用代码示例解释 SDA

这一节源自 deeplearning.net(对于想要理解深度学习的人来说,这个网站提供了很好的参考),其中使用案例对堆叠的去噪自动编码器进行了很好的解释。

我们可以以两种方式看待堆叠的去噪自动编码器:一是自动编码器列表,二是多层感知器(MLP)。在预训练过程中,我们使用了***种方式,即我们将我们的模型看作是一组自动编码器列表,并分开训练每个自动编码器。在第二个训练阶段,我们使用第二种方式。这两种方式是有联系的,因为:

自动编码器和 MLP 的 sigmoid 层共享参数;

MLP 的中间层计算出的隐含表征被用作自动编码器的输入。

class SdA(object):  """Stacked denoising auto-encoder class (SdA)  A stacked denoising autoencoder model is obtained by stacking several  dAs. The hidden layer of the dA at layer `i` becomes the input of  the dA at layer `i+1`. The first layer dA gets as input the input of  the SdA, and the hidden layer of the last dA represents the output.  Note that after pretraining, the SdA is dealt with as a normal MLP,  the dAs are only used to initialize the weights.  """ def __init__(  self,  numpy_rng,  theano_rng=None,  n_ins=784,  hidden_layers_sizes=[500, 500],  n_outs=10,  corruption_levels=[0.1, 0.1]  ):  """ This class is made to support a variable number of layers. :type numpy_rng: numpy.random.RandomState :param numpy_rng: numpy random number generator used to draw initial  weights  :type theano_rng: theano.tensor.shared_randomstreams.RandomStreams  :param theano_rng: Theano random generator; if None is given one is  generated based on a seed drawn from `rng`  :type n_ins: int :param n_ins: dimension of the input to the sdA  :type hidden_layers_sizes: list of ints  :param hidden_layers_sizes: intermediate layers size, must contain  at least one value  :type n_outs: int  :param n_outs: dimension of the output of the network  :type corruption_levels: list of float  :param corruption_levels: amount of corruption to use for each  layer  """  self.sigmoid_layers = [] self.dA_layers = []  self.params = []  self.n_layers = len(hidden_layers_sizes)  assert self.n_layers > 0 if not theano_rng: theano_rng = RandomStreams(numpy_rng.randint(2 ** 30))  # allocate symbolic variables for the data  self.x = T.matrix(x) # the data is presented as rasterized images  self.y = T.ivector(y) # the labels are presented as 1D vector of  # [int] labels 

self.sigmoid_layers 将会存储 MLP 形式的 sigmoid 层,而 self.dA_layers 将会存储与该 MLP 层关联的去噪自动编码器。接下来,我们构建 n_layers sigmoid 层和 n_layers 去噪自动编码器,其中 n_layers 是我们的模型的深度。我们使用了多层感知器中引入的 HiddenLayer 类,但有一项修改:我们将 tanh 非线性替换成了 logistic 函数

我们链接了 sigmoid 层来构建一个 MLP,而且我们在构建自动编码器时使得每个自动编码器的编码部分都与其对应的 sigmoid 层共享权重矩阵和偏置。

for i in range(self.n_layers):  # construct the sigmoidal layer  # the size of the input is either the number of hidden units of  # the layer below or the input size if we are on the first layer  if i == 0:  input_size = n_ins  else:  input_size = hidden_layers_sizes[i - 1]  # the input to this layer is either the activation of the hidden  # layer below or the input of the SdA if you are on the first  # layer  if i == 0:  layer_input = self.x  else:  layer_input = self.sigmoid_layers[-1].output  sigmoid_layer = HiddenLayer(rng=numpy_rng,  input=layer_input,  n_in=input_size,  n_out=hidden_layers_sizes[i],  activation=T.nnet.sigmoid)  # add the layer to our list of layers  self.sigmoid_layers.append(sigmoid_layer)  # its arguably a philosophical question... # but we are going to only declare that the parameters of the # sigmoid_layers are parameters of the StackedDAA # the visible biases in the dA are parameters of those  # dA, but not the SdA  self.params.extend(sigmoid_layer.params)  # Construct a denoising autoencoder that shared weights with this  # layer  dAdA_layer = dA(numpy_rngnumpy_rng=numpy_rng,  theano_rngtheano_rng=theano_rng,  input=layer_input,  n_visible=input_size,  n_hidden=hidden_layers_sizes[i],  W=sigmoid_layer.W,  bhid=sigmoid_layer.b)  self.dA_layers.append(dA_layer) 

现在我们只需要在这个 sigmoid 层上添加一个 logistic 层即可,这样我们就有了一个 MLP。我们将使用 LogisticRegression 类,这个类是在使用 logistic 回归分类 MNIST 数字时引入的。

# We now need to add a logistic layer on top of the MLP  self.logLayer = LogisticRegression(  input=self.sigmoid_layers[-1].output, n_in=hidden_layers_sizes[-1],  n_out=n_outs  ) self.params.extend(self.logLayer.params)  # construct a function that implements one step of finetunining  # compute the cost for second phase of training,  # defined as the negative log likelihood  selfself.finetune_cost = self.logLayer.negative_log_likelihood(self.y) # compute the gradients with respect to the model parameters # symbolic variable that points to the number of errors made on the  # minibatch given by self.x and self.y  selfself.errors = self.logLayer.errors(self.y) 

SdA 类也提供了一种为其层中的去噪自动编码器生成训练函数的方法。它们会作为一个列表返回,其中元素 i 是一个函数——该函数实现了训练对应于第 i 层的 dA 的步骤。

def pretraining_functions(self, train_set_x, batch_size):   Generates a list of functions, each of them implementing one  step in trainnig the dA corresponding to the layer with same index.  The function will require as input the minibatch index, and to train  a dA you just need to iterate, calling the corresponding function on all minibatch indexes. :type train_set_x: theano.tensor.TensorType  :param train_set_x: Shared variable that contains all datapoints used  for training the dA  :type batch_size: int  :param batch_size: size of a [mini]batch :type learning_rate: float  :param learning_rate: learning rate used during training for any of  the dA layers # index to a [mini]batch  index = T.lscalar(index) # index to a minibatch 

为了修改训练过程中的受损水平或学习率,我们将它们与 Theano 变量联系了起来。

corruption_level = T.scalar(corruption) # % of corruption to use  learning_rate = T.scalar(lr) # learning rate to use  # begining of a batch, given `index`  batch_begin = index * batch_size  # ending of a batch given `index`  batch_end = batch_begin + batch_size  pretrain_fns = [] for dA in self.dA_layers:  # get the cost and the updates list  cost, updates = dA.get_cost_updates(corruption_level,  learning_rate)  # compile the theano function  fn = theano.function(  inputs=[  index,  theano.In(corruption_level, value=0.2),  theano.In(learning_rate, value=0.1)  ],  outputs=cost,  updatesupdates=updates,  givens={  self.x: train_set_x[batch_begin: batch_end]  }  )  # append `fn` to the list of functions  pretrain_fns.append(fn)  return pretrain_fns 

现在任意 pretrain_fns[i] 函数都可以使用索引参数了,可选的有 corruption(受损水平)或 lr(学习率)。注意这些参数名是在它们被构建时赋予 Theano 变量的名字,而不是 Python 变量(learning_rate 或 corruption_level)的名字。在使用 Theano 时一定要记住这一点。我们用同样的方式构建了用于构建微调过程中所需函数的方法(train_fn、valid_score 和 test_score)。

def build_finetune_functions(self, datasets, batch_size, learning_rate):  Generates a function `train` that implements one step of  finetuning, a function `validate` that computes the error on  a batch from the validation set, and a function `test` that  computes the error on a batch from the testing set  :type datasets: list of pairs of theano.tensor.TensorType :param datasets: It is a list that contain all the datasets;  the has to contain three pairs, `train`,  `valid`, `test` in this order, where each pair  is formed of two Theano variables, one for the  datapoints, the other for the labels  :type batch_size: int  :param batch_size: size of a minibatch :type learning_rate: float :param learning_rate: learning rate used during finetune stage  (train_set_x, train_set_y) = datasets[0]  (valid_set_x, valid_set_y) = datasets[1]  (test_set_x, test_set_y) = datasets[2]  # compute number of minibatches for training, validation and testing  n_valid_batches = valid_set_x.get_value(borrow=True).shape[0]  n_valid_batches //= batch_size  n_test_batches = test_set_x.get_value(borrow=True).shape[0]  n_test_batches //= batch_size  index = T.lscalar(index) # index to a [mini]batch  # compute the gradients with respect to the model parameters  gparams = T.grad(self.finetune_cost, self.params)  # compute list of fine-tuning updates  updates = [  (param, param - gparam * learning_rate)  for param, gparam in zip(self.params, gparams)  ]  train_fn = theano.function(  inputs=[index],  outputs=self.finetune_cost,  updatesupdates=updates,  givens={  self.x: train_set_x[ index * batch_size: (index + 1) * batch_size  ],  self.y: train_set_y[  index * batch_size: (index + 1) * batch_size  ]  },  )  test_score_i = theano.function(  [index],  self.errors,  givens={  self.x: test_set_x[  index * batch_size: (index + 1) * batch_size  ],  self.y: test_set_y[  index * batch_size: (index + 1) * batch_size  ]  },  )  valid_score_i = theano.function(  [index],  self.errors,  givens={  self.x: valid_set_x[  index * batch_size: (index + 1) * batch_size  ],  self.y: valid_set_y[  index * batch_size: (index + 1) * batch_size  ]  },  )  # Create a function that scans the entire validation set  def valid_score():  return [valid_score_i(i) for i in range(n_valid_batches)]  # Create a function that scans the entire test set  def test_score(): return [test_score_i(i) for i in range(n_test_batches)]  return train_fn, valid_score, test_score 

注意,valid_score 和 test_score 并不是 Theano 函数,而是分别在整个验证集和整个测试集上循环的 Python 函数,可以在这些集合上产生一个损失列表。

总结

下面给出的几行代码就构建了一个堆叠的去噪自动编码器:

numpynumpy_rng = numpy.random.RandomState(89677)  print(... building the model)  # construct the stacked denoising autoencoder class  sda = SdA(  numpy_rngnumpy_rng=numpy_rng,  n_ins=28 * 28,  hidden_layers_sizes=[1000, 1000, 1000],  n_outs=10  ) 

该网络的训练分两个阶段:逐层的预训练,之后是微调。

对于预训练阶段,我们将在网络的所有层上进行循环。对于每个层,我们都将使用编译过的实现 SGD 步骤的函数,以优化权重,从而降低该层的重构成本。这个函数将根据 pretraining_epochs 在训练集上执行固定数量的 epoch。

######################### # PRETRAINING THE MODEL #  #########################  print(... getting the pretraining functions)  pretraining_fns = sda.pretraining_functions(train_set_xtrain_set_x=train_set_x, batch_sizebatch_size=batch_size)  print(... pre-training the model)  start_time = timeit.default_timer()  ## Pre-train layer-wise  corruption_levels = [.1, .2, .3]  for i in range(sda.n_layers):  # go through pretraining epochs  for epoch in range(pretraining_epochs): # go through the training set c = [] for batch_index in range(n_train_batches): c.append(pretraining_fns[i](index=batch_index,  corruption=corruption_levels[i],  lr=pretrain_lr))  print(Pre-training layer %i, epoch %d, cost %f % (i, epoch, numpy.mean(c, dtype=float64)))  end_time = timeit.default_timer() print((The pretraining code for file  + os.path.split(__file__)[1] +  ran for %.2fm % ((end_time - start_time) / 60.)), file=sys.stderr) 

这里的微调循环和多层感知器中的微调过程很相似。唯一的区别是它使用了 build_finetune_functions 给出的函数。

执行代码

用户可以通过调用以下 Python CLI 来运行该代码:

python code/SdA.py 

默认情况下,该代码会为每一层运行 15 次预训练 epoch,其批大小为 1。***层的受损水平为 0.1,第二层为 0.2,第三层为 0.3。预训练的学习率为 0.001,微调学习率为 0.1。预训练耗时 585.01 分钟,每 epoch 平均 13 分钟。微调经历了 36 epoch,耗时 444.2 分钟,每 epoch 平均 12.34 分钟。***的验证分数是 1.39%,测试分数是 1.3%。这些结果是在配置了 Intel Xeon E5430 @ 2.66GHz CPU 的机器上得到的,它有单线程的 GotoBLAS。

原文:https://codeburst.io/deep-learning-types-and-autoencoders-a40ee6754663

【本文是专栏机构“机器之心”的原创译文,微信公众号“机器之心( id: almosthuman2014)”】

戳这里,看该作者更多好文

本文地址:http://www.bzuk.cn/news/83c33899578.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

热门文章

全站热门

5s升级至9.3.2系统后的全面优化与改进(全新升级,系统体验再进一步)

最近全网疯传的一款高效工具箱,开源免费,内置11个黑科技功能!

8个DevOps自动化工具,帮你做出持续改进

微服务公用代码组织实践

假如你是一个测试入侵侦测系统或一些网络访问控制策略的网络管理员,那么你经常需要抓取数据包并在离线状态下分析这些文件。当需要保存捕获的数据包时,我们一般会存储为 libpcap 的数据包格式 pcap,这是一种被许多开源的嗅探工具以及捕包程序广泛使用的格式。假如 pcap 文件被用于入侵测试或离线分析的话,那么在将他们注入网络之前通常要先对 pcap 文件进行一些操作。在该文中,我将介绍一些操作 pcap 文件的工具,以及如何使用它们 。Editcap 与 MergecapWireshark,是最受欢迎的 GUI 嗅探工具,实际上它带了一套非常有用的命令行工具集。其中包括 editcap 与 mergecap。editcap 是一个万能的 pcap 编辑器,它可以过滤并且能以多种方式来分割 pcap 文件。mergecap 可以将多个 pcap 文件合并为一个。 该文就是基于这些 Wireshark 命令行工具的。假如你已经安装过 Wireshark 了,那么这些工具已经在你的系统中了。假如还没装的话,那么我们接下来就安装 Wireshark 命令行工具。 需要注意的是,在基于 Debian 的发行版上我们可以不用安装 Wireshark GUI 而仅安装命令行工具,但是在 Red Hat 及 基于它的发行版中则需要安装整个 Wireshark 包。Debian, Ubuntu 或 Linux Mint复制代码代码如下:$ sudo apt-get install wireshark-commonFedora, CentOS 或 RHEL复制代码代码如下:$ sudo yum install wireshark当安装好工具后, 就可以开始使用 editca 与 mergecap 了。pcap 文件过滤通过 editcap, 我们能以很多不同的规则来过滤 pcap 文件中的内容,并且将过滤结果保存到新文件中。首先,以“起止时间”来过滤 pcap 文件。 - A < start-time >和 - B < end-time >选项可以过滤出在这个时间段到达的数据包(如,从 2:30 ~ 2:35)。时间的格式为 “ YYYY-MM-DD HH:MM:SS。复制代码代码如下:$ editcap -A 2014-12-10 10:11:01 -B 2014-12-10 10:21:01 input.pcap output.pcap 也可以从某个文件中提取指定的 N 个包。下面的命令行从 input.pcap 文件中提取100个包(从 401 到 500)并将它们保存到 output.pcap 中:复制代码代码如下:$ editcap input.pcap output.pcap 401-500使用 -D < dup-window > (dup-window可以看成是对比的窗口大小,仅与此范围内的包进行对比)选项可以提取出重复包。每个包都依次与它之前的 < dup-window >-1 个包对比长度与MD5值,假如有匹配的则丢弃。复制代码代码如下:$ editcap -D 10 input.pcap output.pcap 遍历了 37568 个包, 在 10 窗口内重复的包仅有一个,并丢弃。也可以将 < dup-window >定义成时间间隔。使用-w < dup-time-window >选项,对比< dup-time-window >时间内到达的包。复制代码代码如下:$ editcap -w 0.5 input.pcap output.pcap 检索了 50000 个包, 以0.5s作为重复窗口,未找到重复包。分割 pcap 文件当需要将一个大的 pcap 文件分割成多个小文件时,editcap 也能起很大的作用。将一个 pcap 文件分割成数据包数目相同的多个文件复制代码代码如下:$ editcap -c 输出的每个文件有相同的包数量,以 < output-prefix >-NNNN的形式命名。以时间间隔分割 pcap 文件复制代码代码如下: $ editcap -i 合并 pcap 文件假如想要将多个文件合并成一个,用 mergecap 就很方便。当合并多个文件时,mergecap 默认将内部的数据包以时间先后来排序。复制代码代码如下:$ mergecap -w output.pcap input.pcap input2.pcap [input3.pcap . . .]假如要忽略时间戳,仅仅想以命令行中的顺序来合并文件,那么使用 -a 选项即可。例如,下列命令会将 input.pcap 文件的内容写入到 output.pcap, 并且将 input2.pcap 的内容追加在后面。复制代码代码如下:$ mergecap -a -w output.pcap input.pcap input2.pcap 总结在这篇指导中,我演示了多个 editcap、 mergecap 操作 pcap 文件的例子。除此之外,还有其它的相关工具,如 reordercap用于将数据包重新排序,text2pcap 用于将 pcap 文件转换为文本格式, pcap-diff用于比较 pcap 文

Web 图像技术:前端引入图片的各种方式及其优缺点

动手实践:使用Docker设置数据科学环境

如何突破Decoder性能瓶颈?揭秘FasterTransformer的原理与应用

友情链接

滇ICP备2023006006号-33