Структура автоэнкодера
Auto Encoder — это модель нейронной сети. Он состоит из двух частей: кодера (Ecoder) и декодера (Decoder).
КодерОн используется для кодирования входных данных (входных данных), чтобы отобразить входные данные в скрытое пространство (скрытое пространство) с меньшим размером и получить закодированные данные (кодированные данные).
декодерИспользуется для восстановления (декодирования) данных, закодированных в скрытом пространстве, в «входные данные». Причина кавычек здесь в том, что восстановленные «входные данные» будут иметь некоторые потери по сравнению с исходными входными данными, поэтому это не настоящие входные данные.
На следующем рисунке показана структура автоэнкодера.
Приложения автоэнкодеров
Уменьшение размерности данных/извлечение признаков
Такое использование автоэнкодера легко представить по его структуре. На этапе обучения,После отображения кодировщика низкоразмерный,Восстановлено декодером иПостоянные размеры, похожий контент, обновите веса сети обратным распространением, чтобы свести к минимуму вводи выводпотери между ними.
один из нихэто данные после уменьшения размерности, потому что если вы можете передатьвосстановить ввод, то можно сказать, чтоуже выучилбольшинство характеристик.
в то же время,представляет собой сильно сжатое (уменьшение размера) представление входных данных, поэтому автоэнкодер также можно рассматривать как экстрактор признаков, а представление извлеченных признаков.
Шумоподавление изображения
Шумоподавление изображения заключается в удалении шума из изображения. Например, левая половина изображения ниже — это изображение без шума, а правая половина — с шумом. Наша цель состоит в том, чтобы обучить автоэнкодер, ввод которого представляет собой зашумленное изображение, а вывод — изображение с шумоподавлением, таким образом достигая цели устранения шума.
Метод обучения также очень прост. Подготовьте несколько изображений без шума, а затем вручную добавить шум к этим изображениям, чтобы получить соответствующие изображения с шумом. будетВход в кодировщик, а затем в декодер, чтобы получить вывод, обновите веса с помощью обратного распространения, чтобы свести к минимумуипотери между ними. Таким образом, выводбудет почти бесшумным, который достигает цели снижения шума.
В приложении просто введите зашумленное изображение в обученный автоэнкодер, чтобы получить выходное изображение без шумов.
Изображение "сгенерировано"
Фактически, введение изображения «генерация» было включено во введение двух предыдущих приложений. Удалите энкодер из обученного автоэнкодера, а остаток можно рассматривать как «генератор». Низкоразмерное представление входного скрытого пространства, сгенерированное изображение может быть получено через декодер.
Однако есть проблема. Взяв изображение в качестве примера, ранее закодированные функции скрытого пространстваВход в декодер, декодер будет выводить иСоответствующий вход аналогичен картинке, и если мы попытаемся ввести в декодер случайный шум, соответствующий размерности скрытого пространства, мы получим бессмысленную шумовую картину.
Поэтому "поколение" здесь не совсем поколение, а точнее должно быть "перестроение".
Вариационные автоэнкодеры могут исправить этот недостаток, о котором мы поговорим в следующей статье.
Написать автоэнкодер в Pytorch
Теперь обучите автоэнкодер, используя набор данных рукописных цифр.
Набор данных рукописных цифр изначально состоял из нескольких, здесь мы обучаем полносвязную нейронную сеть, поэтому используем сглаженныйразмерные характеристики. То есть, если естькартинка, то наши данныеshape
этоРядСписок.
Сначала импортируйте необходимые библиотеки:
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import matplotlib.pyplot as plt
import numpy as np
Затем подготовьте набор данных рукописных цифр:
transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
train_dataset = torchvision.datasets.MNIST(
root="torch_datasets", train=True, transform=transform, download=True
)
test_dataset = torchvision.datasets.MNIST(
root="torch_datasets", train=False, transform=transform, download=True
)
train_loader = torch.utils.data.DataLoader(
train_dataset, batch_size=128, shuffle=True, num_workers=4, pin_memory=True
)
test_loader = torch.utils.data.DataLoader(
test_dataset, batch_size=32, shuffle=False, num_workers=4
)
Приведенный выше код автоматически загрузит набор данных из сети в указанныйroot
под дорожкой.
Затем создайте сеть автоэнкодера:
class AE(nn.Module):
def __init__(self, **kwargs):
super().__init__()
#编码器
self.encoder_hidden_layer = nn.Linear(
in_features=kwargs["input_shape"], out_features=128)
self.encoder_output_layer = nn.Linear(
in_features=128, out_features=128)
#解码器
self.decoder_hidden_layer = nn.Linear(
in_features=128, out_features=128)
self.decoder_output_layer = nn.Linear(
in_features=128, out_features=kwargs["input_shape"])
def forward(self, features):
#编码器
activation = torch.relu(self.encoder_hidden_layer(features))
code = torch.relu(self.encoder_output_layer(activation))
#解码器
activation = torch.relu(self.decoder_hidden_layer(code))
reconstructed = torch.relu(self.decoder_output_layer(activation))
#返回重建的图像
return reconstructed
Задайте еще несколько параметров:
#设定随机种子,让每次的结果都一样
#原因:Pytorch的某些操作具有随机性
seed = 42
torch.manual_seed(seed)
torch.backends.cudnn.benchmark = False
torch.backends.cudnn.deterministic = True
#设置 迭代轮数,学习率
epochs = 20
learning_rate = 1e-3
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = AE(input_shape=784).to(device)
#使用Adam优化器
optimizer = optim.Adam(model.parameters(), lr=1e-3)
#使用均方误差作为损失函数
criterion = nn.MSELoss()
Начать обучение:
for epoch in range(epochs):
loss = 0
for batch_features, _ in train_loader:
#将N张*28*28的图片打平成N张784维的特征向量
batch_features = batch_features.view(-1, 784).to(device)
optimizer.zero_grad()
# 前向传播
outputs = model(batch_features)
# 计算损失
train_loss = criterion(outputs, batch_features)
# 反向传播计算梯度
train_loss.backward()
# 更新网络权重
optimizer.step()
# 损失累加
loss += train_loss.item()
# 计算本轮损失
loss = loss / len(train_loader)
# 进度条
print("epoch : {}/{}, loss = {:.6f}".format(epoch + 1, epochs, loss))
Видно, что потери постепенно уменьшаются.
После завершения обучения используйте первую партию тестового набора для тестирования:
#取第一个batch进行测试
with torch.no_grad():
for batch_features in test_loader:
# 只取图片,不取标签
batch_features = batch_features[0]
# 打平
test_examples = batch_features.view(-1, 784).to(device)
# 前向推理
reconstruction = model(test_examples)
break
reconstruction
Содержит 32 реконструированных изображения, каждое из которых представлено 784-мерными признаками. Теперь давайте визуализируем и сравним изображения до и после реконструкции.Обратите внимание, что для восстановленного изображения нам нужно изменить его форму обратно к.
with torch.no_grad():
number = 10
plt.figure(figsize=(20, 4))
for index in range(number):
# 可视化原始图片
ax = plt.subplot(2, number, index + 1)
plt.imshow(test_examples[index].cpu().numpy().reshape(28, 28))
plt.gray()
#不显示坐标轴
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# 可视化重建后的图片
ax = plt.subplot(2, number, index + 1 + number)
plt.imshow(reconstruction[index].cpu().numpy().reshape(28, 28))# on gpu
plt.gray()
#不显示坐标轴
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
Выходное изображение получается следующим образом:
Первая строка — исходное изображение, а вторая строка — реконструированное изображение, соответствующее первой строке. Видно, что реконструированное изображение в основном совпадает с контуром исходного изображения, но есть некоторые потери, которые проявляются на рисунке в виде маленьких черных точек.
Эта статья была впервые опубликована в публичном аккаунте WeChat:Я найду тебя в Антарктиде, публичная учетная запись, которая отправляет только галантерею, нижняя панель меню полна галантерейных товаров, обратите внимание!
Ссылаться на:
[2][woohoo.comp three.com/blog/auto ru…]