{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.python.framework import ops\nimport numpy as np\nimport pandas as pd\nimport os\nimport random\nfrom PIL import Image\nimport skimage\nimport glob\nfrom skimage import transform\nimport matplotlib.pyplot as plt\nfrom keras import layers ,regularizers\nfrom keras.layers import Input, Add, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D\nfrom keras.models import Model, load_model\nfrom keras.preprocessing import image\nfrom keras.utils import layer_utils\nfrom sklearn.preprocessing import LabelBinarizer\nfrom keras.utils.data_utils import get_file\nfrom keras.applications.imagenet_utils import preprocess_input","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"collapsed":true},"cell_type":"code","source":"# this fun load data set and shuffle it too \ndef loadData():\n    '''read data, shuffle it  , split it into training and test and reshape it to (100*100*3)\n    \n    - parameters \n    \n        - no inputs\n        \n        - outputs :\n            # assume (tr) num of images of training & (te) num of images of test\n            - trainingX : np array and shape of (tr,100,100,3)\n            - trainigY : np array shape of (tr,1 )\n            - testX : np array and shape of (te,100,100,3)\n            - testY : np array shape of (te,1 )\n            \n    '''\n    # read images names and labels \n    imageNames = np.array(glob.glob(\"../input/train/*.jpg\"))\n    imageLabels = np.array([f[15:18] for f in imageNames])\n    #imageNames = np.array([f for f in os.listdir(\"../input/train/\")])\n    #imageLabels = np.array([f[0:3] for f in imageNames])\n    \n    # shuffl data \n    m = len(imageLabels)\n    randomIndex = list(np.random.permutation(m))\n    Y_shuffled = imageLabels[randomIndex]\n    imageName_shuffled = imageNames[randomIndex]\n    \n    # splid data into 80% traning and 20% test \n    trainingLen = int(m * .8)\n    testLen = m - trainingLen\n    \n    trainingY = Y_shuffled[0:trainingLen]\n    trainingX_names = imageName_shuffled[0:trainingLen]\n    \n    testY = Y_shuffled[trainingLen:m]\n    testX_names = imageName_shuffled[trainingLen:m]\n    \n    # load images as rgb\n    trainingX = []\n    testX = []\n    \n    for imgName in trainingX_names: #load training images\n        img = np.array(Image.open(imgName))\n        img = skimage.transform.resize(img, output_shape =(100,100))\n        trainingX.append(img)\n    \n    for imgName in testX_names: #load test images\n        img = np.array(Image.open(imgName))\n        img = skimage.transform.resize(img, output_shape =(100,100))\n        testX.append(img)\n    \n    # convert list of trainingX and testX to matrix\n    trainingX = np.array(trainingX,dtype=\"float32\")\n    testX = np.array(testX,dtype=\"float32\")\n    \n\n\n    return trainingX,trainingY,testX,testY","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a6622415b42bbe9e99fd2547d5f656c53e57844a","collapsed":true},"cell_type":"code","source":"def oneHot(y):\n    ''' convert labels into one hot coding \n        parameters:\n            - input : list of labels \n            - output : np array of one hot encoding \n    '''\n    encoder = LabelBinarizer()\n    y = encoder.fit_transform(y)\n    return y\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"15c493ff19ac5c0d4e4d1974ed106dc471d7befe","collapsed":true},"cell_type":"code","source":"# this fun plot example of our images data \ndef plot_figures(x,y,nrows = 3, ncols=4):\n    \"\"\"Plot random figures of data.\n\n    Parameters\n    ----------\n    ncols : number of columns of subplots wanted in the display\n    nrows : number of rows of subplots wanted in the figure\n    \"\"\"\n    # generate random indexs \n    indexs = random.sample(range(0, len(y)), nrows*ncols)\n    \n    fig, axeslist = plt.subplots(ncols=ncols, nrows=nrows,figsize=(10,10))\n    for ind,i in enumerate(indexs):\n        axeslist.ravel()[ind].imshow(x[i], cmap=plt.gray())\n        axeslist.ravel()[ind].set_title(y[i])\n        axeslist.ravel()[ind].set_axis_off()\n    #plt.tight_layout() # optional\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"6084e3fe294071f63c1c64c35ca228edcba26408"},"cell_type":"code","source":"def identityBlock(inputs,stage,block,f,kernal_size=3,s=1):\n    ''' Implementation of indentity block for resNet when input's shape of block == output's shape\n        # using f = 3*3 and num of skipping layers is 3 and s = 1\n        args:\n            - inpute : input tensor of indentity block-- shape (m,h_prev,w_prev,c_prev)\n            - f : int num -- num of filters for every layer in this block \n            - kernal_size : int num -- kernal_size of conv layers of main path \n            - stage : int num -- the number of current stage of resNet, we use it to set names of conv leayers\n            - block :int num -- the number of current block of current stage, we use it to set names of conv leayers\n            - s :  int num -- stride\n\n        output :\n         - x tensor with shape (m,h,w,c) -- c=f\n    '''\n    \n    x = inputs\n    stage = str(stage)\n    block =str(block)\n    nameBase = 'stage'+stage+'-block'+block\n    # first \n    x = Conv2D(f, (kernal_size,kernal_size),padding='same',strides = (s,s),kernel_initializer='he_normal',name = 'a-'+nameBase)(x)\n    x = BatchNormalization(name='bn-a-'+nameBase,axis = 3)(x)\n    x = Activation('relu')(x)\n    \n    # seconde \n    x = Conv2D(f, (kernal_size,kernal_size),padding='same',strides = (s,s),kernel_initializer='he_normal',name = 'b-'+nameBase)(x)\n    x = BatchNormalization(name='bn-b-'+nameBase,axis = 3)(x)\n    x = Activation('relu')(x)\n    \n    #third\n    x = Conv2D(f, (kernal_size,kernal_size),padding='same',strides = (s,s),kernel_initializer='he_normal',name = 'c-'+nameBase)(x)\n    x = BatchNormalization(name='bn-c-'+nameBase,axis = 3)(x)\n    \n    #short \n    x = Add()([x,inputs])\n    x = Activation('relu')(x)\n    \n    return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"835cb0093c800a6c7570ac49880bea68233bb989"},"cell_type":"code","source":"def convBlock(inputs,stage,block,f,kernal_size=3,s=2):\n    ''' Implementation of indentity block for resNet when input's shape of block != output's shape\n        # using f = 3*3 and num of skipping layers is 3 and s = 1\n        args:\n            - inpute : input tensor of indentity block-- shape (m,h_prev,w_prev,c_prev)\n            - f : int num -- num of filters for every layer in this block \n            - kernal_size : int num -- kernal_size of conv layers of main path \n            - stage : int num -- the number of current stage of resNet, we use it to set names of conv leayers\n            - block :int num -- the number of current block of current stage, we use it to set names of conv leayers\n            - s :  int num -- stride\n\n        output :\n         - x tensor with shape (m,h,w,c) -- c=f\n    '''\n    x = inputs\n    stage = str(stage)\n    block = str(block)\n    nameBase = 'stage'+stage+'-block'+block\n    #first\n    x = Conv2D(f, (kernal_size,kernal_size),padding='valid',strides = (s,s),kernel_initializer='he_normal',name = 'a-'+nameBase)(x)\n    x = BatchNormalization(name='bn-a-'+nameBase,axis = 3)(x)\n    x = Activation('relu')(x)\n    \n    #seconde\n    x = Conv2D(f,(kernal_size,kernal_size),padding='same',strides = (1,1),kernel_initializer='he_normal',name = 'b-'+nameBase)(x)\n    x = BatchNormalization(name='bn-b-'+nameBase,axis = 3)(x)\n    x = Activation('relu')(x)\n    \n    #third\n    x = Conv2D(f, (kernal_size,kernal_size),padding='same',strides = (1,1),kernel_initializer='he_normal',name = 'c-'+nameBase)(x)\n    x = BatchNormalization(name='bn-c-'+nameBase,axis = 3)(x)\n\n    #conv for inputs before add it to x \n    inputs = Conv2D(f,(kernal_size,kernal_size),padding='valid',strides = (2,2),kernel_initializer='he_normal',name = 'short-'+nameBase)(inputs)\n    inputs = BatchNormalization(name='bn-short-'+nameBase,axis = 3)(inputs)\n    \n    #add shortcut to x\n    x = Add()([x,inputs])\n    x = Activation('relu')(x)\n    \n    return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5b13ad91e525b51695a0c9aa1d32cb2a6841fcdf","collapsed":true},"cell_type":"code","source":"def resNet35(inputShape):\n    '''Implementation of ResNet with 35 layers \n    Architecture :\n        ->conv2D -> batchNorm -> maxPool = 1 layer \n        -> stage1 =  2*identityBlock = 6 layers\n        -> stage2 = 1*convBlock + 2*identityBlock = 9 layers\n        -> stage3 = 1*convBlock + 3*identityBlock = 12 layers\n        -> stage4 = 1*convBlock + 1*identityBlock = 6 layers\n        -> avgPool -> FC softmax with 1 node (num of class = 2 so output nodes = 1 ) = 1 layer\n    \n    '''\n\n    \n    ###############################\n    \n    BlockNum = [2,3,4,2] # list for number of blocks in every stage \n    kernal_size = [64,128,256,512]\n    modelInput =Input(inputShape[1:]) # define input tensor to feed it later to keras Model\n    x=modelInput\n    print(x.shape)\n    # first layer conv2D ->  batchNorm -> maxPool\n    x = Conv2D(64,(7,7),padding='same',strides=(2,2),name='conv-first',kernel_initializer='he_normal')(x)\n    x = BatchNormalization(name='bn-first',axis = 3)(x)\n    x = MaxPooling2D((3, 3), strides=(2, 2))(x)\n    \n    ## stages and blocks loop\n    for stage in range(1,5):\n        f = kernal_size[stage-1] #num of filters for current stage \n        block =(BlockNum[stage-1])\n        for b in range(block):\n            if stage==1: #first stage so we don't need convBlock\n                x = identityBlock(x,stage,b,f,kernal_size=3,s=1)\n\n            else : \n                if b ==0 : # not first stage but first block\n                    x = convBlock(x,stage,b,f,kernal_size=3,s=2)\n                else:\n                    x = identityBlock(x,stage,b,f,kernal_size=3,s=1)\n    \n    # avgPool layer\n    x= AveragePooling2D(pool_size=(2, 2),name='avg_pool',padding='same')(x)\n    # FC layer\n    x = Flatten()(x)\n    #x = Dense(100,name=\"fc1\", kernel_initializer = 'glorot_uniform',activation='relu',kernel_regularizer=regularizers.l2(0.01))(x)\n    x = Dense(1,name=\"fc\", kernel_initializer = 'glorot_uniform',activation='sigmoid')(x)\n    model = Model(inputs = modelInput, outputs = x, name='ResNet35')\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fcdee94dc71c9d8c6b8d4c34cce98cc77506ed80"},"cell_type":"code","source":"\n## let's start work \n\n#load data \ntrainingX,trainingY,testX,testY = loadData()\n\n# encoding trainingY and testY\ntrainingY=oneHot(trainingY)\ntestY=oneHot(testY)\n\n# check our dim\nprint(\"training X shape is \", trainingX.shape)\nprint(\"training y shape is \", trainingY.shape)\nprint(\"test X shape is \", testX.shape)\nprint(\"test y shape is \", testY.shape)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9f8c28c6c5b931bdd7915bf715fcd0789f7eb4b1"},"cell_type":"code","source":"# plot Figures \nplot_figures(trainingX,trainingY,nrows = 3, ncols=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6eeaf14cbb1fdcbfb4a454ea84a82ff0d631c670"},"cell_type":"code","source":"# call model\nmodel = resNet35(trainingX.shape)\nmodel.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"516a124ef4179c5ffa8c5b8449a2cc95fdde9dce"},"cell_type":"code","source":"#start training\nhistory = model.fit(trainingX,\n                    trainingY,\n                    epochs = 50,\n                    batch_size = 64,\n                    validation_data=(testX,testY), \n                    shuffle = True)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0ce38aa4d46d414a2bf257a9c9f66ddad6ced04e","_cell_guid":"ce0ad88b-4a6b-44bc-870e-a358ca00d2a3","trusted":true,"collapsed":true},"cell_type":"code","source":"def plotModelHistory(modeHistory):\n    # summarize history for accuracy\n    history = modeHistory\n    plt.plot(history.history['acc'])\n    plt.plot(history.history['val_acc'])\n    plt.title('model accuracy')\n    plt.ylabel('accuracy')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'test'], loc='upper left')\n    plt.show()\n    # summarize history for loss\n    plt.plot(history.history['loss'])\n    plt.plot(history.history['val_loss'])\n    plt.title('model loss')\n    plt.ylabel('loss')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'test'], loc='upper left')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"17779c6253d047dc7d3169bfdbcea8a3aaccefc4"},"cell_type":"code","source":"plotModelHistory(history)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"2ec0885a1610f6fa1529cba749884186d3a8ee04"},"cell_type":"code","source":"#save model\nmodel.save_weights('resNet35_wieghts.h5')\nmodel.save('model_keras.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"7df831c661c5544ad550e2168640e06530a9fb9f"},"cell_type":"code","source":"# del some data \ndel trainingX,trainingY , testX,testY","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"75eeb020d810c5f911263adbf6ceb6b07ef0bcde"},"cell_type":"code","source":"#load test data\ndef loadTestData():\n    path = '../input/test/*jpg'\n    imageNames=glob.glob(path)\n    m = len(imageNames)\n    test_x = np.zeros((m,100,100,3),dtype=np.float32)\n    test_y = np.zeros((m,1))\n    for i in range(m):\n        img = np.array(Image.open(imageNames[i]))\n        img = skimage.transform.resize(img, output_shape =(100,100))\n        test_x [i] = img\n    return test_x , test_y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3b0eb8668a41d1c0f74b2a1b2f81fc49165ebfc8"},"cell_type":"code","source":"test_x , test_y = loadTestData()\ntest_y = model.predict(test_x)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1215c0d17e211351e08c98e37517ba16459eda3d"},"cell_type":"code","source":"# plot some test image with there predicted label\nplot_figures(test_x,test_y,nrows = 3, ncols=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"781dc76ab38c4ce91a20f9c1becdfba45f4e9a64"},"cell_type":"code","source":"# save submission file \nframe = pd.DataFrame({'label': test_y.T.squeeze()})\nframe = frame.reset_index(drop=True)\nframe.index += 1 \nframe.to_csv(\"Dogs Vs. Cats.csv\", index_label='id')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"38f24c08b1752090515c3341a7534db24f5cebad"},"cell_type":"code","source":"print(frame)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"e8fddb2fc863c993e5cdf538086ebdf62198dcbc"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}