人工智能 - 自编码器 AutoEncoder [2]

欢迎Follow我的GitHub,关注我的简书

自编码器,使用稀疏的高阶特征重新组合,来重构自己,输入与输出一致。

TensorFlow框架的搭建方法,参考

源码,同时,复制autoencoder_models的模型文件。

本文源码的GitHub地址

AutoEncoder

工程配置

下载Python的依赖库:scikit-learn==0.19.0scipy==0.19.1sklearn==0.0

scipy

如果安装scipy出错,则把scipy==0.19.1写入requestments.txt,再安装,错误如下:

THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
    scipy from http://mirrors.aliyun.com/pypi/packages/63/68/c5098f3b6034e69d187e3f2e989f462143d9f8b524f5a4f9e13c4a6f5f47/scipy-0.19.1-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl#md5=72415e8da753eea97eb9820602931cb5:
        Expected md5 72415e8da753eea97eb9820602931cb5
             Got        073584eb2c597bbfb82a5865b7055787

或者,直接编写requestments.txt,全部安装

pip install -r requirements.txt

matplotlib

安装matplotlib

pip install matplotlib -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com

如果安装matplotlib报错,如下:

RuntimeError: Python is not installed as a framework. The Mac OS X backend will not be able to function correctly if Python is not installed as a framework. See the Python documentation for more information on installing Python as a framework on Mac OS X. Please either reinstall Python as a framework, or try one of the other backends. If you are using (Ana)Conda please install python.app and replace the use of 'python' with 'pythonw'. See 'Working with Matplotlib on OSX' in the Matplotlib FAQ for more information.

则执行Shell命令

cd ~/.matplotlib
touch matplotlibrc

导入matplotlib

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

opencv

opencv的导入库是cv2,安装是opencv-python

sudo pip install opencv-python -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com

导入cv2,如果直接使用import cv2,则无法自动补全,导入时应该使用:

import cv2.cv2 as cv2

图片存储

获取MNIST的图片源,test表示测试集,train表示训练集,images表示图片集,labels表示标签集。images的数据类型是ndarry,784维;labels的数据类型也是ndarray,one-hot类型。

# 加载数据
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
images = mnist.test.images  # 图片
labels = mnist.test.labels  # 标签

将784维的一阶矩阵转换为28维的二阶图片,将one-hot标签转换为数字(0~9),存储test的前100张图片。

# 存储图片
size = len(labels)
for i in range(size):
    pxl = np.array(images[i])  # 像素
    img = pxl.reshape((28, 28))  # 图片
    lbl = np.argmax(labels[i])  # 标签
    misc.imsave('./IMAGE_data/test/' + str(i) + '_' + str(lbl) + '.png', img)  # scipy的存储模式
    if i == 100:
        break

合并100张图片为一张图片,便于做对比。

# 合并图片
large_size = 28 * 10
large_img = Image.new('RGBA', (large_size, large_size))
paths_list, _, __ = listdir_files('./IMAGE_data/test/')
for i in range(100):
    img = Image.open(paths_list[i])
    loc = ((int(i / 10) * 28), (i % 10) * 28)
    large_img.paste(img, loc)
large_img.save('./IMAGE_data/merged.png')

图片的三种存储方式:scipy、matplotlib(含坐标)、opencv。

# 其他的图片存储方式
pixel = np.array(images[0])  # 784维的数据
label = np.argmax(labels[0])  # 找到标签
image = pixel.reshape((28, 28))  # 转换成28*28维的矩阵

# -------------------- scipy模式 -------------------- #
misc.imsave('./IMAGE_data/scipy.png', image)  # scipy的存储模式
# -------------------- scipy模式 -------------------- #

# -------------------- matplotlib模式 -------------------- #
plt.gray()  # 转变为灰度图片
plt.imshow(image)
plt.savefig("./IMAGE_data/plt.png")
# plt.show()
# -------------------- matplotlib模式 -------------------- #

# -------------------- opencv模式 -------------------- #
image = image * 255  # 数据是0~1的浮点数
cv2.imwrite("./IMAGE_data/opencv.png", image)
# cv2.imshow('hah', pixels)
# cv2.waitKey(0)
# -------------------- opencv模式 -------------------- #

自编码器

读取MNIST的数据

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

将训练数据与测试数据标准化

X_train, X_test = standard_scale(mnist.train.images, mnist.test.images)

以训练数据为标准,计算均值和标准差,然后处理训练数据与测试数据。

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

