Advanced Neural Network for Python Deep Learning Experiment

Keywords: network jupyter encoding

Advanced Neural Network

Experimental environment

keras 2.1.5
tensor 1.4.0

Experimental tools

Jupyter Notebook

Experiment 1: MNIST generates antagonistic networks

thinking

Train two models, one to generate a given random noise as input output example G, and one to identify the generated model example A from the actual example.Then, by training A as an effective discriminator, we can overlay G and A into our GAN, freeze the weights of the antagonistic part of the network, and train the generated network weights to push the random noise input to the "real" class output of the antagonistic half class.

Work process:

Experimental process

1. Load Dependencies:

%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

import keras
from keras.layers import Dense, Activation, Dropout, Flatten, Reshape, LeakyReLU 
from keras.layers import Conv2D, Conv2DTranspose, UpSampling2D, BatchNormalization
from keras.layers import Cropping2D
from keras.datasets import mnist
from keras.models import Sequential
from keras.optimizers import RMSprop

from sklearn.utils import shuffle

2. Loading and preparing datasets:

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.astype("float32")/255.

Although the images are grayscale, we will increase the channel dimension by 1 because the convolution layer requires them.

x_train = x_train.reshape((x_train.shape[0],x_train.shape[1],x_train.shape[2],1))
x_test = x_test.reshape((x_test.shape[0],x_test.shape[1],x_test.shape[2],1))

y_train = y_train.reshape((y_train.shape[0],-1))
y_test = y_test.reshape((y_test.shape[0],-1))

train_data_shape = x_train.shape
test_data_shape = x_test.shape

train_label_shape = y_train.shape
test_label_shape = y_test.shape
#Take a look at the output:
print("train data shape:",train_data_shape)
print("train label shape:",train_label_shape)
print("test data shape:",test_data_shape)
print("test label shape:",test_label_shape)
'''
train data shape: (60000, 28, 28, 1)
train label shape: (60000, 1)
test data shape: (10000, 28, 28, 1)
test label shape: (10000, 1)
'''

3. Establish a network model:
Discriminator:
We set up a discriminator network to receive [1,28,28] image vectors and determine whether they are true or false by using multiple convolution layers, dense layers, large loss, and two element Softmax output layer encoding: [0,1]=false and [1,0]=true.

D = Sequential()

dropout = 0.4

input_shape = train_data_shape[1:]

D.add(Conv2D(16, 3, strides=2, input_shape=input_shape,padding='same'))
D.add(LeakyReLU(alpha=0.2))

D.add(Dropout(dropout))

D.add(Conv2D(32, 3, strides=2, padding='same'))
D.add(LeakyReLU(alpha=0.2))

D.add(Dropout(dropout))

D.add(Conv2D(64, 3, strides=2, padding='same'))
D.add(LeakyReLU(alpha=0.2))

D.add(Dropout(dropout))

D.add(Flatten())

D.add(Dense(1))

D.add(Activation('sigmoid'))

D.summary()

optimizer1 = RMSprop(lr=0.0008, clipvalue=1.0, decay=6e-8)
D.compile(loss='binary_crossentropy', optimizer=optimizer1,metrics=['accuracy'])
'''
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 14, 14, 16)        160       
_________________________________________________________________
leaky_re_lu_1 (LeakyReLU)    (None, 14, 14, 16)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 14, 14, 16)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 7, 7, 32)          4640      
_________________________________________________________________
leaky_re_lu_2 (LeakyReLU)    (None, 7, 7, 32)          0         
_________________________________________________________________
dropout_2 (Dropout)          (None, 7, 7, 32)          0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 4, 4, 64)          18496     
_________________________________________________________________
leaky_re_lu_3 (LeakyReLU)    (None, 4, 4, 64)          0         
_________________________________________________________________
dropout_3 (Dropout)          (None, 4, 4, 64)          0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 1024)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 1025      
_________________________________________________________________
activation_1 (Activation)    (None, 1)                 0         
=================================================================
Total params: 24,321
Trainable params: 24,321
Non-trainable params: 0
_________________________________________________________________
'''

Gernerator:
Using the function API, we built a relatively simple generation model in Keras, took 100 random inputs, and finally mapped them to a [1, 28, 28] pixel to match the shape of the MNIST data.First, a dense set of 14*14 values is generated, then several filters of different sizes and number of channels are run, and the use of binary cross-entropy and adam optimizer are trained.We use Sigmiod on the output layer to help saturate the pixels to a 0 or 1 state instead of a gray scale between 0 or 1, and batch normalization to help speed up training and ensure a wide range of activations are used in each layer.

G = Sequential()

dropout = 0.4

G.add(Dense(4*4*128, input_dim=100))
G.add(BatchNormalization(momentum=0.9))
G.add(Activation('relu'))

G.add(Reshape((4, 4, 128)))

G.add(UpSampling2D())
G.add(Conv2DTranspose(64, 3, padding='same'))
G.add(BatchNormalization(momentum=0.9))
G.add(Activation('relu'))

