text: from scipy.io import loadmat
  import pandas as pd
  import numpy as np
  from random import shuffle
  import os
  import cv2
  
  class DataManager(object):
      """Class for loading fer2013 emotion classification dataset or
          imdb gender classification dataset."""
      def __init__(self, dataset_name='imdb', dataset_path=None, image_size=(48, 48)):
  
          self.dataset_name = dataset_name
          self.dataset_path = dataset_path
          self.image_size = image_size
          if self.dataset_path != None:
              self.dataset_path = dataset_path
          elif self.dataset_name == 'imdb':
              self.dataset_path = '../datasets/imdb_crop/imdb.mat'
          elif self.dataset_name == 'fer2013':
              self.dataset_path = '../datasets/fer2013/fer2013.csv'
          elif self.dataset_name == 'KDEF':
              self.dataset_path = '../datasets/KDEF/'
          else:
              raise Exception('Incorrect dataset name, please input imdb or fer2013')
  
      def get_data(self):
          if self.dataset_name == 'imdb':
              ground_truth_data = self._load_imdb()
          elif self.dataset_name == 'fer2013':
              ground_truth_data = self._load_fer2013()
          elif self.dataset_name == 'KDEF':
              ground_truth_data = self._load_KDEF()
          return ground_truth_data
  
      def _load_imdb(self):
          face_score_treshold = 3
          dataset = loadmat(self.dataset_path)
          image_names_array = dataset['imdb']['full_path'][0, 0][0]
          gender_classes = dataset['imdb']['gender'][0, 0][0]
          face_score = dataset['imdb']['face_score'][0, 0][0]
          second_face_score = dataset['imdb']['second_face_score'][0, 0][0]
          face_score_mask = face_score > face_score_treshold
          second_face_score_mask = np.isnan(second_face_score)
          unknown_gender_mask = np.logical_not(np.isnan(gender_classes))
          mask = np.logical_and(face_score_mask, second_face_score_mask)
          mask = np.logical_and(mask, unknown_gender_mask)
          image_names_array = image_names_array[mask]
          gender_classes = gender_classes[mask].tolist()
          image_names = []
          for image_name_arg in range(image_names_array.shape[0]):
              image_name = image_names_array[image_name_arg][0]
              image_names.append(image_name)
          return dict(zip(image_names, gender_classes))
  
      def _load_fer2013(self):
          data = pd.read_csv(self.dataset_path)
          taken_out_data = data.loc[(data.emotion > 1)]
          pixels = taken_out_data['pixels'].tolist()
          width, height = 48, 48
          faces = []
          for pixel_sequence in pixels:
              face = [int(pixel) for pixel in pixel_sequence.split(' ')]
              face = np.asarray(face).reshape(width, height)
              face = cv2.resize(face.astype('uint8'), self.image_size)
              faces.append(face.astype('float32'))
          faces = np.asarray(faces)
          faces = np.expand_dims(faces, -1)
          emotions = pd.get_dummies(taken_out_data['emotion']).as_matrix()
          return faces, emotions
  
      def _load_KDEF(self):
          class_to_arg = get_class_to_arg(self.dataset_name)
          num_classes = len(class_to_arg)
  
          file_paths = []
          for folder, subfolders, filenames in os.walk(self.dataset_path):
              for filename in filenames:
                  if filename.lower().endswith(('.jpg')):
                      file_paths.append(os.path.join(folder, filename))
  
          num_faces = len(file_paths)
          y_size, x_size = self.image_size
          faces = np.zeros(shape=(num_faces, y_size, x_size))
          emotions = np.zeros(shape=(num_faces, num_classes))
          for file_arg, file_path in enumerate(file_paths):
              image_array = cv2.imread(file_path, cv2.IMREAD_GRAYSCALE)
              image_array = cv2.resize(image_array, (y_size, x_size))
              faces[file_arg] = image_array
              file_basename = os.path.basename(file_path)
              file_emotion = file_basename[4:6]
              # there are two file names in the dataset that don't match the given classes
              try:
                  emotion_arg = class_to_arg[file_emotion]
              except:
                  continue
              emotions[file_arg, emotion_arg] = 1
          faces = np.expand_dims(faces, -1)
          return faces, emotions
  
  def get_labels(dataset_name):
      if dataset_name == 'fer2013':
          return {0:'Angry',1:'Disgust',2:'Fear',3:'Happy',
                  4:'Sad',5:'Surprise',6:'Neutral'}
          # return {0:'fear',1:'happy',2:'sad',3:'surprise',
                 # 4:'neutral'}
      elif dataset_name == 'imdb':
          return {0:'woman', 1:'man'}
      elif dataset_name == 'KDEF':
          return {0:'AN', 1:'DI', 2:'AF', 3:'HA', 4:'SA', 5:'SU', 6:'NE'}
      else:
          raise Exception('Invalid dataset name')
  
  def get_class_to_arg(dataset_name='fer2013'):
      if dataset_name == 'fer2013':
          return {'angry':0, 'disgust':1, 'fear':2, 'happy':3, 'sad':4,
                  'surprise':5, 'neutral':6}
      elif dataset_name == 'imdb':
          return {'woman':0, 'man':1}
      elif dataset_name == 'KDEF':
          return {'AN':0, 'DI':1, 'AF':2, 'HA':3, 'SA':4, 'SU':5, 'NE':6}
      else:
          raise Exception('Invalid dataset name')
  
  def split_imdb_data(ground_truth_data, validation_split=.2, do_shuffle=False):
      ground_truth_keys = sorted(ground_truth_data.keys())
      if do_shuffle == True:
          shuffle(ground_truth_keys)
      training_split = 1 - validation_split
      num_train = int(training_split * len(ground_truth_keys))
      train_keys = ground_truth_keys[:num_train]
      validation_keys = ground_truth_keys[num_train:]
      return train_keys, validation_keys
  
  def split_data(x, y, validation_split=.2):
      num_samples = len(x)
      num_train_samples = int((1 - validation_split)*num_samples)
      train_x = x[:num_train_samples]
      train_y = y[:num_train_samples]
      val_x = x[num_train_samples:]
      val_y = y[num_train_samples:]
      train_data = (train_x, train_y)
      val_data = (val_x, val_y)
      return train_data, val_data
  
  