{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Standard data science libraries\nimport psutil\nimport humanize\nimport os\nfrom IPython.display import display_html\n\n# 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\nprint(os.listdir(\"./\"))\ndataDirectory= \"./\" \nprint(os.listdir(dataDirectory))\n\n# Any results you write to the current directory are saved as output.        ","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:30:59.730314Z","iopub.execute_input":"2021-06-18T12:30:59.730634Z","iopub.status.idle":"2021-06-18T12:30:59.749378Z","shell.execute_reply.started":"2021-06-18T12:30:59.730603Z","shell.execute_reply":"2021-06-18T12:30:59.748416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -r ~/.keras\n!mkdir ~/.keras\n!mkdir ~/.keras/models\n# not enough space for both\n#!cp ../input/keras-pretrained-models/* ~/.keras/models/ \n#!cp ../input/vgg19/* ~/.keras/models\n!cp ../input/keras-pretrained-models/*notop* ~/.keras/models/\n!cp ../input/keras-pretrained-models/imagenet_class_index.json ~/.keras/models/\n#!cp ../input/keras-pretrained-models/resnet50* ~/.keras/models/","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:30:59.751046Z","iopub.execute_input":"2021-06-18T12:30:59.751389Z","iopub.status.idle":"2021-06-18T12:31:09.835922Z","shell.execute_reply.started":"2021-06-18T12:30:59.751353Z","shell.execute_reply":"2021-06-18T12:31:09.834838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport keras\nfrom keras import backend as K\nfrom keras.models import Sequential\nfrom keras.models import Model\nfrom keras.layers import Activation\nfrom keras.layers.core import Dense, Flatten\nfrom keras.optimizers import Adam\nfrom keras.metrics import categorical_crossentropy\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.layers.normalization import BatchNormalization\nfrom keras.layers.core import Dropout\nfrom keras.layers.convolutional import *\nfrom keras.callbacks import ModelCheckpoint\nfrom keras.applications.inception_v3 import InceptionV3\nfrom keras.applications.inception_v3 import preprocess_input\nfrom keras.applications.inception_v3 import decode_predictions\nfrom sklearn.metrics import confusion_matrix\nfrom sklearn.metrics import average_precision_score\nfrom sklearn.metrics import recall_score\nfrom sklearn.metrics import precision_score\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.metrics import classification_report\nfrom keras.models import model_from_json\nimport itertools\nimport matplotlib.pyplot as plt\nimport time\nimport pandas as pd\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:09.840164Z","iopub.execute_input":"2021-06-18T12:31:09.840431Z","iopub.status.idle":"2021-06-18T12:31:15.640792Z","shell.execute_reply.started":"2021-06-18T12:31:09.840403Z","shell.execute_reply":"2021-06-18T12:31:15.639938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = dataDirectory+'/train'\ntest_path  = dataDirectory+'/test'\nprint(os.listdir(train_path))\nprint(os.listdir(test_path))","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:15.6423Z","iopub.execute_input":"2021-06-18T12:31:15.642629Z","iopub.status.idle":"2021-06-18T12:31:15.869312Z","shell.execute_reply.started":"2021-06-18T12:31:15.642593Z","shell.execute_reply":"2021-06-18T12:31:15.831437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n        rotation_range=40,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        shear_range=0.2,\n        zoom_range=0.2,\n        fill_mode='nearest',\n    validation_split=0.2) # set validation split","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:15.873121Z","iopub.execute_input":"2021-06-18T12:31:15.873805Z","iopub.status.idle":"2021-06-18T12:31:15.902919Z","shell.execute_reply.started":"2021-06-18T12:31:15.873758Z","shell.execute_reply":"2021-06-18T12:31:15.893466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"selectedClasses = ['copepod_cyclopoid_oithona', 'copepod_calanoid_frillyAntennae', 'radiolarian_colony', 'copepod_calanoid_large_side_antennatucked', 'hydromedusae_narco_dark', 'hydromedusae_other', 'trichodesmium_puff', 'radiolarian_chain', 'trichodesmium_multiple', 'fish_larvae_leptocephali', 'ctenophore_cydippid_tentacles', 'copepod_other', 'hydromedusae_liriope', 'siphonophore_partial', 'tornaria_acorn_worm_larvae', 'chordate_type1', 'protist_star', 'siphonophore_calycophoran_rocketship_adult', 'fish_larvae_medium_body', 'polychaete', 'jellies_tentacles', 'artifacts', 'invertebrate_larvae_other_B', 'hydromedusae_typeD_bell_and_tentacles', 'pteropod_triangle', 'tunicate_salp', 'hydromedusae_solmundella', 'tunicate_doliolid', 'appendicularian_fritillaridae', 'siphonophore_physonect', 'hydromedusae_bell_and_tentacles', 'fish_larvae_thin_body', 'ctenophore_cestid', 'fish_larvae_deep_body', 'artifacts_edge', 'copepod_calanoid_small_longantennae', 'crustacean_other', 'hydromedusae_partial_dark', 'hydromedusae_typeD', 'unknown_blobs_and_smudges', 'protist_noctiluca', 'siphonophore_physonect_young', 'hydromedusae_aglaura', 'copepod_calanoid_octomoms', 'detritus_filamentous', 'hydromedusae_typeF', 'siphonophore_other_parts', 'unknown_unclassified', 'detritus_blob', 'echinoderm_larva_pluteus_early', 'siphonophore_calycophoran_rocketship_young', 'appendicularian_slight_curve', 'appendicularian_s_shape', 'hydromedusae_typeE', 'acantharia_protist_big_center', 'echinoderm_larva_pluteus_typeC', 'trochophore_larvae', 'protist_dark_center', 'echinoderm_seacucumber_auricularia_larva', 'unknown_sticks', 'tunicate_salp_chains', 'invertebrate_larvae_other_A', 'pteropod_theco_dev_seq', 'amphipods', 'acantharia_protist_halo', 'acantharia_protist', 'echinoderm_larva_pluteus_brittlestar', 'chaetognath_other', 'chaetognath_sagitta', 'trichodesmium_tuft', 'hydromedusae_haliscera', 'fish_larvae_myctophids', 'decapods', 'trichodesmium_bowtie', 'tunicate_partial', 'hydromedusae_shapeA', 'heteropod', 'fish_larvae_very_thin_body', 'hydromedusae_solmaris', 'hydromedusae_haliscera_small_sideview', 'echinopluteus', 'pteropod_butterfly', 'euphausiids', 'echinoderm_larva_seastar_brachiolaria', 'ctenophore_lobate', 'shrimp-like_other', 'echinoderm_larva_pluteus_urchin', 'copepod_calanoid', 'protist_other', 'siphonophore_calycophoran_sphaeronectes', 'ephyra', 'copepod_calanoid_flatheads', 'siphonophore_calycophoran_sphaeronectes_young', 'siphonophore_calycophoran_sphaeronectes_stem', 'hydromedusae_narcomedusae', 'diatom_chain_tube', 'chaetognath_non_sagitta', 'shrimp_sergestidae', 'siphonophore_calycophoran_abylidae', 'copepod_cyclopoid_copilia', 'echinoderm_larva_seastar_bipinnaria', 'hydromedusae_shapeA_sideview_small', 'shrimp_zoea', 'fecal_pellet', 'shrimp_caridean', 'ctenophore_cydippid_no_tentacles', 'stomatopod', 'hydromedusae_sideview_big', 'copepod_calanoid_eggs', 'diatom_chain_string', 'tunicate_doliolid_nurse', 'hydromedusae_narco_young', 'copepod_calanoid_large', 'appendicularian_straight', 'hydromedusae_shapeB', 'hydromedusae_h15', 'copepod_calanoid_eucalanus', 'euphausiids_young', 'detritus_other', 'protist_fuzzy_olive', 'copepod_cyclopoid_oithona_eggs']","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:15.904713Z","iopub.execute_input":"2021-06-18T12:31:15.905023Z","iopub.status.idle":"2021-06-18T12:31:16.595816Z","shell.execute_reply.started":"2021-06-18T12:31:15.90499Z","shell.execute_reply":"2021-06-18T12:31:16.590531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batchSize=32\n\n\ntrain_generator = train_datagen.flow_from_directory(\n    train_path,\n    target_size=(224, 224),\n    batch_size=batchSize,\n    classes=selectedClasses,\n    subset='training') # set as training data\n\nvalidation_generator = train_datagen.flow_from_directory(\n    train_path, # same directory as training data\n    target_size=(224, 224),\n    batch_size=batchSize,\n    classes=selectedClasses,\n    subset='validation') # set as validation data\n\ntest_generator = ImageDataGenerator().flow_from_directory(\n    test_path, \n    target_size=(224,224), \n    classes=selectedClasses,\n    shuffle= False,\n    batch_size = batchSize)# set as test data","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:16.600267Z","iopub.execute_input":"2021-06-18T12:31:16.600526Z","iopub.status.idle":"2021-06-18T12:31:18.421838Z","shell.execute_reply.started":"2021-06-18T12:31:16.600499Z","shell.execute_reply":"2021-06-18T12:31:18.420907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print (\"In train_generator \")\nfor cls in range(len (train_generator.class_indices)):\n    print(selectedClasses[cls],\":\\t\",list(train_generator.classes).count(cls))\nprint (\"\") \n\nprint (\"In validation_generator \")\nfor cls in range(len (validation_generator.class_indices)):\n    print(selectedClasses[cls],\":\\t\",list(validation_generator.classes).count(cls))\nprint (\"\") \n\nprint (\"In test_generator \")\nfor cls in range(len (test_generator.class_indices)):\n    print(selectedClasses[cls],\":\\t\",list(test_generator.classes).count(cls))","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:18.423508Z","iopub.execute_input":"2021-06-18T12:31:18.423858Z","iopub.status.idle":"2021-06-18T12:31:27.842725Z","shell.execute_reply.started":"2021-06-18T12:31:18.423821Z","shell.execute_reply":"2021-06-18T12:31:27.822971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#plots images with labels within jupyter notebook\ndef plots(ims, figsize = (22,22), rows=4, interp=False, titles=None, maxNum = 9):\n    if type(ims[0] is np.ndarray):\n        ims = np.array(ims).astype(np.uint8)\n        if(ims.shape[-1] != 3):\n            ims = ims.transpose((0,2,3,1))\n           \n    f = plt.figure(figsize=figsize)\n    #cols = len(ims) //rows if len(ims) % 2 == 0 else len(ims)//rows + 1\n    cols = maxNum // rows if maxNum % 2 == 0 else maxNum//rows + 1\n    #for i in range(len(ims)):\n    for i in range(maxNum):\n        sp = f.add_subplot(rows, cols, i+1)\n        sp.axis('Off')\n        if titles is not None:\n            sp.set_title(titles[i], fontsize=20)\n        plt.imshow(ims[i], interpolation = None if interp else 'none')   ","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:27.844082Z","iopub.execute_input":"2021-06-18T12:31:27.844441Z","iopub.status.idle":"2021-06-18T12:31:27.854559Z","shell.execute_reply.started":"2021-06-18T12:31:27.844405Z","shell.execute_reply":"2021-06-18T12:31:27.853757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator.reset()\nimgs, labels = train_generator.next()\n\n#print(labels)\n\nlabelNames=[]\nlabelIndices=[np.where(r==1)[0][0] for r in labels]\n#print(labelIndices)\n\nfor ind in labelIndices:\n    for labelName,labelIndex in train_generator.class_indices.items():\n        if labelIndex == ind:\n            #print (labelName)\n            labelNames.append(labelName)\n\n#labels","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:27.855904Z","iopub.execute_input":"2021-06-18T12:31:27.856285Z","iopub.status.idle":"2021-06-18T12:31:28.164105Z","shell.execute_reply.started":"2021-06-18T12:31:27.856246Z","shell.execute_reply":"2021-06-18T12:31:28.163235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plots(imgs, rows=4, titles = labelNames, maxNum=8)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:28.166558Z","iopub.execute_input":"2021-06-18T12:31:28.166956Z","iopub.status.idle":"2021-06-18T12:31:28.899309Z","shell.execute_reply.started":"2021-06-18T12:31:28.166917Z","shell.execute_reply":"2021-06-18T12:31:28.898372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#InceptionV3\n\nbase_model = InceptionV3(weights='imagenet', \n                                include_top=False, \n                                input_shape=(224, 224,3))\nbase_model.trainable = False\n\nx = base_model.output\nx = keras.layers.GlobalAveragePooling2D()(x)\n# let's add a fully-connected layer\nx = Dropout(0.5)(x)\n# and a sofymax/logistic layer -- we have 6 classes\npredictions = Dense(len(selectedClasses), activation='softmax')(x)\n\n# this is the model we will train\nmodel = Model(inputs=base_model.input, outputs=predictions)\n\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:28.900816Z","iopub.execute_input":"2021-06-18T12:31:28.901144Z","iopub.status.idle":"2021-06-18T12:31:32.952324Z","shell.execute_reply.started":"2021-06-18T12:31:28.901109Z","shell.execute_reply":"2021-06-18T12:31:32.94547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Atutomatic rename with epoch number and val accuracy:\n#filepath=\"checkpoints/weights-improvement-epeoch-{epoch:02d}-val_acc-{val_acc:.2f}.hdf5\"\n\n\n \nmodelName= \"InceptionTutorial\"\n#save the best weights over the same file with the model name\n\n#filepath=\"checkpoints/\"+modelName+\"_bestweights.hdf5\"\nfilepath=modelName+\"_bestweights.hdf5\"\ncheckpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')\ncallbacks_list = [checkpoint]","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:32.953775Z","iopub.execute_input":"2021-06-18T12:31:32.954121Z","iopub.status.idle":"2021-06-18T12:31:32.959297Z","shell.execute_reply.started":"2021-06-18T12:31:32.954085Z","shell.execute_reply":"2021-06-18T12:31:32.958469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(Adam(lr=0.0001), loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:32.960788Z","iopub.execute_input":"2021-06-18T12:31:32.961128Z","iopub.status.idle":"2021-06-18T12:31:32.985714Z","shell.execute_reply.started":"2021-06-18T12:31:32.961094Z","shell.execute_reply":"2021-06-18T12:31:32.984803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"stepsPerEpoch= (train_generator.samples+ (batchSize-1)) // batchSize\nprint(\"stepsPerEpoch: \", stepsPerEpoch)\n\nvalidationSteps=(validation_generator.samples+ (batchSize-1)) // batchSize\nprint(\"validationSteps: \", validationSteps)\n\n\n#validationSteps=(test_generator.samples+ (batchSize-1)) // batchSize\n#print(\"validationSteps: \", validationSteps)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:32.987292Z","iopub.execute_input":"2021-06-18T12:31:32.987644Z","iopub.status.idle":"2021-06-18T12:31:32.994241Z","shell.execute_reply.started":"2021-06-18T12:31:32.987608Z","shell.execute_reply":"2021-06-18T12:31:32.993364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator.reset()\nvalidation_generator.reset()\n\n# Fit the model\nhistory = model.fit_generator(\n    train_generator, \n    validation_data = validation_generator,\n    epochs = 3,\n    steps_per_epoch = stepsPerEpoch,\n    validation_steps= validationSteps,\n    callbacks=callbacks_list,\n    verbose=1)","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:32:07.728224Z","iopub.execute_input":"2021-06-18T12:32:07.728584Z","iopub.status.idle":"2021-06-18T12:46:30.565937Z","shell.execute_reply.started":"2021-06-18T12:32:07.728549Z","shell.execute_reply":"2021-06-18T12:46:30.565095Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# list all data in history\nprint(history.history.keys())\n\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'Validation'], loc='upper left')\nplt.show()\n# summarize history for loss\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:58.618571Z","iopub.status.idle":"2021-06-18T12:31:58.618961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"timestr = time.strftime(\"%Y%m%d_%H%M%S\")\n\n# serialize model to JSON\nmodel_json = model.to_json()\nwith open(timestr+\"_\"+modelName+\"_MODEL_3\"+\".json\", \"w\") as json_file:\n    json_file.write(model_json)\n# serialize weights to HDF5\nmodel.save_weights(timestr+\"_\"+modelName+\"_3_LAST_WEIGHTS_\"+\".h5\")","metadata":{"execution":{"iopub.status.busy":"2021-06-18T12:31:58.620052Z","iopub.status.idle":"2021-06-18T12:31:58.620602Z"},"trusted":true},"execution_count":null,"outputs":[]}]}