<jupyter_start><jupyter_text>Assignment - ⭐ EmojiGAN ⭐Using the provided "minimum viable GAN" code, train a pair of networks to generate emoji. To get you started, here's some emoji data:**Your goal** - *train a GAN that makes new emoji!*The good news - the data is naturally 28x28, which is the same size as the earlier example (resulting in an input layer size of $28 \times 28=784$). It's big enough to kinda look like a thing, but small enough to be feasible to train with limited resources.The bad news - the emoji are 4 layer PNGs (RGBA), and grayscale conversion is inconsistent at best (the above looks pretty good, but experiment and you'll see). It's OK to convert to grayscale and train that way to start (since it'll pretty much drop in to the example code with minimal modification), but you may want to see if you can figure out handling all 4 layers of the input image (basically - growing the dimensionality of the data).The worse news - this dataset may not be large enough to get the same quality of results as MNIST. The resources/stretch goals section links to additional sources, so feel free to get creative (and practice your scraping/ingest skills) - but, it is suggested to do so only *after* working some with this as a starting point.*Hint* - the main challenge in getting an MVP running will just be loading and converting all the images. [os.listdir](https://docs.python.org/3.7/library/os.htmlos.listdir) plus a loop, and refactoring the image processing code into a function, should go a long way.<jupyter_code>!pip install emoji_data_python
!wget https://github.com/LambdaSchool/DS-Unit-4-Sprint-4-Deep-Learning/raw/master/module3-generative-adversarial-networks/emoji.zip
!unzip emoji.zip
import imageio
import matplotlib.pyplot as plt
from skimage import color

example_emoji = imageio.imread('emoji/1f683.png')
grayscale_emoji = color.rgb2gray(example_emoji)
#images in color have 3 dimensions and will need convolutional 
example_emoji.shape
plt.imshow(example_emoji);
#images in greyscale have 2 dimensions and can use binary
grayscale_emoji.shape
plt.imshow(grayscale_emoji, cmap="gray");<jupyter_output><empty_output><jupyter_text>Convert the images<jupyter_code>import os
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm  # performance timing

# Building on Keras
from keras.layers import Input
from keras.models import Model, Sequential
from keras.layers.core import Dense, Dropout
from keras.layers.advanced_activations import LeakyReLU
from keras.optimizers import Adam
from keras import initializers
emojis = os.listdir('emoji')
emojis
#we need to make the colored images greyscale
#make a function and loop it for everything in emojis
bw_emoji = []
#'emoji/1f683.png'
for png in emojis:
  #read image
  png_array = imageio.imread('emoji/'+str(png))
  #reshape the array to be 2d
  png_array = color.rgb2gray(png_array)
  print(png_array.shape)
  bw_emoji.append(png_array) #they're all 28*28
len(bw_emoji)
#convert bw_emoji to array
bw_emoji = np.asarray(bw_emoji)
bw_emoji
bw_emoji.shape
bw_emoji_normalize = (bw_emoji.astype(np.float32) - 127.5)/127.5
bw_emoji_normalize
bw_emoji_reshape = bw_emoji_normalize.reshape(861, 784)
bw_emoji_reshape<jupyter_output><empty_output><jupyter_text>shape of fashion mnist (reference)<jupyter_code>#what is the input we worked with in lecture?
from keras.datasets import fashion_mnist
fashion = fashion_mnist.load_data()
fashion #an array of arrays
len(fashion) #a tuple containing arrays
print(len(fashion[0]), len(fashion[1])) #of course
#first tuple (train, test)
#second tuples (xtrain, ytrain), (xtest, ytest)
print(fashion[0][0].shape) #yup, there's the arrays
print(fashion[0][1].shape)
x_train = fashion[0][0] #we ignore everything else in mnist

# normalize our inputs to be in the range[-1, 1]
x_train = (x_train.astype(np.float32) - 127.5)/127.5
x_train
# convert x_train with a shape of (60000, 28, 28) to (60000, 784) so we have
# 784 columns per row
x_train = x_train.reshape(60000, 784)
x_train<jupyter_output><empty_output><jupyter_text>BW GAN Model<jupyter_code>#discriminator - binary classification NN
#stretch goal: modify to accept convolutions
def get_discriminator(optimizer):
    discriminator = Sequential()
    discriminator.add(Dense(
        1024, input_dim=784, #ie 28*28
        kernel_initializer=initializers.RandomNormal(stddev=0.02)))
    discriminator.add(LeakyReLU(0.2))
    discriminator.add(Dropout(0.3))
 
    discriminator.add(Dense(512))
    discriminator.add(LeakyReLU(0.2))
    discriminator.add(Dropout(0.3))
 
    discriminator.add(Dense(256))
    discriminator.add(LeakyReLU(0.2))
    discriminator.add(Dropout(0.3))
 
    discriminator.add(Dense(1, activation='sigmoid'))
    discriminator.compile(loss='binary_crossentropy', optimizer=optimizer)
    return discriminator
def get_generator(optimizer):
    generator = Sequential()
    generator.add(Dense(
        256, input_dim=random_dim,
        kernel_initializer=initializers.RandomNormal(stddev=0.02)))
    generator.add(LeakyReLU(0.2))
 
    generator.add(Dense(512))
    generator.add(LeakyReLU(0.2))
 
    generator.add(Dense(1024))
    generator.add(LeakyReLU(0.2))
 
    generator.add(Dense(784, activation='tanh'))
    generator.compile(loss='binary_crossentropy', optimizer=optimizer)
    return generator
def get_gan_network(discriminator, random_dim, generator, optimizer):
    # We initially set trainable to False since we only want to train either the 
    # generator or discriminator at a time
    discriminator.trainable = False
    # gan input (noise) will be 100-dimensional vectors
    gan_input = Input(shape=(random_dim,))
    # the output of the generator (an image)
    x = generator(gan_input)
    # get the output of the discriminator (probability if the image is real/not)
    gan_output = discriminator(x)
    gan = Model(inputs=gan_input, outputs=gan_output)
    gan.compile(loss='binary_crossentropy', optimizer=optimizer)
    return gan
def plot_generated_images(epoch, generator, examples=100, dim=(10, 10),
                          figsize=(10, 10)):
    noise = np.random.normal(0, 1, size=[examples, random_dim])
    generated_images = generator.predict(noise)
    generated_images = generated_images.reshape(examples, 28, 28)
 
    plt.figure(figsize=figsize)
    for i in range(generated_images.shape[0]):
        plt.subplot(dim[0], dim[1], i+1)
        plt.imshow(generated_images[i], interpolation='nearest', cmap='gray_r')
        plt.axis('off')
    plt.tight_layout()
    plt.savefig('gan_generated_image_epoch_%d.png' % epoch)
def train(epochs=1, batch_size=128):
    # Get the training and testing data
    x_train = bw_emoji_reshape
    # Split the training data into batches of size 128
    batch_count = x_train.shape[0] // batch_size
 
    # Build our GAN netowrk
    adam = Adam(lr=0.0002, beta_1=0.5)
    generator = get_generator(adam)
    discriminator = get_discriminator(adam)
    gan = get_gan_network(discriminator, random_dim, generator, adam)
 
    for e in range(1, epochs+1):
        print ('-'*15, 'Epoch %d' % e, '-'*15)
        for _ in tqdm(range(batch_count)):
            # Get a random set of input noise and images
            noise = np.random.normal(0, 1, size=[batch_size, random_dim])
            image_batch = x_train[np.random.randint(0, x_train.shape[0],
                                                    size=batch_size)]
 
            # Generate fake MNIST images
            generated_images = generator.predict(noise)
            X = np.concatenate([image_batch, generated_images])
 
            # Labels for generated and real data
            y_dis = np.zeros(2*batch_size)
            # One-sided label smoothing
            y_dis[:batch_size] = 0.9
 
            # Train discriminator
            discriminator.trainable = True
            discriminator.train_on_batch(X, y_dis)
 
            # Train generator
            noise = np.random.normal(0, 1, size=[batch_size, random_dim])
            y_gen = np.ones(batch_size)
            discriminator.trainable = False
            gan.train_on_batch(noise, y_gen)
 
        if e == 1 or e % 20 == 0:
            plot_generated_images(e, generator)<jupyter_output><empty_output><jupyter_text>Result<jupyter_code>np.random.seed(10)
random_dim = 100
train(40, 128)<jupyter_output>WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.
Instructions for updating:
Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.
{'fraction_non_alphanumeric': 0.09487534626038781, 'fraction_numerical': 0.0265466297322253, 'mean_word_length': 4.058377116170461, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '274408', 'license': 'MIT', 'n_tokens_mistral': 2945, 'n_tokens_neox': 2753, 'n_words': 803, 'path': 'Trista_GAN_Assignment.ipynb', 'repo_name': 'trista-paul/DS-Unit-4-Sprint-4-Deep-Learning', 'size': '8664'}