{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\n# print(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ccd5bb018d80f2451ca96fc04defbc63596742af"},"cell_type":"code","source":"!ls\n!ls ../input/human-protein-atlas-image-classification","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"!pwd\nos.chdir(\"/kaggle/working\")\n\nif True:\n\n    SUBFOLDER = \"human-protein-atlas-image-classification/\"\n    \nINPUT_PATH = \"/kaggle/input/\" + SUBFOLDER \nINPUT_IMAGES_PATH = INPUT_PATH + \"train/\"\nINPUT_IMAGES_TEST_PATH = INPUT_PATH + \"test/\"\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"65ead190e8af834905b268d56ec7772953449b12"},"cell_type":"code","source":"print(INPUT_IMAGES_PATH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b2e8ea0f45c6d71c012dcfb5084fb4e467751bd9"},"cell_type":"code","source":"x = 1000\nos.listdir(\".\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"567020f6fd70c2a5accdb25ecfe2f43b09f83114"},"cell_type":"code","source":"import cv2","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8ccffd66303a77829921414beb4b086c1e62a900"},"cell_type":"markdown","source":"As we can see, each of the images actually has 3 color channels, which are all the same value, since they are monocolour "},{"metadata":{"trusted":true,"_uuid":"03a0d5335799328f445b0be6dfff81404496ac85"},"cell_type":"code","source":"test_img = cv2.imread(INPUT_IMAGES_PATH + \"65ac91dc-bba7-11e8-b2ba-ac1f6b6435d0_red.png\", -1)\n\n%matplotlib inline\nimport matplotlib.pyplot as plt\nplt.axis(\"off\")\nplt.imshow(test_img)\n\nnp.set_printoptions(threshold=np.nan)\nprint(test_img.shape)\nprint(test_img[0].shape)\nprint(test_img[0])\n\n# for some reasons, the image is saved as greyscale?? \n# we could simply load it as greyscale, then extend it with two dimensions of the things we dont want\n# then if we save that, it should work! \n# no, so the image is saved with just one value of intensity. We likely have some additional meta info which enables us to render the image in the appropriate\n# color info.  But cv2 does some modification, depending on the flag you pass in when asking to open \n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e883aed26be988b1676bdaac86f27fb5950caa5e"},"cell_type":"markdown","source":"Hence, we should load them as greyscale, and then use the appropriate cmap to render the image correctly.\nAlternatively, let us now consider using a different library like matplotlib etc.\n"},{"metadata":{"trusted":true,"_uuid":"49529ce736cedd8120675fc9824511a5a5b67b70"},"cell_type":"code","source":"import matplotlib.image as mpimg\nmpimg_image = mpimg.imread(INPUT_IMAGES_PATH + \"65ac91dc-bba7-11e8-b2ba-ac1f6b6435d0_red.png\")\n# print(mpimg_image)\nimgplot = plt.imshow(mpimg_image, cmap=plt.cm.Reds_r)\n\n# one issue with this is that we want the \"inverse\" of this image: black and white values should be flipped or swapped (could take an inverse for example)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"aaebc0dcaa349007cff0fd08499871a4dc6e2db5"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cacc7633e9dfe3a6eedf7a59cc040ed5a2fcb3ca"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"58f57a8330f6a9b6a9da082993e73eeeb6eaa2e3"},"cell_type":"code","source":"test_filename = INPUT_IMAGES_PATH + \"ac39847a-bbb1-11e8-b2ba-ac1f6b6435d0_red.png\"\n\ntest_img = cv2.imread( test_filename)\n\nplt.imshow(test_img)\nplt.show()\n\n# os.chdir(\"..\")\nblur = cv2.GaussianBlur(test_img,(5,5),0)\n\ncv2.imwrite(r\"/kaggle/working/sample_out.png\", test_img)\nplt.imshow(blur)\nplt.show()\n\n# files may be implicitly saved somewhere...","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8580870d0c4cd87ab185839056e6de5cc043d0a3"},"cell_type":"markdown","source":"**Data Loading\n**"},{"metadata":{"trusted":true,"_uuid":"3d2cb5066e77a24696c9a82ba0818a5000eea767"},"cell_type":"code","source":"# we want to match the images (filenames) with their target labels\n# we need to I guess find the log-likelihood\n# we still want to present and do some exploratory data analysis\ndata = pd.read_csv(INPUT_PATH + \"train.csv\")\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"984d8922bd842f22f235c79abecb6d0666c24b59"},"cell_type":"code","source":"name_label_dict = {\n0:  'Nucleoplasm',\n1:  'Nuclear membrane',\n2:  'Nucleoli',   \n3:  'Nucleoli fibrillar center',\n4:  'Nuclear speckles',\n5:  'Nuclear bodies',\n6:  'Endoplasmic reticulum',   \n7:  'Golgi apparatus',\n8:  'Peroxisomes',\n9:  'Endosomes',\n10:  'Lysosomes',\n11:  'Intermediate filaments',\n12:  'Actin filaments',\n13:  'Focal adhesion sites',   \n14:  'Microtubules',\n15:  'Microtubule ends',  \n16:  'Cytokinetic bridge',   \n17:  'Mitotic spindle',\n18:  'Microtubule organizing center',  \n19:  'Centrosome',\n20:  'Lipid droplets',\n21:  'Plasma membrane',   \n22:  'Cell junctions', \n23:  'Mitochondria',\n24:  'Aggresome',\n25:  'Cytosol',\n26:  'Cytoplasmic bodies',   \n27:  'Rods & rings' }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f5a5b6ee0a3fa350b8bfe983d759f017b7293f3e"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bfde8e96b8376f73d69a4d588aa84c927689e2d4"},"cell_type":"code","source":"# we could try a simple network:\n# which does \n# we could train 28 binary networks, or we could train one network that does 28 classifications at once\n# our keras network\n# will have the size of the initial input, be the size of the initial layer\n#  how does convolution appropriately do the patch? (when everything is linearized; assume it takes care of it for us!)\n\n# get the xtrain data as a vector, as well as the ytrain data as a vector\n# how is the loss computed?\n# it is not like Pytorch, where you need to compute a loss, then backwards yourself\n# instead, it is just fitting X and Y\n# presumably, X should be the image data, then Y should be the vector to predict\n# actually this is essentially done!\n\n# ok, so let us assume we want it as one hot vectors then!\n\n# ok, so we will create a row of zeros\n# given a row, we should make it into a k-hot vector\ndef create_one_hot(row):\n    size = len(name_label_dict)\n#     we can make a numpy array, then pass it to pandas\n    vector = np.zeros((size))\n    for label in row.loc[\"Target\"]:\n        vector[label] = 1\n    return vector\n\n    pass\n\n# we could also: just get all the labels; then, just make stuff with that. Then, we would just join or zip everything back together at the end!\n\n# for row in data.head().iterrows():\n#     print(row)\n#     print(create_one_hot(row))\n\n# data.loc[\"Target\"]\ndata.columns\n# loc is used to look up values where it is\n# data.loc['Id']\nsize = len(name_label_dict)\ny_train = []\nfor data_elts in data[\"Target\"]:\n#     we can make a numpy array, then pass it to pandas\n    vector = np.zeros((size))\n    indices = [int(elt) for elt in data_elts.split()]\n#     vector[X = 1]\n#     print(type(data_elts))\n    for elt in indices:\n        vector[elt] = 1\n\n#     print(data_elts)\n#     print(vector)\n    y_train.append(vector)\n    \n# now, we can actually begin adding it into the neural network\n# we can marry them together\n# we have both the input dims as well as the output dims! \n\n# we could have something like this. But we could also have an input layer as defined by Keras\n# model.add(Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=input_shape_img)) \n# model.add(Dense(5000, activation='relu', input_dim=X_train.shape[1]))\ny_train = np.array(y_train)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fc33e2c7c631968efe2469eda2c25a2e1fccdfed"},"cell_type":"code","source":"# now, we want to have both the X and Y\n# actually, they don't need to be explicitly joined together!\n# print(y_train)\nprint(y_train.shape)\nprint(data[\"Target\"][1])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"613dfd51db35dec5fa0a13e5d3fcf66945685089"},"cell_type":"markdown","source":"Data Loading Attempt 2 (Using Keras Datasets)\nThe point is to lazily fetch the data into memory, only when necessary. We hope that by adhereing to the guidelines, the CNN we train will work this way!\nWe can also use stuff that will auto make those labels into vectors (ex. multilabelbinarizer). "},{"metadata":{"trusted":true,"_uuid":"99b3743068f368863eba99f6792e4bf11f686fbf"},"cell_type":"code","source":"from sklearn.preprocessing import MultiLabelBinarizer\nimport keras\n# this class inherits from the dataset sampling class\nclass MyDataGenerator(keras.utils.Sequence):\n#     we need to provide a mapping, listing all the ids in both the training and validation set\n# we also need a dictinary mapping each class to its labels. Here, the implementation is a little different, since we need to adapt it to work with a LIST of labels as opposed to a single label\n    def __init__(self, data_dict, batch_size=32, dim=(512,512), n_channels=1,\n                 n_classes=28, shuffle=True, train=True):\n        'Initialization'\n        self.dim = dim\n        self.batch_size = batch_size\n        self.list_IDs = np.arange(0, len(data_dict))\n        self.n_channels = n_channels\n        self.n_classes = n_classes\n        self.shuffle = shuffle\n        self.on_epoch_end()\n        self.data_frame = data_dict\n        self.total_length = len(data_dict)\n        self.train_ds = train\n        \n        labels = list(map(str, np.arange(0,28)))\n\n        mlb = MultiLabelBinarizer(classes=labels)\n        \n        if self.train_ds:\n            x = self.data_frame[\"Target\"].apply(lambda x: x.split())\n        else:\n            x = self.data_frame[\"Predicted\"].apply(lambda x: str(x).split())\n            \n        self.label_vectors = mlb.fit_transform(x)\n\n    \n    def __len__(self):\n      'Denotes the number of batches per epoch'\n#       print (int(np.ceil(len(self.list_IDs) / self.batch_size)))\n      return int(np.ceil(len(self.list_IDs) / self.batch_size))\n    \n    def on_epoch_end(self):\n      'Updates indexes after each epoch'\n      self.indexes = np.arange(len(self.list_IDs))\n      if self.shuffle == True:\n          np.random.shuffle(self.indexes)\n                \n    # we need to keep a counter of the data! \n    def __data_generation(self, list_IDs_temp, index):\n      'Generates data containing batch_size samples' # X : (n_samples, *dim, n_channels)\n      # Initialization\n      X = np.empty((self.batch_size, *self.dim, self.n_channels))\n      y = np.empty((self.batch_size, self.n_classes), dtype=int)\n\n#         y should probably be k-dimensional as well! \n\n      # Generate data\n      # we will need to build something that can fetch all the addresses/files\n      for i, ID in enumerate(list_IDs_temp):\n          # Store sample\n#         load the data from the disk...\n          if self.train_ds:\n              X[i,] = cv2.imread(INPUT_IMAGES_PATH + self.data_frame.iloc[i][\"Id\"] + \"_green.png\", 0)[..., np.newaxis]\n          else:\n              X[i,] = cv2.imread(INPUT_IMAGES_TEST_PATH + self.data_frame.iloc[i][\"Id\"] + \"_green.png\", 0)[..., np.newaxis]\n          # load classes!!\n          y[i] = self.label_vectors[i]\n\n            \n#             we can rewrite this in terms of efficient list level operations! \n# we would need a function that batches a read however\n\n\n#           mlb.fit_transform([])  \n#       for the final batch, we should be vary of making it too large or too small!\n#       print(\"length is\")\n#       print(self.__len__())\n#       print(index)\n      \n#         this is the last batch, and we have an uneven amount\n      remainder = None\n      if (index == self.__len__()-1 and self.total_length % self.batch_size != 0):\n        remainder = self.total_length % self.batch_size\n        \n        print(\"last\")\n#         pass\n    \n      return X[:remainder], y[:remainder]\n\n\n    def __getitem__(self, index):\n      'Generate one batch of data'\n      # Generate indexes of the batch\n      indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n#       print(indexes)\n#       print(len(indexes))\n\n      # Find list of IDs\n      list_IDs_temp = [self.list_IDs[k] for k in indexes]\n\n      # Generate data\n      \n      X, y = self.__data_generation(list_IDs_temp, index)\n\n      return X, y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ceed450c39a6765fba251e3bb83354ba13e98e8d"},"cell_type":"code","source":"# We can simply pass in an array from 0 to len(data), since we are relying on pandas to do the indexing anyways\nfrom sklearn.model_selection import train_test_split\ntrain_data, valid_data = train_test_split(data)\n# Parameters\nparams = {'dim': (512,512),\n          'batch_size': 32,\n          'n_classes': 28,\n          'n_channels': 1,\n          'shuffle': True}\n\n# Datasets\ntraining_generator = MyDataGenerator(train_data[:], **params)\nvalid_generator = MyDataGenerator(valid_data[:], **params)\n\n\n# for batch in training_generator:\n#     print(batch[0].shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a09899f06f40c5cd42c5ea859f217081de8ef6f0"},"cell_type":"code","source":"# raise Error()\n# print(len(training_generator))\n\n# for index,batch in enumerate(training_generator):\n#     print(index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"40ea9d8c271a50795a971fc791363eaf412826e1"},"cell_type":"code","source":"print(485*64)\n# WARNING: we can ask for things outside the range of it!! \nfor index,elt in enumerate(training_generator[485]):\n    print(elt.shape)\n#     print(X, y)\n# print(training_generator[485])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9b0b09befce8e7a84e0116585a5797c8417bdc71"},"cell_type":"markdown","source":"**Working on the neural network**\n"},{"metadata":{"trusted":true,"_uuid":"04b030b9a6e311e80d838d0351763256022d230b"},"cell_type":"code","source":"import keras.backend as K\n# credits to: https://www.kaggle.com/rejpalcz/cnn-128x128x4-keras-from-scratch-lb-0-328\nTHRESHOLD = 0.05\nimport tensorflow as tf\n\ndef f1(y_true, y_pred):\n    #y_pred = K.round(y_pred)\n    y_pred = K.cast(K.greater(K.clip(y_pred, 0, 1), THRESHOLD), K.floatx())\n    tp = K.sum(K.cast(y_true*y_pred, 'float'), axis=0)\n    tn = K.sum(K.cast((1-y_true)*(1-y_pred), 'float'), axis=0)\n    fp = K.sum(K.cast((1-y_true)*y_pred, 'float'), axis=0)\n    fn = K.sum(K.cast(y_true*(1-y_pred), 'float'), axis=0)\n\n    p = tp / (tp + fp + K.epsilon())\n    r = tp / (tp + fn + K.epsilon())\n\n    f1 = 2*p*r / (p+r+K.epsilon())\n    f1 = tf.where(tf.is_nan(f1), tf.zeros_like(f1), f1)\n    return K.mean(f1)\n\ndef f1_loss(y_true, y_pred):\n    \n    #y_pred = K.cast(K.greater(K.clip(y_pred, 0, 1), THRESHOLD), K.floatx())\n    tp = K.sum(K.cast(y_true*y_pred, 'float'), axis=0)\n    tn = K.sum(K.cast((1-y_true)*(1-y_pred), 'float'), axis=0)\n    fp = K.sum(K.cast((1-y_true)*y_pred, 'float'), axis=0)\n    fn = K.sum(K.cast(y_true*(1-y_pred), 'float'), axis=0)\n\n    p = tp / (tp + fp + K.epsilon())\n    r = tp / (tp + fn + K.epsilon())\n\n    f1 = 2*p*r / (p+r+K.epsilon())\n    f1 = tf.where(tf.is_nan(f1), tf.zeros_like(f1), f1)\n    return 1-K.mean(f1)\n\n\n#  you should be on the right area to write things\nwith open(\"my_file.txt\", \"w\") as file:\n    file.write(\"my content\")\n    \n# anyways, now we want to do all the data \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"228751d479f6bcdf44e90d988b6b2bae87dcda9a"},"cell_type":"code","source":"# # load 5 images into memory\n# import cv2\n# from tqdm import tqdm \n# data_pics = []\n# for i,example in enumerate(tqdm(data[\"Id\"])):\n# #     even here, we must make sure to batch it appropriately!\n# #     IOW, just making a list of all of them will be difficult!\n# #     if i > 3000:\n# #         break\n#     full_path = INPUT_IMAGES_PATH + example + \"_green.png\"\n# #     print(full_path)\n#     img_data = cv2.imread(full_path, 0)\n#     data_pics.append(img_data)\n# #     print(img_data)\n# #     break\n    \n# # we should try doing some batching; keras and stuff should do this for you automatically, so long as you implement one of their datasets\n# numLength = 3000\n\n# X_train = np.array(data_pics) # this will cause an error; conversion of data_pics into an array (i.e. having two compies will be problematic!)\n# del data_pics\n# print(\"god heer\")\n# expanded_X_train = X_train[..., np.newaxis]\n# del X_train\n# print(\"added a new axis\")\n\n# expanded_X_train = expanded_X_train[0:numLength]\n# print(\"cut up the expanded_X_train\")\n\n# # print(expanded_X_train.shape)\n# y_train = y_train[0:len(expanded_X_train)]\n# # print(expanded_X_train)\n# # print(expanded_X_train.shape) \n# print(y_train.shape) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f094d78a528b036f29bdede918569721b9ab55f8"},"cell_type":"code","source":"import keras.backend as K\n# credits to: https://www.kaggle.com/rejpalcz/cnn-128x128x4-keras-from-scratch-lb-0-328\nTHRESHOLD = 0.05\nimport tensorflow as tf\n\ndef f1(y_true, y_pred):\n    #y_pred = K.round(y_pred)\n    y_pred = K.cast(K.greater(K.clip(y_pred, 0, 1), THRESHOLD), K.floatx())\n    tp = K.sum(K.cast(y_true*y_pred, 'float'), axis=0)\n    tn = K.sum(K.cast((1-y_true)*(1-y_pred), 'float'), axis=0)\n    fp = K.sum(K.cast((1-y_true)*y_pred, 'float'), axis=0)\n    fn = K.sum(K.cast(y_true*(1-y_pred), 'float'), axis=0)\n\n    p = tp / (tp + fp + K.epsilon())\n    r = tp / (tp + fn + K.epsilon())\n\n    f1 = 2*p*r / (p+r+K.epsilon())\n    f1 = tf.where(tf.is_nan(f1), tf.zeros_like(f1), f1)\n    return K.mean(f1)\n\ndef f1_loss(y_true, y_pred):\n    \n    #y_pred = K.cast(K.greater(K.clip(y_pred, 0, 1), THRESHOLD), K.floatx())\n    tp = K.sum(K.cast(y_true*y_pred, 'float'), axis=0)\n    tn = K.sum(K.cast((1-y_true)*(1-y_pred), 'float'), axis=0)\n    fp = K.sum(K.cast((1-y_true)*y_pred, 'float'), axis=0)\n    fn = K.sum(K.cast(y_true*(1-y_pred), 'float'), axis=0)\n\n    p = tp / (tp + fp + K.epsilon())\n    r = tp / (tp + fn + K.epsilon())\n\n    f1 = 2*p*r / (p+r+K.epsilon())\n    f1 = tf.where(tf.is_nan(f1), tf.zeros_like(f1), f1)\n    return 1-K.mean(f1)\n\n\n#  you should be on the right area to write things\nwith open(\"my_file.txt\", \"w\") as file:\n    file.write(\"my content\")\n    \n# anyways, now we want to do all the data \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"27356c3d9e912943e8da8879bcfe6bfef8e3effd"},"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Conv2D, Dense, Flatten, Dropout\nmodel = Sequential()\n\n# Dense probably wont work nicely at all! \n# model.add(Dense(512, activation='relu', input_dim=X_train.shape[1]))\n\n# input_dims = X_train[0].shape + (1,)\ninput_dims = (512,512,1)\nprint(type(input_dims))\nprint(input_dims)\n# print(type(X_train[0].shape))\n# we could do 2D or otger convolution\n# now we understand: both why they have green and 4 other loaders, as well as why we have batch_first and so forth\n# the input dims are for a specific example\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='same', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid'))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid'))\nmodel.add(Dropout(0.5))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid'))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid'))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid'))\nmodel.add(keras.layers.Dropout(0.5, noise_shape=None, seed=None))\n\n# model.add(Conv2D(16, (3, 3), activation='relu', padding='valid'))\n# model.add(Conv2D(16, (3, 3), activation='relu', padding='valid'))\n# model.add(Conv2D(16, (3, 3), activation='relu', padding='valid'))\n\nmodel.add(Conv2D(16, (3, 3), strides = 11, activation='relu', padding='valid'))\nmodel.add(Dropout(0.5))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Dropout(0.5))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\nmodel.add(Conv2D(16, (3, 3), activation='relu', padding='valid', input_shape=input_dims))\n\nmodel.add(Flatten())\n# we want to get the \n\nmodel.add(Dense(y_train.shape[1], activation='sigmoid'))\nmodel.add(Dropout(0.5))\n# model.add(Activation('sigmoid'))\n### Regular SGD \n# sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)\n# model.compile(loss='binary_crossentropy',\n#               optimizer=sgd)\n###\n\nmodel.compile(loss='binary_crossentropy',\n              optimizer='adam',\n              metrics=['accuracy','acc',f1] )\nprint(model.summary())\n\n# preds = model.predict(X_test)\n# Note that we cannot use too large a batch size! 64*32*512*512 is just over 5gb!!","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"bdb5985b4a5ffd134ad90bc39db9c71bc948cbdf"},"cell_type":"markdown","source":""},{"metadata":{"trusted":true,"_uuid":"baed3b0a5736ed09898ee9cba0df45c1652629f3"},"cell_type":"code","source":"!pwd\nLIMIT_STEPS = None\nmodel.fit_generator(generator=training_generator, epochs=10,\n                    steps_per_epoch=LIMIT_STEPS , validation_data=valid_generator,  verbose = 1, \n                    validation_steps=LIMIT_STEPS )\n\n# model.save('my_model_nov26.h5')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"13bd37a15899788489efa6ae9866140095ca097d"},"cell_type":"code","source":"model.save('my_model_nov30_hard_sig.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2cc73fd3391e7f7a229b342b3ec69ce3940375d2"},"cell_type":"code","source":"!ls .\n!pwd","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0953129920deb6b9984c1b9106b2f5133b298f51","scrolled":true},"cell_type":"code","source":"from keras.models import load_model\n\nmodel = load_model('../input/csc420-pea-working-model-evaluate-generator/my_model_nov26.h5')\n\nprint(model.summary())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"835d5a8e2d4db386239d9fba004a4a1c34cc082e"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cbbe0ee212326849dd855b37a64de0651fd35c7b"},"cell_type":"code","source":"model.compile(loss='binary_crossentropy',\n              optimizer='adam',\n              metrics=['categorical_accuracy', f1])\nprint(model.summary())\n# model.fit_generator(generator=training_generator, epochs=1,  verbose = 1)\nmodel.evaluate_generator(generator=training_generator,  verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9c882e676418d1efb803e803ba5eef23b94d11c3"},"cell_type":"code","source":"def f1_score(predictions, true_labels, threshold):\n    '''computes the f1_score for a given set of predictions and the true labels, and threshold'''\n#     find true positives, false negatives and so forth; these depend on the threshold!\n# they have some fancy softmax to do it without using np where and so forth! and that's fine! \n# ah, so they just provide an alternate formulation of the cost fnction!! \n\n#     true_positive = # wherever they agree and they are both 1 (AND they exceed the threshold)!\n#     true_negative = # whether they agree and they are both 0 \n    \n    \n#     y_pred = K.round(y_pred)\n#     find y_pred by checking it vs the vector of thresholds \n# do the vector comparison! \n\n    predictions[predictions > threshold] = 1\n    y_pred = predictions\n    y_true = true_labels\n#     y_pred =  \n\n    tp = K.sum(K.cast(y_true*y_pred, 'float'), axis=0)\n    # tn = K.sum(K.cast((1-y_true)*(1-y_pred), 'float'), axis=0)\n    fp = K.sum(K.cast((1-y_true)*y_pred, 'float'), axis=0)\n    fn = K.sum(K.cast(y_true*(1-y_pred), 'float'), axis=0)\n\n    p = tp / (tp + fp + K.epsilon())\n    r = tp / (tp + fn + K.epsilon())\n\n    f1 = 2*p*r / (p+r+K.epsilon())\n    f1 = tf.where(tf.is_nan(f1), tf.zeros_like(f1), f1)\n    return K.mean(f1)\n\n#     return score\n\n    \n    pass\n\n# find optimal f1_score: we also want to find the threshold which is best\ndef find_optimal_f1_threshold(predictions, true_labels):\n    params = 0.5*np.ones(len(name_label_dict))\n\n#     call to least squares here\n# least squares\n#     p should be a 28-dim vector\n    error = lambda p: (f1_score(predictions,true_labels,p)\n                                      ) # flatten the arrays before concatenating them!\n#     so this now will tell us what we want vs what we get\n#     f1 score will give us a score, while the true score will give us the wd*(p-0.5)\n\n    #     so we can get out the solutions to this problem, as well as the covaraince stuff \n    import scipy\n    \n    p, success = scipy.optimize.leastsq(error, params) \n    \n    return p\n\n# then, we apply the threshold to get the actual classifications\n#  the threshold is done via already making classifications! hence, we need to back up a bit!","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e62c1e720faf17d09dc9a09e21ea40f2fbfa82a2"},"cell_type":"code","source":"params = {'dim': (512,512),\n          'batch_size': 64,\n          'n_classes': 28,\n          'n_channels': 1,\n          'shuffle': True}\nevaluation_generator = MyDataGenerator(data, **params)\n\n\n# submit = pd.read_csv(DIR + '/sample_submission.csv')\n# P = np.zeros((pathsTest.shape[0], 28))\n# for i in tqdm(range(len(testg))):\n#     images, labels = testg[i]\n#     score = bestModel.predict(images)\n#     P[i*BATCH_SIZE:i*BATCH_SIZE+score.shape[0]] = score","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e3b921186f14737d03aa924f10b0ed02902972ff"},"cell_type":"code","source":"model.evaluate_generator(generator=evaluation_generator, verbose = 1)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"015a03169d70508c4c88e190c0a73e7949beb36e"},"cell_type":"code","source":"# we just want to get all the predictions out now!! \n\n# my_predictions =model.predict_generator(generator=evaluation_generator, verbose = 1)\n\n# smaller evaluation generator\n# evaluation_generator = MyDataGenerator(data[0:1000], **params)\n# my_predictions =model.predict_generator(generator=evaluation_generator, verbose = 1)\n\n#CONSIDER  we are also randomizing the batch data, so we should get the actual order that it was randomized as well!","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"67bb2984a12d125d284499c6a778cb3986382364"},"cell_type":"code","source":"print(len(evaluation_generator))\nprint(len(training_generator))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"516f54a6672cf847b9d31a1a45a733de1c0c8bcb"},"cell_type":"code","source":"485*32*2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0fd3899b59d3d9e2069bce8d6cdc5c886f398d5f"},"cell_type":"code","source":"# now, let us examine the predictions, potentially needing to sort them!\n# we really just need to turn it into a string, amenable for the predictions!! \nLIMIT_SIZE = None\n# print(my_predictions)\nlabels = list(map(str, np.arange(0,28)))\n\nmlb = MultiLabelBinarizer(classes=labels)\nx = data[\"Target\"].apply(lambda x: x.split())[:LIMIT_SIZE]\n\nlabel_vectors = mlb.fit_transform(x)\nprint(len(my_predictions))\nprint(len(label_vectors))\n# ideally: what we have is the following: both a list of thresholds for all the classes, as well as\n# the scores for al of the classes\n# find_optimal_f1_threshold(my_predictions,label_vectors )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8f1d3caaa02a55cc4c1dc07c7dc2970eee86b3bb"},"cell_type":"code","source":"from tqdm import tqdm\n\nlastFullValPred = np.empty((0, 28))\nlastFullValLabels = np.empty((0, 28))\nfor i in tqdm(range(len(evaluation_generator))): \n    im, lbl = evaluation_generator[i]\n    scores = model.predict(im)\n    lastFullValPred = np.append(lastFullValPred, scores, axis=0)\n    lastFullValLabels = np.append(lastFullValLabels, lbl, axis=0)\nprint(lastFullValPred.shape, lastFullValLabels.shape)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b12bebb7c968e18134a56ccc06a64ca7f92ce219"},"cell_type":"code","source":"from sklearn.metrics import f1_score as off1\nrng = np.arange(0, 0.00, 0.01)\nrng = np.array([0])\nprint(rng.shape)\n# print(rng)\n\nrng = np.concatenate((rng, np.arange(0.01, 1,0.01)), None )\nrng = np.arange(0.001, 1, 0.01)\nprint(rng)\nf1s = np.zeros((rng.shape[0], 28))\n\nrow_sums = lastFullValPred.sum(axis=1)\nprint(row_sums[1])\nprint(\"rybbubg\")\nnormalized_lastFullValPred = lastFullValPred/row_sums[:, np.newaxis]\n# print(normalized_lastFullValPred[0:1])\n# print(np.sum(normalized_lastFullValPred[0]))\nfor j,t in enumerate(tqdm(rng)):\n    for i in range(28):\n#         print(p)\n        \n        p = np.array(normalized_lastFullValPred[:,i]>t, dtype=np.int8)\n        scoref1 = off1(lastFullValLabels[:,i], p, average='binary')\n        f1s[j,i] = scoref1\n        \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d60d0be697f84b9099530464966fbf0620ed21e1"},"cell_type":"code","source":"print('Individual F1-scores for each class:')\nprint(np.max(f1s, axis=0))\nprint('Macro F1-score CV =', np.mean(np.max(f1s, axis=0)))\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"43c0c4f8334ed98ebd74727fb0c308103a4ec476"},"cell_type":"code","source":"plt.plot(rng, f1s)\nT = np.empty(28)\nfor i in range(28):\n    T[i] = rng[np.where(f1s[:,i] == np.max(f1s[:,i]))[0][0]]\nprint('Probability threshold maximizing CV F1-score for each class:')\nprint(T)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fce94fc5085cb8dcd727c12b7d7193b0f3aa2742"},"cell_type":"code","source":"def getTestDataset():\n    \n    path_to_test = INPUT_PATH  + '/test/'\n    test_data = pd.read_csv(INPUT_PATH + '/sample_submission.csv')\n\n    paths = []\n    labels = []\n    \n    for name in data['Id']:\n        y = np.ones(28)\n        paths.append(os.path.join(path_to_test, name))\n        labels.append(y)\n\n    return np.array(paths), np.array(labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f72832dfb19c52489303017dc966003bdafe8d08"},"cell_type":"code","source":"pathsTest, labelsTest = getTestDataset()\nBATCH_SIZE = 64\n\nparams = {'dim': (512,512),\n          'batch_size': 64,\n          'n_classes': 28,\n          'n_channels': 1,\n          'shuffle': True, \n         'train': False}\n\ntest_data = pd.read_csv(INPUT_PATH + '/sample_submission.csv')\nprint(test_data)\n\ntestg = MyDataGenerator(test_data, **params)\nsubmit = pd.read_csv(INPUT_PATH + '/sample_submission.csv')\nP = np.zeros((len(test_data), 28))\nfor i in tqdm(range(len(testg))):\n    images, labels = testg[i]\n    score = model.predict(images)\n#     print(score)\n#     print(score.shape)\n#     score = np.\n    row_sums = score.sum(axis=1)\n    score = score / row_sums[:, np.newaxis]\n    \n#     score = score / np.sum(score)\n#     print(score)\n#     print(np.sum(score, axis=1))\n    P[i*BATCH_SIZE:i*BATCH_SIZE+score.shape[0]] = score\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eb432ec342ecdc039c87654299a26426add51d1e"},"cell_type":"code","source":"PP = np.array(P)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ff716be0f24dd44cfb37de6e9c8d308827b107ef"},"cell_type":"code","source":"prediction = []\n# submit['Predicted'] = []\nfor row in tqdm(range(submit.shape[0])):\n#     print(\"ok\")\n    str_label = ''\n    \n    for col in range(PP.shape[1]):\n        if(PP[row, col] < T[col]):\n#             print(T[col])\n            str_label += ''\n        else:\n            str_label += str(col) + ' '\n    prediction.append(str_label.strip())\n#     print(\"these are preds\")\n#     print(prediction)\n#     break\n    \nsubmit['Predicted'] = np.array(prediction)\nsubmit.to_csv('csc420_scratch.csv', index=False)\nprint(submit.to_csv)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}