【TensorFlow-windows】(二) 实现一个去噪自编码器
主要内容:
1.自编码器的TensorFlow实现代码(详细代码注释)
2.该实现中的函数总结
平台:
1.windows 10 64位
2.Anaconda3-4.2.0-Windows-x86_64.exe (当时TF还不支持python3.6,又懒得在高版本的anaconda下配置多个Python环境,于是装了一个3-4.2.0(默认装python3.5),建议装anaconda3的最新版本,TF1.2.0版本已经支持python3.6!)
3.TensorFlow1.1.0
老样子,先贴代码:
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 20 12:59:16 2017
@author: ASUS
"""
import numpy as np
import sklearn.preprocessing as prep
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 定义Xavier初始化函数 tf.random_uniform产生均匀分布
def xavier_init(fan_in, fan_out, constant = 1):
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 AdditiveGaussianNoiseAutoEncoder(object):
def __init__(self, n_input, n_hidden, transfer_function = tf.nn.softplus,
optimizer = tf.train.AdamOptimizer(), scale = 0.1):
self.n_input = n_input
self.n_hidden = n_hidden
self.transfer = transfer_function
self.scale = tf.placeholder(tf.float32)
self.training_scale = scale
network_weights = self._initialize_weights()
self.weights = network_weights
# 定义网络结构
# x 为输入,因此要用placeholder进行“占位符”操作
self.x = tf.placeholder(tf.float32, [None, self.n_input])
# hidden 是隐含层 ,此自编码器只含一个隐层
# self.x + scale * tf.random_normal((n_input,)) 是加噪声,scale是噪声系数
# hidden = f(w*x1+b), f 是激活函数
# weights w1和b1 分别表示第一层的权值、偏置
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
# tf.pow()是计算幂 2.0则表示计算平方, tf.subtract是对应元素相减
self.cost = 0.5 * tf.reduce_sum(tf.pow(tf.subtract(
self.reconstruction, self.x), 2.0))
# 定义优化器 对损失 self.cost进行优化
self.optimizer = optimizer.minimize(self.cost)
# 全局参数初始化
init = tf.global_variables_initializer()
# 创建会话 sess
self.sess = tf.Session()
self.sess.run(init)
# 定义权值初始化函数,AE的权值存放在一个字典里
# w1采用xavier初始化,其余设置为全0
def _initialize_weights(self):
all_weights = dict()
all_weights['w1'] = tf.Variable(xavier_init(
self.n_input, self.n_hidden))
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_weights
# 定义 执行一步训练的函数
def partial_fit(self, X):
cost, opt = self.sess.run((self.cost, self.optimizer),
feed_dict = {self.x: X, self.scale: self.training_scale})
return cost
# 定义计算总的cost,在评测AE时用到
# 只让Session执行一个计算图节点 self.cost
def calc_total_cost(self, X):
return self.sess.run(self.cost, feed_dict = {
self.x : X, self.scale: self.training_scale
})
# 定义transform函数,
# 作用是 返回AE隐含层的输出结果
# 目的是 提供一个接口来获取抽象后的特征
def transform(self, X):
return self.sess.run(self.hidden, feed_dic = {
self.scale: self.training_scale
})
# 定义generate函数,将隐含层的输出作为输入,
# 通过重建层(reconstruction)来复原原始数据
def generate(self, hidden = None):
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):
return self.sess.run(self.reconstruction, fedd_dict = {
self.x: X, self.scale: self.traning_scale
})
# getWeights获取 隐含层权重
def getWeights(self):
return self.sess.run(self.weights['w1'])
def getBiases(self):
return self.sess.run(self.weights['b1'])
mnist = input_data.read_data_sets('MNIST_data', one_hot = True)
# 定义函数 对 mnist数据进行标准化 (减均值,除以标准差)
# 利用skleran里的 StandardScaler类
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数据
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)]
# 数据标准化
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
display_step = 1
# 创建AGN(Additive Gaussian Noise,加性高斯噪声)自编码器实例
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):
avg_cost = 0.
total_batch = int(n_samples / batch_size)
for i in range(total_batch):
batch_xs = get_random_block_from_data(X_train, batch_size)
cost = autoencoder.partial_fit(batch_xs)
avg_cost += cost / n_samples * batch_size
if epoch % display_step ==0 :
print('Epoch: ', '%04d' % (epoch+1), 'Cost = ','{:.9f}'.format(avg_cost))
print('Total cost: ' + str(autoencoder.calc_total_cost(X_test)))
此代码主要实现了一个去噪自编码器,噪声采用的AGN(Additive Gaussian Noise,加性高斯噪声)。
自编码器的介绍可以查看如下链接:
http://ufldl.stanford.edu/wiki/index.php/Autoencoders_and_Sparsity
简单讲,自编码器就是对原始数据利用神经网络进行编码,这里的码其实就是隐含层的输出,通过BP算法对神经网络的权值进行修改,最终通过这些权值对原始数据做运算(运算则是编码过程),得到输出(输出则是编好的码) ,而有编码,就有解码。解码呢,就是将编好的码还原成原始数据,这里的还原方法,同样是采用神经网络的某一层。
其中用到Xavier初始化方法是2010年 Xavier提出的,有兴趣可拜读:
《Understanding the Difficult of Training Deep Feedforward Neural Networks》
其中用到的函数总结(续上篇):
1. sess = tf.InteractiveSession() 将sess注册为默认的session
2. tf.placeholder() , Placeholder是输入数据的地方,也称为占位符,通俗的理解就是给输入数据(此例中的图片x)和真实标签(y_)提供一个入口,或者是存放地。(个人理解,可能不太正确,后期对TF有深入认识的话再回来改~~)
3. tf.Variable() Variable是用来存储模型参数,与存储数据的tensor不同,tensor一旦使用掉就消失
4. tf.matmul() 矩阵相乘函数
5. tf.reduce_mean 和tf.reduce_sum 是缩减维度的计算均值,以及缩减维度的求和
6. tf.argmax() 是寻找tensor中值最大的元素的序号 ,此例中用来判断类别
7. tf.cast() 用于数据类型转换
————————————–我是分割线(一)———————————–
- tf.random_uniform 生成均匀分布的随机数
- tf.train.AdamOptimizer() 创建优化器,优化方法为Adam(adaptive moment estimation,Adam优化方法根据损失函数对每个参数的梯度的一阶矩估计和二阶矩估计动态调整针对于每个参数的学习速率)
- tf.placeholder “占位符”,只要是对网络的输入,都需要用这个函数这个进行“初始化”
- tf.random_normal 生成正态分布
- tf.add 和 tf.matmul 数据的相加 、相乘
- tf.reduce_sum 缩减维度的求和
- tf.pow 求幂函数
- tf.subtract 数据的相减
- tf.global_variables_initializer 定义全局参数初始化
- tf.Session 创建会话.
- tf.Variable 创建变量,是用来存储模型参数的变量。是有别于模型的输入数据的
- tf.train.AdamOptimizer (learning_rate = 0.001) 采用Adam进行优化,学习率为 0.001
【TensorFlow-windows】(二) 实现一个去噪自编码器的更多相关文章
- 被windows“折磨”了一个礼拜
说是被windows折磨了一个礼拜,这话一点都不假!由于想彻底的卸载SQL Server而误删系统文件,导致系统重启之后持续蓝屏.无奈之下只能重装系统(心想,加入当初自己将系统备份的话,那该是多美好的 ...
- SuperSocket基础(二)-----一个完成SocketServer项目
SuperSocket基础(二)-----一个完成SocketServer项目 由于时间关系未能及时更新,关于SuperSocket,对于初学者而言,一个SuperSock的Server真的不好写.官 ...
- 深入浅出TensorFlow(二):TensorFlow解决MNIST问题入门
2017年2月16日,Google正式对外发布Google TensorFlow 1.0版本,并保证本次的发布版本API接口完全满足生产环境稳定性要求.这是TensorFlow的一个重要里程碑,标志着 ...
- 使用Windows service创建一个简单的定时器
一.需求 我们有时候可能会想要做一些定时任务,例如每隔一段时间去访问某个网站,或者下载一些东西到我们服务器上等等之类的事情,这时候windows service 是一个不错的选择. 二.实现 1.打开 ...
- windows forms 上一个类似于wpf snoop 的工具: Hawkeye
windows forms 上一个类似于wpf snoop 的工具: Hawkeye 周银辉 WPF上有snoop这样的run time object editor让人用着很爽, 今天搜到了一个for ...
- Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器
Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器 MVC概念 MVC的含义是 “模型-视图-控制器”.MVC是一个架构良好并且易于测试和易于维护的开发模式.基于MVC模式的应用程 ...
- 【IE6的疯狂之十二】一个display:none引起的3像素的BUG
今天同事给我看了一个display:none引起的3像素的BUG,非常奇怪!从来没碰到过display:none还能引起这种bug. 看代码: <div style="width: ...
- Go笔记之二:一个完整的播放器示例
Go笔记之二:一个完整的播放器示例 该示例从命令行运行一个播放器示例,可进行添加.删除.浏览和模拟播放,其内容是对 Go 语言接口使用的良好展示 源码及可执行文件 参考书籍<Go语言编程> ...
- windows 上查看一个命令的退出码
windows 上查看一个命令的退出码可以使用下面语句 echo %errorlevel% 例如:windows 上没有ls 命令,所以使用后没有成功,查看退出码为9009 ,非0 使用dir 列出目 ...
随机推荐
- Java Socket IO(BIO、NIO)
总结下Java socket IO.首先是各种IO的定义,这个定义似乎也是众说纷纭.我按照stackoverflow上面的解释: IO有两种分法:按照阻塞或者按照同步.按照阻塞,有阻塞IO和非阻塞IO ...
- 【转】SpringMVC访问静态资源的三种方式
如何你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题.如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对*.js,*.jpg ...
- BNU 12846 LCM Extreme 最小公倍数之和(线性欧拉筛选+递推)
LCM Extreme Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Orig ...
- GridView主键列不让编辑时应该修改属性DataKeyNames
原文发布时间为:2008-08-02 -- 来源于本人的百度文章 [由搬家工具导入] 为了防止GridView主键被编辑,应该在GridView属性DataKeyNames里面写上主键
- poj 1950(搜索)
Dessert Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 5430 Accepted: 2029 Descripti ...
- LeetCode OJ——Validate Binary Search Tree
http://oj.leetcode.com/problems/validate-binary-search-tree/ 判断一棵树是否为二叉搜索树.key 是,在左子树往下搜索的时候,要判断是不是子 ...
- codevs——1700 施工方案第二季
1700 施工方案第二季 2012年市队选拔赛北京 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description c国边防 ...
- Skiing(最短路)
poj——3037 Skiing Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4921 Accepted: 1315 ...
- loj #110. 乘法逆元
#110. 乘法逆元 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 这是一道模板题. 给定 ...
- docker run 报错——WARNING: IPv4 forwarding is disabled. Networking will not work.
执行 docker run 时遇到如下WARNING: [root@etcd1 volumes]# docker run -d -p 8080:80 -v /tmp/test_mount http ...