G.add(UpSampling2D())
G.add(Conv2DTranspose(32, 3, padding='same'))
G.add(BatchNormalization())
G.add(Activation('relu'))

G.add(UpSampling2D())

G.add(Cropping2D(cropping=((2, 2), (2, 2))))
      
G.add(Conv2DTranspose(16, 3, padding='same'))
G.add(BatchNormalization(momentum=0.9))
G.add(Activation('relu'))

G.add(Conv2DTranspose(8, 3, padding='same'))
G.add(BatchNormalization(momentum=0.9))
G.add(Activation('relu'))

G.add(Conv2DTranspose(1, 3, padding='same'))
G.add(Activation('sigmoid'))

G.summary()
'''
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_2 (Dense)              (None, 2048)              206848    
_________________________________________________________________
batch_normalization_1 (Batch (None, 2048)              8192      
_________________________________________________________________
activation_2 (Activation)    (None, 2048)              0         
_________________________________________________________________
reshape_1 (Reshape)          (None, 4, 4, 128)         0         
_________________________________________________________________
up_sampling2d_1 (UpSampling2 (None, 8, 8, 128)         0         
_________________________________________________________________
conv2d_transpose_1 (Conv2DTr (None, 8, 8, 64)          73792     
_________________________________________________________________
batch_normalization_2 (Batch (None, 8, 8, 64)          256       
_________________________________________________________________
activation_3 (Activation)    (None, 8, 8, 64)          0         
_________________________________________________________________
up_sampling2d_2 (UpSampling2 (None, 16, 16, 64)        0         
_________________________________________________________________
conv2d_transpose_2 (Conv2DTr (None, 16, 16, 32)        18464     
_________________________________________________________________
batch_normalization_3 (Batch (None, 16, 16, 32)        128       
_________________________________________________________________
activation_4 (Activation)    (None, 16, 16, 32)        0         
_________________________________________________________________
up_sampling2d_3 (UpSampling2 (None, 32, 32, 32)        0         
_________________________________________________________________
cropping2d_1 (Cropping2D)    (None, 28, 28, 32)        0         
_________________________________________________________________
conv2d_transpose_3 (Conv2DTr (None, 28, 28, 16)        4624      
_________________________________________________________________
batch_normalization_4 (Batch (None, 28, 28, 16)        64        
_________________________________________________________________
activation_5 (Activation)    (None, 28, 28, 16)        0         
_________________________________________________________________
conv2d_transpose_4 (Conv2DTr (None, 28, 28, 8)         1160      
_________________________________________________________________
batch_normalization_5 (Batch (None, 28, 28, 8)         32        
_________________________________________________________________
activation_6 (Activation)    (None, 28, 28, 8)         0         
_________________________________________________________________
conv2d_transpose_5 (Conv2DTr (None, 28, 28, 1)         73        
_________________________________________________________________
activation_7 (Activation)    (None, 28, 28, 1)         0         
=================================================================
Total params: 313,633
Trainable params: 309,297
Non-trainable params: 4,336
_________________________________________________________________
'''

Generate regression models:
Use the functional API to combine the generation model with the resistance model.

D.trainable = False  

gan = Sequential()
gan.add(G)
gan.add(D)
gan.summary()

optimizer2 = RMSprop(lr=0.0004, clipvalue=1.0, decay=3e-8)
gan.compile(loss='binary_crossentropy', optimizer=optimizer2, metrics=['accuracy'])
'''
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
sequential_2 (Sequential)    (None, 28, 28, 1)         313633    
_________________________________________________________________
sequential_1 (Sequential)    (None, 1)                 24321     
=================================================================
Total params: 337,954
Trainable params: 309,297
Non-trainable params: 28,657
_________________________________________________________________
'''

4. Training:
Define a function to draw and save the output of the generator:

def plot_images(save2file=False, fake=True, samples=16, noise=None, step=0):
    filename = 'mnist.png'
    if fake:
        if noise is None:
            noise = np.random.uniform(-1.0, 1.0, size=[samples, 100])
        else:
            filename = "mnist_%d.png" % step
        images = G.predict(noise)
    else:
        i = np.random.randint(0, self.x_train.shape[0], samples)
        images = x_train[i, :, :, :]

    plt.figure(figsize=(10,10))
    for i in range(images.shape[0]):
        plt.subplot(4, 4, i+1)
        image = images[i, :, :, :]
        image = np.reshape(image, [train_data_shape[1], train_data_shape[2]])
        plt.imshow(image, cmap='gray')
        plt.axis('off')
    plt.tight_layout()
    if save2file:
        plt.savefig(filename)
        plt.close('all')
    else:
        plt.show()

Set superparameters:

save_interval = 20   #save a plot that includes the output of the generator every number of steps 
train_steps=2000      # end number of steps
start_step = 0        # start number of steps
batch_size=256       # batch size

Discriminant models are pre-trained, several random images are generated using untrained generation models, connected to the same number of real digital images, tagged appropriately, and fitted until we reach a relatively stable loss value, which exceeds 20,000 examples.

