具体实现:
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)
处理结果: