gpt4 book ai didi

machine-learning - MXNet - GAN 在 MNIST 中的应用

转载 作者:行者123 更新时间:2023-11-30 09:34:19 25 4
gpt4 key购买 nike

所以这个问题是关于 GANs .

我正在尝试为我自己的概念证明做一个简单的例子;即生成手写数字的图像(MNIST)。虽然大多数人会通过深度卷积甘斯 (dgGAN) 来实现这一点,但我只是尝试通过 1D 数组(即 28*28 1d 数组而不是 28x28 灰度像素值)来实现这一点。

这个git repo具有“vanilla”gans,它将 MNIST 数据集视为包含 784 个值的一维数组。它们的输出值看起来相当可以接受,所以我想做类似的事情。

导入语句

from __future__ import print_function
import matplotlib as mpl
from matplotlib import pyplot as plt
import mxnet as mx
from mxnet import nd, gluon, autograd
from mxnet.gluon import nn, utils
import numpy as np
import os
from math import floor
from random import random
import time
from datetime import datetime
import logging


ctx = mx.gpu()
np.random.seed(3)

超参数

batch_size = 100
epochs = 100
generator_learning_rate = 0.001
discriminator_learning_rate = 0.001
beta1 = 0.5
latent_z_size = 100

加载数据

mnist = mx.test_utils.get_mnist()
# convert imgs to arrays
flattened_training_data = mnist["test_data"].reshape(10000, 28*28)

定义模型

G = nn.Sequential()
with G.name_scope():
G.add(nn.Dense(300, activation="relu"))
G.add(nn.Dense(28 * 28, activation="tanh"))

D = nn.Sequential()
with D.name_scope():
D.add(nn.Dense(128, activation="relu"))
D.add(nn.Dense(64, activation="relu"))
D.add(nn.Dense(32, activation="relu"))
D.add(nn.Dense(2, activation="tanh"))


loss = gluon.loss.SoftmaxCrossEntropyLoss()

初始化东西

G.initialize(mx.init.Normal(0.02), ctx=ctx)
D.initialize(mx.init.Normal(0.02), ctx=ctx)
trainer_G = gluon.Trainer(G.collect_params(), 'adam', {"learning_rate": generator_learning_rate, "beta1": beta1})
trainer_D = gluon.Trainer(D.collect_params(), 'adam', {"learning_rate": discriminator_learning_rate, "beta1": beta1})

metric = mx.metric.Accuracy()

动态图(适用于 juptyer 笔记本)

import matplotlib.pyplot as plt
import time

def dynamic_line_plt(ax, y_data, colors=['r', 'b', 'g'], labels=['Line1', 'Line2', 'Line3']):
x_data = []
y_max = 0
y_min = 0
x_min = 0
x_max = 0
for y in y_data:
x_data.append(list(range(len(y))))
if max(y) > y_max:
y_max = max(y)
if min(y) < y_min:
y_min = min(y)

if len(y) > x_max:
x_max = len(y)

ax.set_ylim(y_min, y_max)
ax.set_xlim(x_min, x_max)

if ax.lines:
for i, line in enumerate(ax.lines):
line.set_xdata(x_data[i])
line.set_ydata(y_data[i])

else:
for i in range(len(y_data)):
l = ax.plot(x_data[i], y_data[i], colors[i], label=labels[i])
ax.legend()

fig.canvas.draw()

火车

stamp = datetime.now().strftime('%Y_%m_%d-%H_%M')
logging.basicConfig(level=logging.DEBUG)


# arrays to store data for plotting
loss_D = nd.array([0], ctx=ctx)
loss_G = nd.array([0], ctx=ctx)
acc_d = nd.array([0], ctx=ctx)
labels = ['Discriminator Loss', 'Generator Loss', 'Discriminator Acc.']

%matplotlib notebook
fig, ax = plt.subplots(1, 1)
ax.set_xlabel('Time')
ax.set_ylabel('Loss')
dynamic_line_plt(ax, [loss_D.asnumpy(), loss_G.asnumpy(), acc_d.asnumpy()], labels=labels)


for epoch in range(epochs):
tic = time.time()

data_iter.reset()

for i, batch in enumerate(data_iter):
####################################
# Update Disriminator: maximize log(D(x)) + log(1-D(G(z)))
####################################

# extract batch of real data
data = batch.data[0].as_in_context(ctx)
# add noise


# Produce our noisey input to the generator
latent_z = mx.nd.random_normal(0,1,shape=(batch_size, latent_z_size), ctx=ctx)


# soft and noisy labels
# real_label = mx.nd.ones((batch_size, ), ctx=ctx) * nd.random_uniform(.7, 1.2, shape=(1)).asscalar()
# fake_label = mx.nd.ones((batch_size, ), ctx=ctx) * nd.random_uniform(0, .3, shape=(1)).asscalar()

