Список работ

Автокодировщик MNIST

Содержание

Реализация

Приводится пример реализации на Keras автокодировщика, обучаемого на MNIST генерировать изображения рукописных цифр (рис. 1).

Исходные и сгенерированные цифры

Рис. 1. Исходные и сгенерированные цифры

На вход обученного автокодировщика подаются случайно выбранные изображения проверочного множества MNIST (рис. 1, а), на выходе модель с определенной точностью воспроизводит эти изображения (рис. 1, б).
MNIST загружается из библиотеки tensorflow.keras.datasets:

from tensorflow.keras.datasets import mnist
(x_trn, y_trn), (x_tst, y_tst) = mnist.load_data()
x_trn = x_trn / 255
x_tst = x_tst / 255
len_tst = len(y_tst)
x_trn = x_trn.reshape(len(y_trn), 784)
x_tst = x_tst.reshape(len_tst, 784)

После загрузки выводится случайный пример из обучающего множества:

from matplotlib import pyplot as plt
import numpy as np
# Случайное изображение элемента обучающего множества
i = np.random.randint(len(y_trn))
img = x_trn[i].reshape(28, 28)
def one_plt(img):
    plt.figure(figsize = (2, 2))
    plt.imshow(img, cmap = 'gray')
    plt.axis('off')
    plt.show()
one_plt(img)

Кодер и декодер автокодировщика построены из блоков, формируемых процедурой one_part:

from tensorflow.keras.layers import Input, Dense, LeakyReLU, Dropout
from tensorflow.keras.models import Model
def one_part(units, x):
    x = Dense(units)(x)
    x = LeakyReLU()(x)
    return Dropout(0.25)(x)

Формирование модели автокодировщика:

latent_size = 32 # Размер латентного пространста
inp = Input(shape = (784))
x = one_part(512, inp)
x = one_part(256, x)
x = one_part(128, x)
x = one_part(64, x)
x = Dense(latent_size)(x)
encoded = LeakyReLU()(x)
x = one_part(64, encoded)
x = one_part(128, x)
x = one_part(256, x)
x = one_part(512, x)
decoded = Dense(784, activation = 'sigmoid')(x)
model = Model(inputs = inp, outputs = decoded)
model.compile('adam', loss = 'binary_crossentropy') # nadam
model.summary()

Используемая функция потерь – binary_crossentropy
Состав модели показан в табл. 1:

Layer (type)Output ShapeParam #
input_1 (InputLayer)[(None, 784)]0
dense (Dense)(None, 512)401920
leaky_re_lu (LeakyReLU)(None, 512)0
dropout (Dropout)(None, 512)0
dense_1 (Dense)(None, 256)131328
leaky_re_lu_1 (LeakyReLU)(None, 256)0
dropout_1 (Dropout)(None, 256)0
dense_2 (Dense)(None, 128)32896
leaky_re_lu_2 (LeakyReLU)(None, 128)0
dropout_2 (Dropout)(None, 128)0
dense_3 (Dense)(None, 64)8256
leaky_re_lu_3 (LeakyReLU)(None, 64)0
dropout_3 (Dropout)(None, 64)0
dense_4 (Dense)(None, 32)2080
leaky_re_lu_4 (LeakyReLU)(None, 32)0
dense_5 (Dense)(None, 64)2112
leaky_re_lu_5 (LeakyReLU)(None, 64)0
dropout_4 (Dropout)(None, 64)0
dense_6 (Dense)(None, 128)8320
leaky_re_lu_6 (LeakyReLU)(None, 128)0
dropout_5 (Dropout)(None, 128)0
dense_7 (Dense)(None, 256)33024
leaky_re_lu_7 (LeakyReLU)(None, 256)0
dropout_6 (Dropout)(None, 256)0
dense_8 (Dense)(None, 512)131584
leaky_re_lu_8 (LeakyReLU)(None, 512)0
dropout_7 (Dropout)(None, 512)0
dense_9 (Dense)(None, 784)402192
Total params: 1,153,712
Trainable params: 1,153,712
Non-trainable params: 0

На вход модели подается изображение MNIST. Задача кодировщика – повторить это изображение.
Цикл обучения:

