Tensorflow实现自编码器

  • 自编码器
    • Denoising AutoEncoder(去噪自编码器)

自编码器

特征的稀疏表达:使用少量的基本特征组合拼装得到更高层抽象的特征。
如:图像碎片可由少量的基本结构稀疏表达。

自编码器定义:

  • 使用自身的高阶特征编码自己,目标是使用稀疏的一些高阶特征重新组合来重构自己。

自编码器特点:

  • 输入节点和输出节点的数量一致
  • 使用自身的高阶特征编码自己,不只是复制像素点

自编码器作用:

  • 给监督训练做无监督的预训练,提取特征
  • 可直接进行特征提取和分析

自编码器使用少量稀疏的高阶特征来重构输入,所以加入几种限制:

  • 如果限制隐含层的数量,中间隐含层节点数量小于输入输出节点数量,相当于降维的过程,只能学习输入数据最重要的特征,将不太相关的内容去除。
  • 如果给数据加噪声(通常是加性高斯噪声Additive Gaussian Noise,AGN),那么就是Denoising AutoEncoder(去噪自编码器),将从噪声中学习出数据的特征,学习数据频繁出现的模式和结构,将无规律的噪声去除。

Denoising AutoEncoder(去噪自编码器)

"""作者:Heart Sea功能:tessorflow实现去噪自编码器Additive Gaussian Noise,AGNModel:1个输入层, 加噪声全连接1个隐含层, 激活全连接1个输出层版本:1.0日期:10/10/2019
"""import numpy as np                       # 导入常用库numpy
import sklearn.preprocessing as prep     # 导入sklearn中的preprocessing模块,负责预处理数据标准化
import tensorflow as tf                  # 导入tensorflow
from tensorflow.examples.tutorials.mnist import input_data    # 导入mnist数据集# 实现标准均匀分布的Xaiver初始化器(根据某一层网络的输入、输出节点数量自动调整最合适的权重分布)
# Xaiver就是让权值满足:均值=0,方差=2/(n_in+n_out)
# 分布可以用均匀分布或者高斯分布,这里采用均匀分布,方差=2/(n_in+n_out)=(max-min)^2/12
def xavier_init_(fan_in, fan_out, constant=1):  # xavier_init_(self.n_input, self.n_hidden)""":param fan_in: 输入节点的数量, 行数:param fan_out: 输出节点的数量, 列数:param constant: 1:return: 返回一个比较适合softplus等激活函数的权重初始分布w1"""low = -constant*np.sqrt(6.0/(fan_in + fan_out))high = constant*np.sqrt(6.0/(fan_in + fan_out))return tf.random_uniform((fan_in, fan_out),minval=low, maxval=high,dtype=tf.float32)# 定义一个去噪自编码的class,此类包括一个构建函数_init_(),还有一些成员函数
class AdditiveGaussianNoiseAutoencoder(object):def __init__(self, n_input, n_hidden, transfer_function=tf.nn.softplus,optimizer=tf.train.AdadeltaOptimizer(), scale=0.1):""":param n_input: 输入变量数:param n_hidden: 隐含层节点数:param transfer_function: 隐含层激活函数,默认为softplus:param optimizer: 默认为Adam:param scale: 高斯噪声系数,默认0.1"""self.n_input = n_inputself.n_hidden = n_hiddenself.transfer = transfer_functionself.scale = tf.placeholder(tf.float32)self.training_scale = scalenetwork_weights = self._initialize_weights()  # 使用_initialize_weights()函数初始化参数,后面会定义self.weights = network_weights# 定义网格结构:输入层,隐含层,输出层# x每行是一个样本,列是特征self.x = tf.placeholder(tf.float32, [None, self.n_input])# 建立能提取特征的隐含层,給输入添加维度为(n_input,)的正态分布的噪声# tf.random_normal((n_input,))里的小括号可换成中括号,一行n_input列个正态随机个数,没有设置随机种子# self.x + scale * tf.random_normal((n_input,))相当于每个样本的n_input个特征都加了噪声self.hidden = self.transfer(tf.add(tf.matmul(self.x + scale * tf.random_normal((n_input,)),self.weights['w1']),self.weights['b1']))# 建立输出层self.reconstruction = tf.add(tf.matmul(self.hidden,self.weights['w2']),self.weights['b2'])# 定义自编码器的损失函数,用平方误差作为cost,输出与输入之差再平方,求和,0.5self.cost = 0.5 * tf.reduce_sum(tf.pow(tf.subtract(self.reconstruction, self.x), 2.0))         # 使用平方误差作为costself.optimizer = optimizer.minimize(self.cost)  # 优化器为损失进行优化init = tf.global_variables_initializer()        # 初始化全部模型参数self.sess = tf.Session()                        # 建立Sessionself.sess.run(init)# 定义参数初始化函数_initialize_weights# 输出层权重和偏置不含激活函数,直接初始化为0def _initialize_weights(self):all_weights = dict()  # 创建字典dictall_weights['w1'] = tf.Variable(xavier_init_(self.n_input, self.n_hidden))   # 返回一个比较适合softplus等激活函数的权重初始分布all_weights['b1'] = tf.Variable(tf.zeros([self.n_hidden], dtype=tf.float32))all_weights['w2'] = tf.Variable(tf.zeros([self.n_hidden, self.n_input], dtype=tf.float32))all_weights['b2'] = tf.Variable(tf.zeros([self.n_input], dtype=tf.float32))return all_weightsdef partial_fit(self, X):"""aim: 定义计算损失cost及执行一步训练的函数partial_fit:param X: 一个batch数据:return: 当前损失"""cost, opt = self.sess.run((self.cost, self.optimizer),feed_dict={self.x: X, self.scale: self.training_scale})return costdef calc_total_cost(self, X):"""aim: 定义一个只计算cost的函数,主要是在训练完毕后,在测试集上对模型性能进行测评,不会触发训练操作:param X: 测试集数据:return: 平方误差cost"""return self.sess.run(self.cost, feed_dict={self.x: X,self.scale: self.training_scale})def transform(self, X):"""aim: 定义transform函数(自编码器的前半部分),目的是提供一个接口来获取高阶特征:param X::return: 返回自编码器隐含层的输出结果 hidden"""return self.sess.run(self.hidden, feed_dict={self.x: X,self.scale: self.training_scale})def generate(self, hidden=None):"""定义generate函数(自编码器的后半部分),将transform提取的高阶特征经过重建层复原为原始数据:param hidden: 隐含层的输出结果:return: 高阶特征经过重建层复原为原始数据"""if hidden is None:hidden = np.random.normal(size=self.weights["b1"])return self.sess.run(self.reconstruction, feed_dict={self.hidden: hidden})def reconstruct(self, X):"""整体运行transform和generate两个过程:param X: 原始数据:return: 复原的原始数据"""return self.sess.run(self.reconstruction, feed_dict={self.x: X,self.scale: self.training_scale})# 定义getWeights函数,获取隐含层的权重W1def getWeights(self):return self.sess.run(self.weights['w1'])# 定义getBiases函数,获取隐含层偏置系数b1def getBiases(self):return self.sess.run(self.weights['b1'])# 去噪自编码器的类已经定义完,包括神经网络的设计、权重的初始化mnist = input_data.read_data_sets('MNIST_data', one_hot=True)   # 载入minist数据集# 定义standard_scale函数,对训练、测试数据标准化,
# 标准化即让数据变成0均值,且标准差为1的分布。方法是先减去均值,再除以标准差
# 为保证训练、测试数据使用完全相同的Scaler,需要先在训练数据上fit出一个共用的Scaler,再将这个Scaler用到训练数据和测试数据上
def standard_scale(X_train, X_test):preprocessor = prep.StandardScaler().fit(X_train)X_train = preprocessor.transform(X_train)X_test = preprocessor.transform(X_test)return X_train, X_test# 定义一个随机取block数据的函数
# random.randint(a, b),用于生成一个指定范围a <= n <= b的整数
# 将这个随机数作为block的起始位置,顺序取到一个batch size的数据。这属于放回原样,可以提高数据利用率
def get_random_block_from_data(data, batch_size):start_index = np.random.randint(0, len(data) - batch_size)return data[start_index:(start_index + batch_size)]# 使用standard_index函数标准化训练集,测试集
X_train, X_test = standard_scale(mnist.train.images, mnist.test.images)# 定义常用参数
n_samples = int(mnist.train.num_examples)  # 总训练样本数
training_epochs = 20                       # 最大训练轮数
batch_size = 128                           # 批数据,即多少个样本作为一个batch
display_step = 1                           # 每隔一轮epoch显示一次损失cost# 创建一个AGN自编码器的实例,并设置输入层节点数、隐含层节点数、隐含层激活函数、优化器、噪声系数
autoencoder = AdditiveGaussianNoiseAutoencoder(n_input=784,n_hidden=200,transfer_function=tf.nn.softplus,optimizer=tf.train.AdamOptimizer(learning_rate=0.001),scale=0.01)# 开始训练
for epoch in range(training_epochs):                # 迭代训练轮数# print(epoch)avg_cost = 0.                                   # 每一轮开始时,平均损失=0total_batch = int(n_samples / batch_size)       # 样本总数/batch大小=需要的batch数for i in range(total_batch):                    # 迭代一轮中所有的批数据# print(i)batch_xs = get_random_block_from_data(X_train, batch_size)       # 随机抽取block数据cost = autoencoder.partial_fit(batch_xs)      # 使用partial_fit训练这个当前的batch数据的平方误差avg_cost += cost / n_samples * batch_size     # 将当前的cost整合到avg_cost,计算平均cost# 每一轮迭代后,显示当前的迭代数和这一轮迭代的acg_costif epoch % display_step == 0:print("Epoch:", '%04d' % (epoch + 1),"cost =", "{:.9f}".format(avg_cost))# 对测试集进行测试,评价指标仍然是平方误差
print("Total cost: " + str(autoencoder.calc_total_cost(X_test)))

Epoch: 0001 cost= 19708.600550000
Epoch: 0002 cost= 13143.029138636


从实现的角度而言,自编码器其实和一个单隐含层的神经网络差不多,只是自编码器在数据输入时做了标准化处理,且加上了一个高斯噪声,同时我们的输出结果不是数字分类结果,而是复原的数据,因此不需要用标注过的数据进行监督训练。自编码器作为一种无监督学习方法,它与其他无监督学习的区别主要在于:它不是对数据进行聚类,而是把数据中最有用、最频繁的高阶特征提取出来,然后根据这些高阶特征进行重构数据。在深度学习发展早期非常流行的DBN,也是依靠这种思想,先对数据进行无监督学习,提取到一些有用的特征,将神经网络权重初始化到一个较好的分布,然后再使用有标注的数据进行监督训练,即对权重进行fine-tune。

现实生活中,大部分数据是没有标准信息的,但人脑比较擅长处理这些数据,会提取出其中的高阶抽象特征,并使用在别的地方。自编码器作为深度学习在无监督领域的应用的确非常成功,同时无监督学习也将成为深度学习一个重要发展方向。

Tensorflow基于minist数据集实现自编码器相关推荐

  1. TensorFlow基于minist数据集实现手写字识别实战的三个模型

    手写字识别 model1:输入层→全连接→输出层softmax model2:输入层→全连接→隐含层→全连接→输出层softmax model3:输入层→卷积层1→卷积层2→全连接→dropout层→ ...

  2. 【MLP实战】001:基于Minist数据集的手写数字识别

    本文又是一篇基于Minist数据集的手写数字识别. 首先,mnist数据集: 链接:https://pan.baidu.com/s/1z7R7_jnDKZm9F7M6n8hiIw 提取码:rn8z 首 ...

  3. TensorFlow基于cifar10数据集实现进阶的卷积网络

    TensorFlow基于cifar10数据集实现进阶的卷积网络 学习链接 CIFAR10模型及数据集介绍 综述 CIFAR10数据集介绍 CIFAR10数据集可视化 CIFAR10模型 CIFAR10 ...

  4. 机器学习Tensorflow基于MNIST数据集识别自己的手写数字(读取和测试自己的模型)

    机器学习Tensorflow基于MNIST数据集识别自己的手写数字(读取和测试自己的模型)

  5. tensorflow基于csv数据集实现多元线性回归并预测

    #coding:utf8 import tensorflow as tf from sklearn import linear_model from sklearn import preprocess ...

  6. (转)CNN基于Tensorflow实现cifar10数据集80-准确率

    https://www.jianshu.com/p/a2c1016faa95 数据导入和预处理 本文使用的是CIFAR10的数据集.CIFAR10包含了十个类型的图片,有60000张大小为32x32的 ...

  7. 基于TensorFlow和mnist数据集的手写数字识别系统 ,可识别电话号码,识别准确率高,有对比实验,两组模型,可讲解代码

    基于TensorFlow和mnist数据集的手写数字识别系统 ,可识别电话号码,识别准确率高,有对比实验,两组模型,可讲解代码

  8. 图像分类经典项目:基于开源数据集Fashion-MNIST的应用实践

    Datawhale 作者:何新,Datawhale优秀学习者 简介:何新,武汉理工大学硕士 https://github.com/whut2962575697 图像分类是计算机视觉和数字图像处理的一个 ...

  9. TF之CNN:基于CIFAR-10数据集训练、检测CNN(2+2)模型(TensorBoard可视化)

    TF之CNN:基于CIFAR-10数据集训练.检测CNN(2+2)模型(TensorBoard可视化) 目录 1.基于CIFAR-10数据集训练CNN(2+2)模型代码 2.检测CNN(2+2)模型 ...

