{"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":"\n#import all required library\nimport os\nimport cv2\nimport numpy as np\nimport random as rn\nimport pandas as pd\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import all tensorflow and keras library \n\nimport tensorflow as tf\nimport keras\nfrom keras import initializers\nfrom keras import regularizers\nfrom keras import constraints\nfrom keras import backend as K\nfrom keras.activations import elu\nfrom keras.optimizers import Adam\nfrom keras.models import Sequential\nfrom keras.engine import Layer, InputSpec\nfrom keras.utils.generic_utils import get_custom_objects\nfrom keras.callbacks import Callback, EarlyStopping, ReduceLROnPlateau\nfrom keras.layers import Dense, Conv2D, Flatten, GlobalAveragePooling2D, Dropout,MaxPooling2D,BatchNormalization,GlobalMaxPooling2D","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set seed for reproducability\nseed=1234\nrn.seed(seed)\nnp.random.seed(seed)\ntf.random.set_seed(seed)\nos.environ[\"PYTHONHASHSEED\"]=str(seed)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model=tf.keras.applications.MobileNetV2(input_shape=(256,256,3),include_top=False,weights=\"imagenet\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set all layer trainable\nfor layer in base_model.layers:\n    layer.trainable=True","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Build Model according to your output\ndef build_model():\n    model=Sequential()\n    model.add(base_model) \n    model.add(GlobalAveragePooling2D())\n    model.add(Dropout(0.3))  # change dropout get better result\n    model.add(Dense(1,activation=\"sigmoid\")) # output is 0 or 1 binary \n    \n    # now compile model\n    # we are using adam you can use other to optimize better\n    optimizer=keras.optimizers.Adam(learning_rate=0.00005,beta_1=0.9,beta_2=0.999,amsgrad=False)\n    # This is important part of model \n    # Number of positive image is less than number of negative image\n    # we use AUC metrics\n    metrics=tf.keras.metrics.AUC(name=\"auc\")\n    model.compile(loss=\"binary_crossentropy\",optimizer=optimizer,metrics=metrics)\n    print(model.summary())\n    return model\n\nmodel=build_model()\n    \n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df=pd.read_csv(\"../input/jpeg-melanoma-256x256/train.csv\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df # we will use only image_name and target","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\na,b=np.unique(df[\"target\"],return_counts=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"b # 32542 negative image and only 584 positive image\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# split train dataframe into training and validation","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain,valid=train_test_split(df,test_size=0.2)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ntrain,test=train_test_split(train,test_size=0.01)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train[\"image_name_jpg\"]=train[\"image_name\"]+\".jpg\"\ntest[\"image_name_jpg\"]=test[\"image_name\"]+\".jpg\"\nvalid[\"image_name_jpg\"]=valid[\"image_name\"]+\".jpg\"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# now convert target in string\ntrain[\"target\"]=train[\"target\"].astype(str)\ntest[\"target\"]=test[\"target\"].astype(str)\nvalid[\"target\"]=valid[\"target\"].astype(str)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# now create train_generator and validation_generator\n# you can add other augmentation example vertical_flip, random cropping ,etc to get bettter accuracy\ntrain_datagen=tf.keras.preprocessing.image.ImageDataGenerator(\n    rescale=1/255,\n    horizontal_flip=True\n    )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_datagen=tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255) # we have to divide by 255 for testing in android app","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator =train_datagen.flow_from_dataframe(\n    dataframe=train,\n    directory=\"../input/jpeg-melanoma-256x256/train/\",\n    x_col=\"image_name_jpg\", # name +\".jpg\"\n    y_col=\"target\",\n    target_size=(256,256),\n    batch_size=32,\n    class_mode=\"binary\"\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"validation_generator =test_datagen.flow_from_dataframe(\n    dataframe=valid,\n    directory=\"../input/jpeg-melanoma-256x256/train/\",\n    x_col=\"image_name_jpg\",\n    y_col=\"target\",\n    target_size=(256,256),\n    batch_size=16,\n    class_mode=\"binary\"\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train model\nmodel.fit_generator(\n    train_generator,\n    epochs=3, #you have set or use early stopping to stop before overfiting\n    shuffle=True,\n    validation_data=validation_generator\n    # can also define callback to save model when gets best accuracy\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# This is most basic version of training with decent accuracy ","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# After 3 epoch it start to overfit \n#When the training is done save model in tflite formate which is much faster but accuracy decreases\nconverter=tf.lite.TFLiteConverter.from_keras_model(model)\ntflite_model=converter.convert()\n# save model\nwith open (\"model.tflite\",\"wb\") as f:\n    f.write(tflite_model)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}