num_pretrain = 5000
images_train = x_train[np.random.randint(0,x_train.shape[0], size=num_pretrain), :, :, :]  #selecting random num_pretrain images from training data
noise = np.random.uniform(0, 1.0, size=[num_pretrain, 100])   #generating random num_pretrain noise vectors
images_fake = G.predict(noise)   #generating fake images from the generator
x = np.concatenate((images_train, images_fake))  #stacking both real and fake images
#generating labels in which real=1, fake =0
y = np.ones([2*num_pretrain, 1])
y[num_pretrain:, :] = 0

x,y = shuffle(x,y)  #shuffling the data and labels

d_loss = D.fit(x, y, batch_size=batch_size, epochs=1, validation_split=0.15) #the pretraining step
'''
Train on 8500 samples, validate on 1500 samples
Epoch 1/1
8500/8500 [==============================] - 3s 335us/step - loss: 0.1738 - acc: 0.9426 - val_loss: 0.0033 - val_acc: 1.0000
'''

Generators can be trained in an overlay model of two networks.
The core of GaN training is as follows:
(1) G and random noise are used to generate the image (pass forward only).
(2) Perform batch updates of weights in a given generated image, real image, and label.
(3) Perform a batch of updates weighting the noise given in G and force the "true" label throughout the GaN.
(4) Repeat...

#noise input for generator output plotting
noise_input = None
if save_interval>0:
    noise_input = np.random.uniform(0.0, 1.0, size=[16, 100])
#the training loop
d_losses = []
g_losses = []
for i in range(start_step,train_steps):
    # train the discriminator 2 times
    for dis_iter in range(1):
        #training the discriminator
        images_train = x_train[np.random.randint(0,x_train.shape[0], size=batch_size), :, :, :] #selecting random real images whose count equals the batch size
        noise = np.random.uniform(0.0, 1.0, size=[batch_size, 100]) # generating the noise vectors whose count equals batch size
        images_fake = G.predict(noise) #generate fake images from generator
        x = np.concatenate((images_train, images_fake)) #stack real and fake images
        #generating the labels
        y = np.ones([2*batch_size, 1]) 
        y[batch_size:, :] = 0
        # Add random noise to the labels - important trick!
        # y += 0.05 * np.random.random(y.shape)
        x,y = shuffle(x,y) #shuffling the images and labels
        d_loss = D.train_on_batch(x, y) #train the discriminator on this batch of data
    d_losses.append(d_loss)
    
    #training the adverserial model, aka training the generator
    y = np.ones([batch_size, 1]) #the labels, they are always one
    noise = np.random.uniform(0.0, 1.0, size=[batch_size, 100]) #input noise for generator
    g_loss = gan.train_on_batch(noise, y) #train the adeveserial model, with the discrimimator frozen only the generator is updated\
                                         # and with all the labels equal (1), we are telling the generator to strive to generate data that will make the]
                                         # discriminator always output (1) aka fooling it.
    g_losses.append(g_loss)
    
    #print the losses and accuracy values 
    log_mesg = "%d: [D loss: %f, acc: %f]" % (i, d_loss[0], d_loss[1])
    log_mesg = "%s  [G loss: %f, acc: %f]" % (log_mesg, g_loss[0], g_loss[1])
    print(log_mesg)
    #save the plots of generator outputs
    if save_interval>0:
        if (i+1)%save_interval==0:
            plot_images(save2file=True, samples=noise_input.shape[0],noise=noise_input, step=(i+1))
'''
#Wait a long time, don't switch it off easily.
0: [D loss: 0.005583, acc: 1.000000]  [G loss: 6.771719, acc: 0.000000]
1: [D loss: 0.004642, acc: 1.000000]  [G loss: 5.488572, acc: 0.003906]
2: [D loss: 0.006872, acc: 1.000000]  [G loss: 6.208431, acc: 0.000000]
3: [D loss: 0.008283, acc: 1.000000]  [G loss: 4.167761, acc: 0.015625]
4: [D loss: 0.011295, acc: 0.998047]  [G loss: 6.652860, acc: 0.000000]
5: [D loss: 0.020132, acc: 0.994141]  [G loss: 3.805618, acc: 0.023438]
······
//Omit thousands
······
1995: [D loss: 0.686364, acc: 0.550781]  [G loss: 0.707710, acc: 0.433594]
1996: [D loss: 0.682135, acc: 0.552734]  [G loss: 0.706227, acc: 0.460938]
1997: [D loss: 0.682364, acc: 0.552734]  [G loss: 0.696030, acc: 0.519531]
1998: [D loss: 0.687504, acc: 0.529297]  [G loss: 0.695345, acc: 0.511719]
1999: [D loss: 0.692645, acc: 0.498047]  [G loss: 0.717447, acc: 0.425781]
'''

5. Drawing:

fig, ax = plt.subplots()
losses = np.array(g_losses)
plt.plot(d_losses, label='Discriminator')
plt.plot(g_losses, label='Generator')
plt.title("Training Losses")
plt.legend()

173 original articles published. 6. 40,000 visits+
Private letter follow

Posted by jonat8 on Sat, 11 Jan 2020 16:58:06 -0800