A quiz on the autoencoder on the fashion_mnist dataset

1. Data set acquisition

In the pyfile, use (x_train, y_train), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()can be used to automatically download and automatically read the data set. However, the download process is slow and easily interrupted. Therefore, it is directly downloaded from the download address printed in the console. The download address is briefly organized as follows:

name description address
train-images-idx3-ubyte.gz Training set image here
train-labels-idx1-ubyte.gz Training set label here
t10k-images-idx3-ubyte.gz Test set image here
t10k-labels-idx1-ubyte.gz Test set label here

2. Data set reading

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


# 1. 加载数据集
def load_data(path='data/fashion_mnist/'):
    def __load_mnist__(path, kind='train'):
        labels_path = os.path.join(path, '%s-labels-idx1-ubyte.gz' % kind)
        images_path = os.path.join(path, '%s-images-idx3-ubyte.gz' % kind)

        with gzip.open(labels_path, 'rb') as lbpath:
            labels = np.frombuffer(lbpath.read(), dtype=np.uint8, offset=8)

        with gzip.open(images_path, 'rb') as imgpath:
            images = np.frombuffer(imgpath.read(), dtype=np.uint8, offset=16).reshape(len(labels), 784)
        return images, labels
    train_images, train_lables = __load_mnist__(path, kind="train")
    test_images, test_lables = __load_mnist__(path, kind="t10k")
    return (train_images, train_lables), (test_images, test_lables)

(x_train, y_train), (x_test, y_test) = load_data()
# print(x_train.shape) # (60000, 784)
# print(y_train.shape) # (60000,)
# print(type(x_train)) # 'numpy.ndarray'

After reading the data set, you might as well simply draw a picture:

# 不妨简单显示
import matplotlib.pyplot as plt
image_0 = np.resize(x_train[0], (int(math.sqrt(x_train.shape[1])),int(math.sqrt(x_train.shape[1]))))
plt.imshow(image_0)

Insert picture description here
Then, simply process the data set:

# 2. 数据简单处理
x_train, x_test = x_train.astype(np.float32) / 255, x_test.astype(np.float32) / 255 # 将0-255数据简单归一化到0-1

train_x = tf.data.Dataset.from_tensor_slices(x_train) # 将array转化为tensor
# 从data数据集中按顺序抽取buffer_size个样本放在buffer中,然后打乱buffer中的样本
# buffer中样本个数不足buffer_size,继续从data数据集中安顺序填充至buffer_size,
# 此时会再次打乱
train_x = train_x.shuffle(buffer_size=512 * 3)
# 每次从buffer中抽取batch_size个样本
train_x = train_x.batch(batch_size=512)

test_x = tf.data.Dataset.from_tensor_slices(x_test).batch(batch_size=512)

Start the preparation of a simple self-encoder:

hdim = 20

class AE(tf.keras.Model):
    def __init__(self):
        super(AE, self).__init__()

        self.encoder = tf.keras.Sequential([
            # [d, 784] => [d, 512]
            tf.keras.layers.Dense(512, activation=tf.nn.relu),
            # [d, 512] = > [d, 256]
            tf.keras.layers.Dense(256, activation=tf.nn.relu),
            # [d, 256] => [d, hdim]
            tf.keras.layers.Dense(hdim)
        ])
        
        self.decoder = tf.keras.Sequential([
            tf.keras.layers.Dense(256, activation=tf.nn.relu),
            tf.keras.layers.Dense(512, activation=tf.nn.relu),
            tf.keras.layers.Dense(784)
        ])
    
    def call(self, inputs):
        # 前向传播
        h = self.encoder(inputs)
        x_hat = self.decoder(h)
        return x_hat

# 使用
model = AE()
model.build(input_shape=(None, 784))
model.summary()

Insert picture description here
Then, you can start training:

epoch = 5
lr = 1e-3
optimizer = tf.keras.optimizers.Adam(lr)

def save_images(imgs, name):
    im = Image.new("L", (280, 280))
    index = 0
    for i in range(0, 280, 28):
        for j in range(0, 280, 28):
            t_im = imgs[index]
            t_im = Image.fromarray(t_im, mode="L")
            im.paste(t_im, (i, j))
            index += 1
    im.save(name)

for epoch in range(epoch):
    for step, x in enumerate(train_x):
        with tf.GradientTape() as tape:
            # 前向传播过程
            x_rec = model(x)
            # 损失函数定义
            loss = tf.losses.binary_crossentropy(x, x_rec, from_logits=True)
            loss = tf.reduce_mean(loss)
        grads = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(grads, model.trainable_variables))
        
        if step % 200 == 0:
            print(epoch, step, float(loss))
        
        #evaluation
        x = next(iter(test_x))
        logits = model(x)
        x_hat = tf.sigmoid(logits)
        # 对比存储
        x_before = tf.reshape(x, [-1, 28, 28])
        x_before = x_before.numpy() * 255
        x_before = x_before.astype(np.uint8)
        save_images(x_before, "before_%d.png"%epoch)
        
        x_after = tf.reshape(x_hat, [-1, 28, 28])
        x_after = x_after.numpy() * 255
        x_after = x_after.astype(np.uint8)
        save_images(x_after, "after_%d.png"%epoch) 

May wish to open the two pictures before and after training: it is
Insert picture description here
obviously blurred.

Guess you like

Origin blog.csdn.net/qq_26460841/article/details/113880274