用Keras实现SDAE

看了Deep Auto-encoder,然后实现了一下,但是发现要初始化好参数,不然可能效果不佳。Deep Auto-encoder的实现

SDAE的思想是每次训练一层网络,训练好了之后将此网络的输入当做下一层网络的输入,用于训练下一层网络。这样当前k层训练好之后,再训练第k+1层,而不是像我上面那个文章一样,一次性将k层一起训练了。将每层都训练好之后,再结合起来进行训练(fine-tune),这样能够达到比较好的效果。

SDAE的思想可以再搜一下,可以了解更清楚。

实现效果:
单独训练好每一层的网络,然后测试一下效果(上面是原图,下面是编码再解码的图片):
在这里插入图片描述
然后将网络结合起来进行训练,下面是迭代6000次的效果,测试的时候发现有的图片效果很棒,有的效果不太好(上面是原图,下面是编码再解码的图片):
在这里插入图片描述

上面的效果encoder的最后一层神经元有30个,即将28 x 28的图片降到30维,然后再从30维转回图片的效果。
但是30维不好显示在二维图形上面,所以下面将30换成2,然后用散点图进行显示。

重新训练,将图片降到2维之后,再从2维解码生成图片,效果如下:
在这里插入图片描述
从测试集中选取了3000个图片,然后通过encoder进行编码,降到2维,绘制效果如下:
在这里插入图片描述
可以看出0,1,2,6的被分隔得很开,其他的会重叠在一起。

上面的实验结果都是没有加入噪声数据的,加入20%的噪声数据,即随机将图片上面的像素值设置为0,效果如下(上面的是噪声图片,下面是编码再解码生成的图片):
在这里插入图片描述
在这里插入图片描述
可以看出,SDAE可以从噪声数据进行降维,然后生成去噪的图片,效果还是不错的。上面的效果是降到10维的效果。
降到2维的效果:
在这里插入图片描述
在这里插入图片描述
不知道为什么加了噪声之后,生成的图片反而没有黑点了,有点神奇。

代码:

# coding=utf-8

from keras.datasets import mnist
from keras.layers import Input, Dense, Reshape,Flatten
from keras.models import Sequential, Model
from keras.optimizers import Adam, SGD
from keras.layers.convolutional import UpSampling2D, Conv2D,MaxPooling2D,Conv2DTranspose
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import sys
import os
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data

img_height = 28
img_width = 28
batch_size = 64
mnist = input_data.read_data_sets('../data/MNIST_data', one_hot=True)


def img_to_code(img_input):
    if trained_encoder is not None:
        return trained_encoder.predict(img_input)
    else:
        return img_input
    
def noise(code):
    idx = np.around(np.random.uniform(0.,code.shape[1]-1,size=int(code.shape[1]/5))).astype(np.int)
    noise_code = np.copy(code)
    noise_code[:,idx] = 0
    return noise_code

def train_one_by_one():
    epochs = 3000
    delta = 0
    trained_encoder = None
    layers = [28 * 28, 700, 400, 200, 50,10,2]
    decoders = []
    for i in range(len(layers) - 1):
        
        encoder = Sequential()
        if i == len(layers) -2:
            encoder.add(Dense(units=layers[i + 1]))
        else:
            encoder.add(Dense(units=layers[i + 1],activation='sigmoid'))
        decoder = Sequential()
        decoder.add(Dense(units=layers[i], activation='sigmoid'))
        encoder_input = Input(shape=(layers[i],))
        code = encoder(encoder_input)
        reconstruct_code = decoder(code)
        combined = Model(encoder_input, reconstruct_code)
        optimizer = Adam(0.001)
        combined.compile(loss='mse', optimizer=optimizer)

        for j in range(epochs):
            imgs, _ = mnist.train.next_batch(batch_size)
            # 由之前训练好的encoder 将image转成code  如果没有训练过的encoder 那code就是image
            code = imgs if (trained_encoder is None) else trained_encoder.predict(imgs)
            noise_code = noise(code)
            loss = combined.train_on_batch(noise_code, code)
            if j % 50 == 0:
                print("%d layer,loss:%f"%(i,loss))
                
        # 经过上面的for循环 已经又训练好了一层encoder  将encoder与之前的合并
        if trained_encoder is None:
            trained_encoder = encoder
        else:
            img_input = Input(shape=[img_width * img_height])
            input_code = trained_encoder(img_input)
            code = encoder(input_code)
            trained_encoder = Model(img_input,code)
        
        # 保存当前encoder 对应的decoder
        decoders.append(decoder)
        epochs += delta  #每层增加1000次迭代次数
        
    img_input = Input(shape=[img_width * img_height])
    decoders.reverse()
    last_decode = trained_encoder(img_input)
    for decoder in decoders:
        last_decode = decoder(last_decode)
    combined = Model(img_input, last_decode)
    combined.compile(loss='mse', optimizer=optimizer)
    return trained_encoder,combined

