from __future__ import print_function
import keras
#import tensorflow as tf
from keras.datasets import cifar10
#from keras.backend.tensorflow_backend import set_session
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
import numpy as np

K.set_image_dim_ordering('th')


#config = tf.ConfigProto()
#config.gpu_options.per_process_gpu_memory_fraction = 0.5
#set_session(tf.Session(config=config))


batch_size = 256
num_classes = 10
epochs = 200
data_augmentation = False



# The data, shuffled and split between train and test sets:
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# Convert class vectors to binary class matrices.
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)

model = Sequential()

model.add(Convolution2D(32, 3, 3, input_shape=x_train.shape[1:])) #1
model.add(Activation('relu'))
model.add(Convolution2D(32, 3, 3)) #3
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Convolution2D(64, 3, 3)) #7
model.add(Activation('relu'))
model.add(Convolution2D(64, 3, 3)) #9
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(512)) #14
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes)) #17
model.add(Activation('softmax'))

# initiate RMSprop optimizer
opt = keras.optimizers.Adam(lr=0.0001, beta_2=0.9)
#opt = keras.optimizers.Adam(lr=0.0001, epsilon=1e-1)

# Let's train the model using RMSprop
model.compile(loss='categorical_crossentropy',
              optimizer=opt,
              metrics=['accuracy'])

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255

layer_list = [1, 3, 7, 9, 14, 17]
loss = []
val_loss = []

if not data_augmentation:
    print('Not using data augmentation.')
    for i in range(200):
      count = 1
      for layer in model.layers:
        if count in layer_list:
          print(count)

          weights = layer.get_weights()
          #print(weights)
          #print(weights[0].shape)
          #exit()
          #print(weights[0])
          #print(len(weights[0]))
          #print(weights[0].shape)
          #dir = "./l"+str(count)+"/eps_1e-1/"
          dir = "./l"+str(count)+"/b2_0.9/"
          name = "ep"+str(i)+".npy"
          path = dir+name
          #print(path)
          np.save(path, weights[0])
          #exit()
        #print (count)
        count += 1
      
      
      hist = model.fit(x_train, y_train,
              batch_size=batch_size,
              nb_epoch=1,
              validation_data=(x_test, y_test),
              shuffle=True)
      loss.append(hist.history['loss'][0])
      val_loss.append(hist.history['val_loss'][0])
      print(hist.history['loss'][0])
      print(hist.history['val_loss'][0])

    #np.save("./1e-1/loss.npy", np.array(loss))
    np.save("./b2_0.9/loss.npy", np.array(loss))
    #np.save("./1e-1/val_loss.npy", np.array(val_loss))
    np.save("./b2_0.9/val_loss.npy", np.array(val_loss))


else:
    print('Using real-time data augmentation.')
    # This will do preprocessing and realtime data augmentation:
    datagen = ImageDataGenerator(
        featurewise_center=False,  # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range=0,  # randomly rotate images in the range (degrees, 0 to 180)
        width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
        horizontal_flip=True,  # randomly flip images
        vertical_flip=False)  # randomly flip images

    # Compute quantities required for feature-wise normalization
    # (std, mean, and principal components if ZCA whitening is applied).
    datagen.fit(x_train)

    # Fit the model on the batches generated by datagen.flow().
   
  
    model.fit_generator(datagen.flow(x_train, y_train,
                                     batch_size=batch_size),
                        steps_per_epoch=x_train.shape[0] // batch_size,
                        epochs=1,
                        validation_data=(x_test, y_test))

    


