text: # Imports
  import numpy as np
  from keras.preprocessing.image import ImageDataGenerator
  from keras.callbacks import LearningRateScheduler
  from keras import regularizers
  from keras.models import Sequential
  from keras.layers import Dense
  from keras.layers import Dropout
  from keras.layers import Flatten
  from keras.layers import Activation
  from keras.layers import BatchNormalization
  from keras.constraints import maxnorm
  from keras.optimizers import SGD
  from keras.layers.convolutional import Conv2D
  from keras.layers.convolutional import MaxPooling2D
  from keras.utils import np_utils 
  from keras.datasets import cifar10
  from keras import backend as K
  from sklearn.model_selection import train_test_split
  
  def lr_schedule(epoch):
      lrate = 0.01        
      return lrate
  
  # load data
  K.set_image_dim_ordering('th')
  (X_train, y_train), (X_test, y_test) = cifar10.load_data()
  X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=0.1)
  
  seed = 7
  np.random.seed(seed)
  
  X_train = X_train.astype('float32')
  X_test = X_test.astype('float32')
  #X_valid = X_valid.astype('float32')
  
  X_train = X_train / 255.0
  X_test = X_test / 255.0
  #X_valid = X_valid / 255.0
  
  y_train = np_utils.to_categorical(y_train)
  y_test = np_utils.to_categorical(y_test)
  #y_valid = np_utils.to_categorical(y_valid)
  num_classes = y_test.shape[1]
  print(X_train.shape)
  
  weight_decay = 1e-4
  model = Sequential()
  model.add(Conv2D(32, (3,3), padding='same', kernel_regularizer=regularizers.l2(weight_decay), input_shape=X_train.shape[1:]))
  model.add(Activation('elu'))
  model.add(BatchNormalization())
  model.add(Conv2D(32, (3,3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
  model.add(Activation('elu'))
  model.add(BatchNormalization())
  model.add(MaxPooling2D(pool_size=(2,2)))
  model.add(Dropout(0.2))
  
  model.add(Conv2D(64, (3,3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
  model.add(Activation('elu'))
  model.add(BatchNormalization())
  model.add(Conv2D(64, (3,3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
  model.add(Activation('elu'))
  model.add(BatchNormalization())
  model.add(MaxPooling2D(pool_size=(2,2)))
  model.add(Dropout(0.3))
  
  model.add(Conv2D(128, (3,3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
  model.add(Activation('elu'))
  model.add(BatchNormalization())
  model.add(Conv2D(128, (3,3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
  model.add(Activation('elu'))
  model.add(BatchNormalization())
  model.add(MaxPooling2D(pool_size=(2,2)))
  model.add(Dropout(0.4))
  
  model.add(Flatten())
  model.add(Dense(num_classes, activation='softmax'))
  
  #data augmentation
  datagen = ImageDataGenerator(
      rotation_range=15,
      width_shift_range=0.1,
      height_shift_range=0.1,
      horizontal_flip=True,
      )
  datagen.fit(X_train)
  
  epochs = 25 
  lrate = 0.01
  decay = lrate/epochs
  sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
  
  model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
  
  print(model.summary())
  
  batch_size = 64
  #model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=32)
  model.fit_generator(datagen.flow(X_train, y_train, batch_size=batch_size),\
                      steps_per_epoch=X_train.shape[0] // batch_size,epochs=125,\
                      verbose=1,validation_data=(X_test,y_test),callbacks=[LearningRateScheduler(lr_schedule)])
  
  #save to disk
  model_json = model.to_json()
  with open('model.json', 'w') as json_file:
      json_file.write(model_json)
  
  model.save_weights('cifarcnnmodel.h5') 
  
  scores = model.evaluate(X_test,y_test,verbose=0)
  print("Accuracy: %.2f%%" % (scores[1]*100))
  
  print("Application end.")
  
  