在StandardScaler中,mean_表示均值矩阵,与图片维数一致;scale_表示标准差,也与图片维数一致;矩阵中每一个数字都减去对应的均值,除以对应的标准差。

self.scale_ = _handle_zeros_in_scale(np.sqrt(self.var_))
X -= self.mean_
X /= self.scale_

设置训练参数:n_samples全部样本个数,training_epochs迭代次数,batch_size批次的样本数,display_step显示步数。

n_samples = int(mnist.train.num_examples)
training_epochs = 20
batch_size = 128
display_step = 1

AdditiveGaussianNoiseAutoencoder,简称AGN,加高斯噪声的自动编码器。n_input输入节点数,与图片维数相同,784维;n_hidden隐含层的节点数,需要小于输入节点数,200维;transfer_function激活函数,tf.nn.softplusoptimizer优化器,AdamOptimizer,学习率是0.001;scale噪声系数,0.01。

autoencoder = AdditiveGaussianNoiseAutoencoder(
    n_input=784, n_hidden=200, transfer_function=tf.nn.softplus,
    optimizer=tf.train.AdamOptimizer(learning_rate=0.001), scale=0.01)

关于激活函数softplus的原理如下:

mat = [1., 2., 3.]  # 需要使用小数
# softplus: [ln(e^1 + 1), ln(e^2 + 1), ln(e^3 + 1)]
print tf.Session().run(tf.nn.softplus(mat))

random_normal生成随机的正态分布数组

rn = tf.random_normal((100000,))  # 一行,指定seed,防止均值的时候随机
mean, variance = tf.nn.moments(rn, 0)  # 计算均值和方差,预期均值约等于是0,方差是1
print tf.Session().run(tf.nn.moments(rn, 0))

AdditiveGaussianNoiseAutoencoder的构造器

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)  # 系数,待训练的参数,初始的feed数据是training_scale
    self.training_scale = scale  # 高斯噪声系数
    network_weights = self._initialize_weights()  # 初始化权重系数,输入层w1/b1,输出层w2/b2
    self.weights = network_weights  # 权重

    # model
    self.x = tf.placeholder(tf.float32, [None, self.n_input])  # 需要feed的数据
    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.5*(x - x_)^2,求和
    self.cost = 0.5 * tf.reduce_sum(tf.pow(tf.subtract(self.reconstruction, self.x), 2.0))
    self.optimizer = optimizer.minimize(self.cost)

    init = tf.global_variables_initializer()
    self.sess = tf.Session()
    self.sess.run(init)  # 执行图

random_normal随机生成矩阵,参数(n_input,),n_input行1列,均值为0,方差为1,tf.nn.moments,返回均值和方差。

rn = tf.random_normal((100000,))  # 一行,指定seed,防止均值的时候随机
mean, variance = tf.nn.moments(rn, 0)  # 计算均值和方差,预期均值约等于是0,方差是1
print tf.Session().run(tf.nn.moments(rn, 0))

初始化权重,分为两层,将n_input维的数据转换为n_hidden维的数据,再反向转换回去。初始权重初始化使用xavier_initializer(泽维尔初始化器),权重的均值为1,方差为1/(n_input+n_hidden)

def _initialize_weights(self):
    all_weights = dict()
    # 使用xavier_initializer初始化
    all_weights['w1'] = tf.get_variable("w1", shape=[self.n_input, self.n_hidden],
                                        initializer=tf.contrib.layers.xavier_initializer())
    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

训练模型,输出每个轮次的平均avg_cost,

for epoch in range(training_epochs):
    avg_cost = 0.
    total_batch = int(n_samples / batch_size)
    # Loop over all batches
    for i in range(total_batch):
        batch_xs = get_random_block_from_data(X_train, batch_size)

        # Fit training using batch data
        cost = autoencoder.partial_fit(batch_xs)
        # Compute average loss
        avg_cost += cost / n_samples * batch_size

    # Display logs per epoch step
    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)))

随机获取起始位置,取区块大小的一批数据。

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)]  # batch_size大小的区块

调用autoencoder的partial_fit,向算法Feed数据,数据就是批次数据,高斯噪声系数使用默认。

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

最终输出整个测试集X_test的Cost值。

print("Total cost: " + str(autoencoder.calc_total_cost(X_test)))

原图像的效果(100张):

MINST

自编码器的效果(100张):

AutoEncoder的MINST

OK,that‘s all! Enjoy it!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容