最新文章

  1. matlab中的数值计算,MATLAB数值计算(中译本,最新修订)
  2. iOS tableview性能优化及分析
  3. python语言可以应用在哪些方面-Python语言的应用领域主要有哪些?
  4. 我的程序员之路:上帝的苹果
  5. [SQL基础教程]1-4 SQL 表的创建
  6. 王道8套有变化吗_求求你别再套花艺设计公式了
  7. Codeforces Round #655 (Div. 2) B C
  8. samba服务设置与访问共享文件夹
  9. 华为浏览器工具箱 html修改,华为电子文档浏览器(HedEx Lite)
  10. linux aria2安装路径,Aria2 Linux 完整安装及使用教程
  11. discuz X2中template文件夹中模板文件目录
  12. 仿支付宝头像外加一个边框的工具类
  13. 「时序数据库」时间序列数据与MongoDB:第一部分-简介
  14. js绘制的漂亮玫瑰曲线rose curve
  15. djyvp2计算机电缆哪家好,ZA-DJYVP22-2*2*1.5计算机电缆
  16. 画皮SAP-世界管理软件公司的中国真相
  17. 在线教育APP的发展历程
  18. 解决Windows7英文版显示简体中文程序乱码
  19. 校园英语杂志《校园英语》杂志社《校园英语》编辑部2023年第一期目录
  20. linux下VsFTP配置全方案

热门文章

  1. 【Python】青少年蓝桥杯_每日一题_10.11_小球反弹
  2. Android --- 订单编号怎样不重复?一秒钟如果有n个人同时下单怎么解决?凌晨12点限量抢购1000件商品,直到抢完为止订单编号怎么处理?
  3. jQuery-基本选择器的种类
  4. Android --- layout_marginStart和layout_marginEnd的详细讲解
  5. java里函数式表达式_Java8函数式编程 (一) 数据流和lambda表达式
  6. 高校邦python程序设计基础篇_高校邦Python程序设计基础【实境编程】章节答案
  7. cvid matlab,WAKE-WIN10-SOFT-软件-Matlab配置及工具箱
  8. am335x linux内核烧写_实时 Linux 抖动分析 Step by step
  9. 成功解决ImportError: Something is wrong with the numpy installation. While importing we detected an olde
  10. Algorithm:数学建模大赛(国赛和美赛)的简介/内容、数学建模做题流程、历年题目类型及思想、常用算法、常用工具之详细攻略