def train(combined,epochs):
    losses = []
    for i in range(epochs):
        imgs, labels = mnist.train.next_batch(batch_size)
        noise_imgs = noise(imgs)
        loss = combined.train_on_batch(noise_imgs, imgs)
        if i >= 20 and i % 5 == 0:
            print("epoch:%d,loss:%f" % (i, loss))
            losses.append(loss)
    plt.plot(np.arange(20, epochs, 5), losses)
    plt.show()

picture_num = 4
def test(combined):
    figure_num = 1
    for _ in range(picture_num):
        imgs, labels = mnist.test.next_batch(3)
        noise_imgs = noise(imgs)
        score = combined.evaluate(noise_imgs, imgs, verbose=0)
        print("Test loss:", score)
        output_imgs = combined.predict(noise_imgs)
        for i in range(3):
            plt.figure(figure_num)
            plt.subplot(2, 3, i + 1)  # 两行一列的第一个子图
            plt.imshow(noise_imgs[i].reshape((28, 28)), cmap='gray')
            plt.subplot(2, 3, i + 1 + 3)  # 两行一列的第二个子图
            plt.imshow(output_imgs[i].reshape((28, 28)), cmap='gray')
        figure_num += 1

def plot_low_dimension():
    imgs, labels = mnist.test.next_batch(3000)
    labels = np.transpose(np.nonzero(labels))[:,1]
    codes = encoder.predict(imgs)
    plt.figure(10)
    i = 0
    for color in ['red','blue','green','black','chocolate','silver','lawngreen','darkcyan','lawngreen','c']:
        y = (labels.T == i)
        x = codes[y]
        plt.scatter(x[:,0],x[:,1],c=color,label=str(i),alpha=0.6,edgecolors='white')
        i+=1
    plt.title('Scatter')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.legend(loc='best')
    plt.show()
    
def plot_3d():
    imgs, labels = mnist.test.next_batch(3000)
    labels = np.transpose(np.nonzero(labels))[:,1]
    codes = encoder.predict(imgs)
    plt.figure(4)
    ax = Axes3D(fig)
    i = 0
    for color in ['red','blue','green','black','chocolate','silver','lawngreen','darkcyan','lawngreen','c']:
        y = (labels.T == i)
        x = codes[y]
        plt.scatter(x[:,0],x[:,1],x[:,2],c=color,label=str(i),alpha=0.6,edgecolors='white')
        i+=1

    # 绘制图例
    ax.legend(loc='best')


    # 添加坐标轴(顺序是Z, Y, X)
    ax.set_zlabel('Z', fontdict={'size': 15, 'color': 'red'})
    ax.set_ylabel('Y', fontdict={'size': 15, 'color': 'red'})
    ax.set_xlabel('X', fontdict={'size': 15, 'color': 'red'})

    # 展示
    plt.show()

if __name__ == '__main__':
    encoder, combined = train_one_by_one()
    train(combined, 6000)
    test(combined)
    
#     plot_low_dimension()

  • 3
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Stacked Denoising Autoencoder (Sdae) 是一种无监督学习方法,用于学习数据的低维表示。它是一种深度学习方法,由多个堆叠的自编码器组成,每个自编码器都学习数据的不同层次的特征表示。在训练过程中,每个自编码器都会对输入数据进行降噪处理,以增强其鲁棒性。 在 TensorFlow.Keras 框架下,可以使用 `tf.keras` 库来实现 Sdae 模型。以下是一个简单的 Sdae 模型示例代码: ```python from tensorflow.keras.layers import Input, Dense from tensorflow.keras.models import Model # 定义输入层 input_layer = Input(shape=(784,)) # 定义编码器层 encoded = Dense(128, activation='relu')(input_layer) encoded = Dense(64, activation='relu')(encoded) encoded = Dense(32, activation='relu')(encoded) # 定义解码器层 decoded = Dense(64, activation='relu')(encoded) decoded = Dense(128, activation='relu')(decoded) decoded = Dense(784, activation='sigmoid')(decoded) # 定义 Sdae 模型 sdae = Model(inputs=input_layer, outputs=decoded) # 编译 Sdae 模型 sdae.compile(optimizer='adam', loss='binary_crossentropy') ``` 在上面的代码中,我们定义了一个三层编码器和三层解码器的 Sdae 模型。编码器层由三个具有 ReLU 激活函数的 Dense 层组成,解码器层由三个 Dense 层组成,其中最后一层使用 Sigmoid 激活函数。我们使用二元交叉熵作为损失函数,并使用 Adam 优化器进行训练。 接下来,我们可以使用 `fit()` 方法训练模型: ```python # 训练 Sdae 模型 sdae.fit(x_train, x_train, epochs=10, batch_size=256, shuffle=True) ``` 在上面的代码中,我们使用 `x_train` 作为输入和输出数据,训练模型 10 个 epochs,使用批量大小为 256 进行训练,并在每个 epoch 之前打乱数据的顺序。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值