import numpy as np
plt_epoch = not False
epochs = 90 # Число эпох
for epoch in range(epochs):
    print('epoch:', epoch + 1)
    model.fit(x = x_trn, y = x_trn)
    # Выводим, если работаем в IPython, Jupyter или Colab
    if plt_epoch and epoch > 0 and epoch % 5 == 0:
        display.clear_output()
        arr_idx = np.random.randint(0, len_tst, 16) # class 'numpy.ndarray'
        imgs_for_test = x_tst[arr_idx].reshape(16, 784) # class 'numpy.ndarray'
        some_plts(imgs_for_test)
        imgs_pedicted = model.predict(imgs_for_test)
        some_plts(imgs_pedicted) # imgs_pedicted.shape = (16, 784)

Если plt_epoch = True, то после каждой 5-й эпохи будeт показаны эталонные и генерируемые изображения (см. рис. 1). Используется следующая процедура:

from matplotlib import pyplot as plt
# Для очистки области вывода в IPython, Jupyter, Colab
from IPython import display
def some_plts(imgs):
    fig, axs = plt.subplots(4, 4)
    k = -1
    for i in range(4):
        for j in range(4):
            k += 1
            img = imgs[k].reshape(28, 28)
            axs[i, j].imshow(img, cmap = 'gray')
            axs[i, j].axis('off')
    plt.subplots_adjust(wspace = 1, hspace = 0)
    plt.show()

Задания

С использованием приведенных сведений студентам надлежит:

Полный код программы

# https://towardsdatascience.com/how-to-make-an-autoencoder-2f2d99cd5103
# https://habr.com/ru/post/417405/
from sys import exit
from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Input, Dense, LeakyReLU, Dropout
from tensorflow.keras.models import Model
from matplotlib import pyplot as plt
# Для очистки области вывода в IPython, Jupyter, Colab
from IPython import display
import numpy as np
plt_epoch = not False
epochs = 90
(x_trn, y_trn), (x_tst, y_tst) = mnist.load_data()
x_trn = x_trn / 255
x_tst = x_tst / 255
len_tst = len(y_tst)
x_trn = x_trn.reshape(len(y_trn), 784)
x_tst = x_tst.reshape(len_tst, 784)
# Случайное изображение элемента обучающего множества
i = np.random.randint(len(y_trn))
img = x_trn[i].reshape(28, 28)
def one_plt(img):
    plt.figure(figsize = (2, 2))
    plt.imshow(img, cmap = 'gray')
    plt.axis('off')
    plt.show()
one_plt(img)
def one_part(units, x):
    x = Dense(units)(x)
    x = LeakyReLU()(x)
    return Dropout(0.25)(x)
latent_size = 32 # Размер латентного пространста
inp = Input(shape = (784))
x = one_part(512, inp)
x = one_part(256, x)
x = one_part(128, x)
x = one_part(64, x)
x = Dense(latent_size)(x)
encoded = LeakyReLU()(x)
x = one_part(64, encoded)
x = one_part(128, x)
x = one_part(256, x)
x = one_part(512, x)
decoded = Dense(784, activation = 'sigmoid')(x)
model = Model(inputs = inp, outputs = decoded)
model.compile('adam', loss = 'binary_crossentropy') # nadam
# model.summary()
def some_plts(imgs):
    fig, axs = plt.subplots(4, 4)
    k = -1
    for i in range(4):
        for j in range(4):
            k += 1
            img = imgs[k].reshape(28, 28)
            axs[i, j].imshow(img, cmap = 'gray')
            axs[i, j].axis('off')
    plt.subplots_adjust(wspace = 1, hspace = 0)
    plt.show()
for epoch in range(epochs):
    print('epoch:', epoch + 1)
    model.fit(x = x_trn, y = x_trn)
    # Выводим, если работаем в IPython, Jupyter или Colab
    if plt_epoch and epoch > 0 and epoch % 5 == 0:
        display.clear_output()
        arr_idx = np.random.randint(0, len_tst, 16) # class 'numpy.ndarray'
        imgs_for_test = x_tst[arr_idx].reshape(16, 784) # class 'numpy.ndarray'
        some_plts(imgs_for_test)
        imgs_pedicted = model.predict(imgs_for_test)
        some_plts(imgs_pedicted) # imgs_pedicted.shape = (16, 784)
# Прогноз из шума
# img = np.random.uniform(0, 1, 16 * 784).reshape(16, 784)
# imgs_pedicted = model.predict(img)
# some_plts(imgs_pedicted)

Список работ

Рейтинг@Mail.ru