# real_label = nd.random_uniform(.7, 1.2, shape=(batch_size), ctx=ctx)
# fake_label = nd.random_uniform(0, .3, shape=(batch_size), ctx=ctx)

real_label = mx.nd.ones((batch_size, ), ctx=ctx)
fake_label = mx.nd.zeros((batch_size, ), ctx=ctx)

with autograd.record():
# train with real data
real_output = D(data)
errD_real = loss(real_output, real_label)

# train with fake data
fake = G(latent_z)
fake_output = D(fake.detach())
errD_fake = loss(fake_output, fake_label)

errD = errD_real + errD_fake
errD.backward()

trainer_D.step(batch_size)
metric.update([real_label, ], [real_output,])
metric.update([fake_label, ], [fake_output,])


####################################
# Update Generator: maximize log(D(G(z)))
####################################
with autograd.record():
output = D(fake)
errG = loss(output, real_label)
errG.backward()

trainer_G.step(batch_size)



####
# Plot Loss
####
# append new data to arrays
loss_D = nd.concat(loss_D, nd.mean(errD), dim=0)
loss_G = nd.concat(loss_G, nd.mean(errG), dim=0)
name, acc = metric.get()
acc_d = nd.concat(acc_d, nd.array([acc], ctx=ctx), dim=0)

# plot array
dynamic_line_plt(ax, [loss_D.asnumpy(), loss_G.asnumpy(), acc_d.asnumpy()], labels=labels)



name, acc = metric.get()
metric.reset()
logging.info('Binary training acc at epoch %d: %s=%f' % (epoch, name, acc))
logging.info('time: %f' % (time.time() - tic))

输出

img = G(mx.nd.random_normal(0,1,shape=(100, latent_z_size), ctx=ctx))[0].reshape((28, 28))
plt.imshow(img.asnumpy(),cmap='gray')
plt.show()

enter image description here

现在这并不像上面的存储库示例那么好。虽然相当相似。

因此我想知道您是否可以看一下并找出原因:

  1. 颜色反转
  2. 为什么结果低于标准

我一直在摆弄这个问题,尝试了很多不同的方法来改进结果(我将在一秒钟内列出它),但对于 MNIST 数据集来说,这确实不需要。

我尝试过的事情(我也尝试过很多组合):

  • 增加发电机网络
  • 增加鉴别器网络
  • 使用软标签
  • 使用噪声标签
  • 生成器中每一层之后的批量归一化
  • 数据的批量归一化
  • 标准化 -1 到 1 之间的所有值
  • 生成器中的 relus 泄漏
  • 删除生成器中的图层
  • 与生成器相比,判别器的学习率更高
  • 与生成器相比,i 的学习率降低

如果您有任何想法,请告诉我。

最佳答案

1)如果你查看原始数据集:

training_set = mnist["train_data"].reshape(60000, 28, 28)
plt.imshow(training_set[10,:,:], cmap='gray')

您会注意到数字是黑色背景上的白色。因此,从技术上讲,您的结果不是相反的 - 它们与您用作真实数据的原始图像的模式相匹配。

如果您想反转颜色以实现可视化目的,您可以通过添加“_r”将调色板更改为反转颜色来轻松实现这一点(它适用于所有调色板):

plt.imshow(img.asnumpy(), cmap='gray_r')

您还可以通过更改 vmin 和 vmax 参数来调整颜色范围。它们控制颜色之间的差异应该有多大。默认情况下,它是根据提供的集自动计算的。

2) “为什么结果低于标准” - 我认为这正是社区开始使用 dcGAN 的原因。对我来说,您提供的 git 存储库中的结果非常嘈杂。当然,它们与您收到的不同,您只需将激活函数从 tanh 更改为 sigmoid 即可实现相同的质量,如 github 上的示例所示:

G = nn.Sequential()
with G.name_scope():
G.add(nn.Dense(300, activation="relu"))
G.add(nn.Dense(28 * 28, activation="sigmoid"))

D = nn.Sequential()
with D.name_scope():
D.add(nn.Dense(128, activation="relu"))
D.add(nn.Dense(64, activation="relu"))
D.add(nn.Dense(32, activation="relu"))
D.add(nn.Dense(2, activation="sigmoid"))

Sigmoid never goes below zero在这种情况下效果更好。这是如果我训练更新后的模型 30 个 epoch 时得到的示例图片(其余超参数相同)。

enter image description here

如果您决定探索 dcGAN 以获得更好的结果,请查看此处 - https://mxnet.incubator.apache.org/tutorials/unsupervised_learning/gan.html这是关于如何使用 Mxnet 和 Gluon 构建 dcGAN 的详细解释的教程。通过使用 dcGAN,您将获得比这更好的结果。

关于machine-learning - MXNet - GAN 在 MNIST 中的应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47081667/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com