Tensorflow2.0 无监督学习自编码Auto Encoder

在这里插入图片描述
具体实现:

import os

import numpy as np
import tensorflow as tf
from PIL import Image

print(tf.__version__)
print(np.__version__)

# 自增长
gpus = tf.config.experimental.list_physical_devices('GPU')
print(gpus)
for gpu in gpus:
    tf.config.experimental.set_memory_growth(gpu, True)


# 保存图片 10 * 10 矩阵图片
def save_images(imgs, name):
    new_im = Image.new('L', (280, 280))
    index = 0
    for i in range(0, 280, 28):
        for j in range(0, 280, 28):
            im = imgs[index]
            im = Image.fromarray(im, mode='L')
            new_im.paste(im, (i, j))
            index += 1
    new_im.save(name)


# 中间层宽度
h_dim = 20
batch_size = 512

# 数据集加载与变换
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
x_train = x_train.astype(np.float32) / 255.
x_test = x_test.astype(np.float32) / 255.

train_db = tf.data.Dataset.from_tensor_slices(x_train)
train_db = train_db.shuffle(batch_size * 5).batch(batch_size)

test_db = tf.data.Dataset.from_tensor_slices(x_test)
test_db = test_db.batch(batch_size)

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)


# auto encoder 自编码模型类
class AE(tf.keras.Model):
    def __init__(self):
        super(AE, self).__init__()

        # Encoders 编码网络
        self.encoder = tf.keras.Sequential([
            tf.keras.layers.Dense(256, activation=tf.nn.relu),
            tf.keras.layers.Dense(128, activation=tf.nn.relu),
            tf.keras.layers.Dense(h_dim)
        ])

        # Decoders 解码网络
        self.decoder = tf.keras.Sequential([
            tf.keras.layers.Dense(128, activation=tf.nn.relu),
            tf.keras.layers.Dense(256, activation=tf.nn.relu),
            tf.keras.layers.Dense(784)
        ])

    def call(self, inputs, training=None, mask=None):
        # 编码
        # [b, 784] ==> [b, 20]
        h = self.encoder(inputs)

        # 解码
        # [b, 20] ==> [b, 784]
        x_hat = self.decoder(h)

        return x_hat


# 模型的创建与编译、显示
model = AE()
model.build(input_shape=(None, 784))
model.summary()

lr = 1e-3
# 优化器
optimizer = tf.keras.optimizers.Adam(lr=lr)

for epoch in range(100):
    for step, x in enumerate(train_db):
        # [b, 28, 28] => [b, 784]
        x = tf.reshape(x, [-1, 784])
        # 梯度计算
        with tf.GradientTape() as tape:
            # 前向传播
            x_rec_logits = model(x)

            # 损失计算
            rec_loss = tf.losses.binary_crossentropy(x, x_rec_logits, from_logits=True)
            rec_loss = tf.reduce_mean(rec_loss)
        # 梯度计算 更新参数
        grads = tape.gradient(rec_loss, model.trainable_variables)
        optimizer.apply_gradients(zip(grads, model.trainable_variables))

        if step % 100 == 0:
            print(epoch, step, float(rec_loss))

    # 测试数据集 自动编码测试
    x = next(iter(test_db))
    logits = model(tf.reshape(x, [-1, 784]))
    x_hat = tf.sigmoid(logits)
    # [b, 784] => [b, 28, 28]
    x_hat = tf.reshape(x_hat, [-1, 28, 28])

    x_concat = tf.concat([x, x_hat], axis=0)
    x_concat = x_hat
    x_concat = x_concat.numpy() * 255
    x_concat = x_concat.astype(np.uint8)

    # 保存图片
    if os.path.exists('./ae_images') is False:
        os.mkdir('./ae_images')
    save_images(x_concat, 'ae_images/rec_epoch_%d.png' % epoch)

处理结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45875105/article/details/112276254