{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":30587,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"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\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 read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-13T20:11:28.048881Z","iopub.execute_input":"2023-12-13T20:11:28.049303Z","iopub.status.idle":"2023-12-13T20:11:34.988452Z","shell.execute_reply.started":"2023-12-13T20:11:28.049272Z","shell.execute_reply":"2023-12-13T20:11:34.986915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Basic Libs..\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport pandas as pd\nimport numpy as np\nfrom tqdm import tqdm,tqdm_notebook\nfrom prettytable import PrettyTable\nimport pickle\nimport os\nprint('CWD is',os.getcwd())\n\n# Vis Libs..\nfrom sklearn.manifold import TSNE\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n%matplotlib inline\nplt.rcParams[\"axes.grid\"] = False\n\n# Image Libs.\nfrom PIL import Image\nimport cv2\n\n# DL Libs..\nimport keras\nfrom keras import applications\nfrom keras.preprocessing import image\nfrom keras import optimizers,Model,Sequential\nfrom keras.layers import Input,GlobalAveragePooling2D,Dropout,Dense,Activation\nfrom keras.callbacks import EarlyStopping,ReduceLROnPlateau","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:11:34.991205Z","iopub.execute_input":"2023-12-13T20:11:34.992778Z","iopub.status.idle":"2023-12-13T20:11:50.443940Z","shell.execute_reply.started":"2023-12-13T20:11:34.992720Z","shell.execute_reply":"2023-12-13T20:11:50.442751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\nThis function reads data from the respective train and test directories\n'''\n\ndef load_data():\n    train = pd.read_csv(\"../input/aptos2019-blindness-detection/train.csv\")\n    test = pd.read_csv(\"../input/aptos2019-blindness-detection/test.csv\")\n    \n    train_dir = os.path.join(\"../input/aptos2019-blindness-detection/train_images\")\n    test_dir = os.path.join(\"../input/aptos2019-blindness-detection/test_images\")\n    \n    train['file_path'] = train['id_code'].map(lambda x: os.path.join(train_dir,'{}.png'.format(x)))\n    test['file_path'] = test['id_code'].map(lambda x: os.path.join(test_dir,'{}.png'.format(x)))\n    \n    train['file_name'] = train[\"id_code\"].apply(lambda x: x + \".png\")\n    test['file_name'] = test[\"id_code\"].apply(lambda x: x + \".png\")\n    \n    train['diagnosis'] = train['diagnosis'].astype(str)\n    \n    return train,test","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:11:50.445750Z","iopub.execute_input":"2023-12-13T20:11:50.446405Z","iopub.status.idle":"2023-12-13T20:11:50.457934Z","shell.execute_reply.started":"2023-12-13T20:11:50.446372Z","shell.execute_reply":"2023-12-13T20:11:50.455996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train,df_test = load_data()\nprint(df_train.shape,df_test.shape,'\\n')\ndf_train.head(6)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:11:50.461290Z","iopub.execute_input":"2023-12-13T20:11:50.461713Z","iopub.status.idle":"2023-12-13T20:11:50.547929Z","shell.execute_reply.started":"2023-12-13T20:11:50.461666Z","shell.execute_reply":"2023-12-13T20:11:50.546598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"''''This Function Plots a Bar plot of output Classes Distribution'''\n\ndef plot_classes(df):\n    df_group = pd.DataFrame(df.groupby('diagnosis').agg('size').reset_index())\n    df_group.columns = ['diagnosis','count']\n\n    sns.set(rc={'figure.figsize':(10,5)}, style = 'whitegrid')\n    sns.barplot(x = 'diagnosis',y='count',data = df_group,palette = \"Blues_d\")\n    plt.title('Output Class Distribution')\n    plt.show() ","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:11:50.549830Z","iopub.execute_input":"2023-12-13T20:11:50.550222Z","iopub.status.idle":"2023-12-13T20:11:50.558714Z","shell.execute_reply.started":"2023-12-13T20:11:50.550190Z","shell.execute_reply":"2023-12-13T20:11:50.557558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_classes(df_train)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:11:50.560428Z","iopub.execute_input":"2023-12-13T20:11:50.560832Z","iopub.status.idle":"2023-12-13T20:11:50.958977Z","shell.execute_reply.started":"2023-12-13T20:11:50.560763Z","shell.execute_reply":"2023-12-13T20:11:50.957880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Defining a global variable to be used as Image size..\nIMG_SIZE = 200\n\n'''This Function converts a color image to gray scale image'''\n\ndef conv_gray(img):\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n    img = cv2.resize(img, (IMG_SIZE,IMG_SIZE))\n    return img\n  \n    \n'''\nThis Function shows the visual Image photo of 'n x 5' points (5 of each class)\n'''\n\ndef visualize_imgs(df,pts_per_class,color_scale):\n    df = df.groupby('diagnosis',group_keys = False).apply(lambda df: df.sample(pts_per_class))\n    df = df.reset_index(drop = True)\n    \n    plt.rcParams[\"axes.grid\"] = False\n    for pt in range(pts_per_class):\n        f, axarr = plt.subplots(1,5,figsize = (15,15))\n        axarr[0].set_ylabel(\"Sample Data Points\")\n        \n        df_temp = df[df.index.isin([pt + (pts_per_class*0),pt + (pts_per_class*1), pt + (pts_per_class*2),pt + (pts_per_class*3),pt + (pts_per_class*4)])]\n        for i in range(5):\n            if color_scale == 'gray':\n                img = conv_gray(cv2.imread(df_temp.file_path.iloc[i]))\n                axarr[i].imshow(img,cmap = color_scale)\n            else:\n                axarr[i].imshow(Image.open(df_temp.file_path.iloc[i]).resize((IMG_SIZE,IMG_SIZE)))\n            axarr[i].set_xlabel('Class '+str(df_temp.diagnosis.iloc[i]))\n\n        plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:11:50.960373Z","iopub.execute_input":"2023-12-13T20:11:50.960732Z","iopub.status.idle":"2023-12-13T20:11:50.973113Z","shell.execute_reply.started":"2023-12-13T20:11:50.960701Z","shell.execute_reply":"2023-12-13T20:11:50.972180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize_imgs(df_train,3,color_scale = None)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:11:50.974729Z","iopub.execute_input":"2023-12-13T20:11:50.975418Z","iopub.status.idle":"2023-12-13T20:11:58.492265Z","shell.execute_reply.started":"2023-12-13T20:11:50.975385Z","shell.execute_reply":"2023-12-13T20:11:58.490700Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize_imgs(df_train,2,color_scale = 'gray')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:11:58.493852Z","iopub.execute_input":"2023-12-13T20:11:58.494178Z","iopub.status.idle":"2023-12-13T20:12:02.076395Z","shell.execute_reply.started":"2023-12-13T20:11:58.494149Z","shell.execute_reply":"2023-12-13T20:12:02.075142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\nThis section of code applies gaussian blur on top of image\n'''\n\nrn = np.random.randint(low = 0,high = len(df_train) - 1)\n\nimg = cv2.imread(df_train.file_path.iloc[rn])\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\nimg = cv2.resize(img, (IMG_SIZE,IMG_SIZE))\n\nimg_t = cv2.addWeighted(img,4, cv2.GaussianBlur(img , (0,0) , 30) ,-4 ,128)\n\nf, axarr = plt.subplots(1,2,figsize = (11,11))\naxarr[0].imshow(img)\naxarr[1].imshow(img_t)\nplt.title('After applying Gaussian Blur')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:12:02.081145Z","iopub.execute_input":"2023-12-13T20:12:02.081580Z","iopub.status.idle":"2023-12-13T20:12:03.483813Z","shell.execute_reply.started":"2023-12-13T20:12:02.081507Z","shell.execute_reply":"2023-12-13T20:12:03.482969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\nThis Function performs image processing on top of images by performing Gaussian Blur and Circle Crop\n'''\n\ndef crop_image_from_gray(img,tol=7):\n    if img.ndim ==2:\n        mask = img>tol\n        return img[np.ix_(mask.any(1),mask.any(0))]\n    elif img.ndim==3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img>tol\n        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # image is too dark so that we crop out everything,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]\n            img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]\n            img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]\n    #         print(img1.shape,img2.shape,img3.shape)\n            img = np.stack([img1,img2,img3],axis=-1)\n    #         print(img.shape)\n        return img\n    \n    \ndef circle_crop(img, sigmaX):   \n    \"\"\"\n    Create circular crop around image centre    \n    \"\"\"    \n    img = crop_image_from_gray(img)    \n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    height, width, depth = img.shape    \n    \n    x = int(width/2)\n    y = int(height/2)\n    r = np.amin((x,y))\n    \n    circle_img = np.zeros((height, width), np.uint8)\n    cv2.circle(circle_img, (x,y), int(r), 1, thickness=-1)\n    img = cv2.bitwise_and(img, img, mask=circle_img)\n    img = crop_image_from_gray(img)\n    img=cv2.addWeighted(img,4, cv2.GaussianBlur( img , (0,0) , sigmaX) ,-4 ,128)\n    return img ","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:12:03.485211Z","iopub.execute_input":"2023-12-13T20:12:03.486395Z","iopub.status.idle":"2023-12-13T20:12:03.502351Z","shell.execute_reply.started":"2023-12-13T20:12:03.486356Z","shell.execute_reply":"2023-12-13T20:12:03.500593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''Perform Image Processing on a sample image'''\n\nrn = np.random.randint(low = 0,high = len(df_train) - 1)\n\n#img = img_t\nimg = cv2.imread(df_train.file_path.iloc[rn])\nimg_t = circle_crop(img,sigmaX = 30)\n\nf, axarr = plt.subplots(1,2,figsize = (11,11))\naxarr[0].imshow(cv2.resize(cv2.cvtColor(img, cv2.COLOR_BGR2RGB),(IMG_SIZE,IMG_SIZE)))\naxarr[1].imshow(img_t)\nplt.title('After applying Circular Crop and Gaussian Blur')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:12:03.504202Z","iopub.execute_input":"2023-12-13T20:12:03.504702Z","iopub.status.idle":"2023-12-13T20:12:05.616512Z","shell.execute_reply.started":"2023-12-13T20:12:03.504655Z","shell.execute_reply":"2023-12-13T20:12:05.615256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ref - https://www.kaggle.com/ratthachat/aptos-eye-preprocessing-in-diabetic-retinopathy\n'''\nThis Function shows the visual Image photo of 'n x 5' points (5 of each class) \nand performs image processing (Gaussian Blur, Circular crop) transformation on top of that\n'''\n\ndef visualize_img_process(df,pts_per_class,sigmaX):\n    df = df.groupby('diagnosis',group_keys = False).apply(lambda df: df.sample(pts_per_class))\n    df = df.reset_index(drop = True)\n    \n    plt.rcParams[\"axes.grid\"] = False\n    for pt in range(pts_per_class):\n        f, axarr = plt.subplots(1,5,figsize = (15,15))\n        axarr[0].set_ylabel(\"Sample Data Points\")\n        \n        df_temp = df[df.index.isin([pt + (pts_per_class*0),pt + (pts_per_class*1), pt + (pts_per_class*2),pt + (pts_per_class*3),pt + (pts_per_class*4)])]\n        for i in range(5):\n            img = cv2.imread(df_temp.file_path.iloc[i])\n            img = circle_crop(img,sigmaX)\n            axarr[i].imshow(img)\n            axarr[i].set_xlabel('Class '+str(df_temp.diagnosis.iloc[i]))\n\n        plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:12:05.618125Z","iopub.execute_input":"2023-12-13T20:12:05.619279Z","iopub.status.idle":"2023-12-13T20:12:05.630565Z","shell.execute_reply.started":"2023-12-13T20:12:05.619221Z","shell.execute_reply":"2023-12-13T20:12:05.629050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize_img_process(df_train,5,sigmaX = 30)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:12:05.632066Z","iopub.execute_input":"2023-12-13T20:12:05.632435Z","iopub.status.idle":"2023-12-13T20:12:41.613458Z","shell.execute_reply.started":"2023-12-13T20:12:05.632404Z","shell.execute_reply":"2023-12-13T20:12:41.608780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train image data\nnpix = 224 # resize to npix x npix (for now)\nX_train = np.zeros((df_train.shape[0], npix, npix))\nfor i in tqdm_notebook(range(df_train.shape[0])):\n    # load an image\n    img = cv2.imread(df_train.file_path.iloc[i])\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) \n    X_train[i, :, :] = cv2.resize(img, (npix, npix)) \n    \nprint(\"X_train shape: \" + str(np.shape(X_train))) ","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:12:41.614988Z","iopub.execute_input":"2023-12-13T20:12:41.616245Z","iopub.status.idle":"2023-12-13T20:20:52.632637Z","shell.execute_reply.started":"2023-12-13T20:12:41.616189Z","shell.execute_reply":"2023-12-13T20:20:52.630913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# normalize\nX = X_train / 255\n\n# reshape\nX = X.reshape(X.shape[0], -1)\ntrainy = df_train['diagnosis']","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:20:52.635650Z","iopub.execute_input":"2023-12-13T20:20:52.636138Z","iopub.status.idle":"2023-12-13T20:20:53.780148Z","shell.execute_reply.started":"2023-12-13T20:20:52.636097Z","shell.execute_reply":"2023-12-13T20:20:53.778902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"per_vals = [2,5,10,15,20,30,40,50]\n\nfor per in tqdm_notebook(per_vals):\n    X_decomposed = TSNE(n_components=2,perplexity = per).fit_transform(X)\n    df_tsne = pd.DataFrame(data=X_decomposed, columns=['Dimension_x','Dimension_y'])\n    df_tsne['Score'] = trainy.values\n    \n    sns.FacetGrid(df_tsne, hue='Score', height=6).map(plt.scatter, 'Dimension_x', 'Dimension_y').add_legend()\n    plt.title('TSNE for perplexity = ' + str(per))\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:20:53.781909Z","iopub.execute_input":"2023-12-13T20:20:53.782340Z","iopub.status.idle":"2023-12-13T20:28:51.731324Z","shell.execute_reply.started":"2023-12-13T20:20:53.782297Z","shell.execute_reply":"2023-12-13T20:28:51.729639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:28:51.733753Z","iopub.execute_input":"2023-12-13T20:28:51.734157Z","iopub.status.idle":"2023-12-13T20:28:51.741775Z","shell.execute_reply.started":"2023-12-13T20:28:51.734124Z","shell.execute_reply":"2023-12-13T20:28:51.740374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ref - https://www.youtube.com/watch?v=hxLU32zhze0\n# ref - https://stackoverflow.com/questions/49643907/clipping-input-data-to-the-valid-range-for-imshow-with-rgb-data-0-1-for-floa\n# ref - https://keras.io/preprocessing/image/\n\n'''This Function generates 'lim' number of Image Augmentations from a random Image in the directory'''\n\ndef generate_augmentations(lim):\n    datagen = ImageDataGenerator(featurewise_center=True,\n                                 featurewise_std_normalization=True,\n                                 rotation_range=20,\n                                 #width_shift_range=0.2,\n                                 #height_shift_range=0.2,\n                                 horizontal_flip=True)\n    img = cv2.imread(df_train.file_path.iloc[np.random.randint(low = 0,high = len(df_train) - 1)])\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = cv2.resize(img, (IMG_SIZE,IMG_SIZE))\n    plt.imshow(img)\n    plt.title('ORIGINAL IMAGE')\n    plt.show()\n    \n    img_arr = img.reshape((1,) + img.shape)\n    \n    i = 0\n    for img_iterator in datagen.flow(x = img_arr,batch_size = 1):\n        i = i + 1\n        if i > lim:\n            break\n        plt.imshow((img_iterator.reshape(img_arr[0].shape)).astype(np.uint8))\n        plt.title('IMAGE AUGMENTATION ' + str(i))\n        plt.show() ","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:28:51.743591Z","iopub.execute_input":"2023-12-13T20:28:51.744017Z","iopub.status.idle":"2023-12-13T20:28:51.760804Z","shell.execute_reply.started":"2023-12-13T20:28:51.743982Z","shell.execute_reply":"2023-12-13T20:28:51.758645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generate_augmentations(4)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:28:51.762654Z","iopub.execute_input":"2023-12-13T20:28:51.763025Z","iopub.status.idle":"2023-12-13T20:28:54.782463Z","shell.execute_reply.started":"2023-12-13T20:28:51.762993Z","shell.execute_reply":"2023-12-13T20:28:54.780490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ref - https://stackoverflow.com/questions/14463277/how-to-disable-python-warnings\n\n# Basic Libs..\nimport multiprocessing\nfrom multiprocessing.pool import ThreadPool\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport pandas as pd\nimport numpy as np\nfrom tqdm import tqdm,tqdm_notebook\nfrom prettytable import PrettyTable\nimport pickle\nimport os\nprint('CWD is ',os.getcwd())\n\n# Vis Libs..\nfrom sklearn.manifold import TSNE\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n%matplotlib inline\nplt.rcParams[\"axes.grid\"] = False\n\n# Image Libs.\nfrom PIL import Image\nimport cv2\n\n# sklearn libs..\nfrom sklearn.model_selection import train_test_split\n\n# DL Libs..\nimport keras\nfrom keras import applications\nfrom keras.preprocessing.image import ImageDataGenerator,img_to_array,array_to_img,load_img\nfrom keras import optimizers,Model,Sequential\nfrom keras.layers import Input,GlobalAveragePooling2D,Dropout,Dense,Activation\nfrom keras.callbacks import EarlyStopping,ReduceLROnPlateau","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:28:54.783902Z","iopub.execute_input":"2023-12-13T20:28:54.784289Z","iopub.status.idle":"2023-12-13T20:28:54.804740Z","shell.execute_reply.started":"2023-12-13T20:28:54.784256Z","shell.execute_reply":"2023-12-13T20:28:54.802523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train,df_test = load_data()\nprint(df_train.shape,df_test.shape,'\\n')\ndf_train.head(6)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T20:28:54.807316Z","iopub.execute_input":"2023-12-13T20:28:54.809150Z","iopub.status.idle":"2023-12-13T20:28:54.907460Z","shell.execute_reply.started":"2023-12-13T20:28:54.809086Z","shell.execute_reply":"2023-12-13T20:28:54.904399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# Kemudian gunakan fungsi train_test_split untuk membagi dataset\ndf_train_train, df_train_valid = train_test_split(df_train, test_size=0.2)\nprint(df_train_train.shape, df_train_valid.shape)\ndf_train_train.head(6)\n\n","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:20:19.519553Z","iopub.execute_input":"2023-12-13T22:20:19.521050Z","iopub.status.idle":"2023-12-13T22:20:19.540056Z","shell.execute_reply.started":"2023-12-13T22:20:19.520993Z","shell.execute_reply":"2023-12-13T22:20:19.538753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport shutil\n\n# Definisikan path untuk direktori train dan validation\ntrain_images_dir = \"../input/aptos2019-blindness-detection/train_images\"  # Path direktori asal\ntrain_dir = './train_images_split'  # Ganti dengan path yang diinginkan\nvalid_dir = './valid_images_split'  # Ganti dengan path yang diinginkan\n\n# Membuat direktori baru untuk data train\nos.makedirs(train_dir, exist_ok=True)\n\n# Membuat direktori baru untuk data validation\nos.makedirs(valid_dir, exist_ok=True)\n\n# Copy data train dari train_images ke direktori train baru\nfor index, row in df_train_train.iterrows():\n    src = os.path.join(train_images_dir, row['file_name'])  # Path asal dari file gambar\n    dst = os.path.join(train_dir, row['file_name'])  # Path tujuan untuk file gambar\n    shutil.copy(src, dst)  # Lakukan peng-copy-an file dari path asal ke path tujuan\n\n# Copy data validation dari train_images ke direktori validation baru\nfor index, row in df_train_valid.iterrows():\n    src = os.path.join(train_images_dir, row['file_name'])  # Path asal dari file gambar\n    dst = os.path.join(valid_dir, row['file_name'])  # Path tujuan untuk file gambar\n    shutil.copy(src, dst)  # Lakukan peng-copy-an file dari path asal ke path tujuan","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:29:06.104656Z","iopub.execute_input":"2023-12-13T22:29:06.105250Z","iopub.status.idle":"2023-12-13T22:31:22.229739Z","shell.execute_reply.started":"2023-12-13T22:29:06.105204Z","shell.execute_reply":"2023-12-13T22:31:22.228158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''This Function Plots a Bar plot of output Classes Distribution'''\n\ndef plot_classes(df,title):\n    df_group = pd.DataFrame(df.groupby('diagnosis').agg('size').reset_index())\n    df_group.columns = ['diagnosis','count']\n\n    sns.set(rc={'figure.figsize':(10,5)}, style = 'whitegrid')\n    sns.barplot(x = 'diagnosis',y='count',data = df_group,palette = \"Blues_d\")\n    plt.title('Output Class Distribution ' + str(title))\n    plt.show() ","metadata":{"execution":{"iopub.status.busy":"2023-12-13T21:45:14.472702Z","iopub.execute_input":"2023-12-13T21:45:14.473952Z","iopub.status.idle":"2023-12-13T21:45:14.483356Z","shell.execute_reply.started":"2023-12-13T21:45:14.473876Z","shell.execute_reply":"2023-12-13T21:45:14.481148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_classes(df_train_train,\"TRAIN DATA\")","metadata":{"execution":{"iopub.status.busy":"2023-12-13T21:45:20.788508Z","iopub.execute_input":"2023-12-13T21:45:20.789028Z","iopub.status.idle":"2023-12-13T21:45:21.164336Z","shell.execute_reply.started":"2023-12-13T21:45:20.788992Z","shell.execute_reply":"2023-12-13T21:45:21.163143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_classes(df_train_valid,'VALIDATION DATA')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T21:45:24.813254Z","iopub.execute_input":"2023-12-13T21:45:24.813769Z","iopub.status.idle":"2023-12-13T21:45:25.192743Z","shell.execute_reply.started":"2023-12-13T21:45:24.813727Z","shell.execute_reply":"2023-12-13T21:45:25.191367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"file = open('df_train_train', 'wb')\npickle.dump(df_train_train, file)\nfile.close()\n\nfile = open('df_train_valid', 'wb')\npickle.dump(df_train_valid, file)\nfile.close()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T21:45:29.549955Z","iopub.execute_input":"2023-12-13T21:45:29.550445Z","iopub.status.idle":"2023-12-13T21:45:29.564922Z","shell.execute_reply.started":"2023-12-13T21:45:29.550409Z","shell.execute_reply":"2023-12-13T21:45:29.562813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df_train_train.shape,df_train_valid.shape)\n#print(len(os.listdir('./train_images_resized_preprocessed')),len(os.listdir('./test_images_resized_preprocessed')))\nprint(len(os.listdir('/kaggle/working/train_images_split')),len(os.listdir('/kaggle/working/valid_images_split')))","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:34:30.857974Z","iopub.execute_input":"2023-12-13T22:34:30.858556Z","iopub.status.idle":"2023-12-13T22:34:30.871415Z","shell.execute_reply.started":"2023-12-13T22:34:30.858503Z","shell.execute_reply":"2023-12-13T22:34:30.870190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE  = 512","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:41:49.092676Z","iopub.execute_input":"2023-12-13T22:41:49.093070Z","iopub.status.idle":"2023-12-13T22:41:49.098146Z","shell.execute_reply.started":"2023-12-13T22:41:49.093040Z","shell.execute_reply":"2023-12-13T22:41:49.096854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''Function loads an image from Folder , Resizes and saves in another directory '''\n\ndef image_resize_save(file):\n    input_filepath = os.path.join(\"../input/aptos2019-blindness-detection/train_images\",'{}.png'.format(file))\n    #output_filepath = os.path.join('./','valid_images_resized','{}.png'.format(file))\n    output_filepath = os.path.join(\"/kaggle/working/valid_images_split\",'{}.png'.format(file))\n    img = cv2.imread(input_filepath)\n    cv2.imwrite(output_filepath, cv2.resize(img, (IMG_SIZE,IMG_SIZE)))\nimage_resize_save(df_train.id_code.iloc[201])","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:52:45.493068Z","iopub.execute_input":"2023-12-13T22:52:45.493633Z","iopub.status.idle":"2023-12-13T22:52:45.581480Z","shell.execute_reply.started":"2023-12-13T22:52:45.493575Z","shell.execute_reply":"2023-12-13T22:52:45.580453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''This Function uses Multi processing for faster saving of images into folder'''\n\ndef multiprocess_image_downloader(process:int, imgs:list):\n    \"\"\"\n    Inputs:\n        process: (int) number of process to run\n        imgs:(list) list of images\n    \"\"\"\n    print(f'MESSAGE: Running {process} process')\n    results = ThreadPool(process).map(image_resize_save, imgs)\n    return results","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:52:51.230717Z","iopub.execute_input":"2023-12-13T22:52:51.231147Z","iopub.status.idle":"2023-12-13T22:52:51.238500Z","shell.execute_reply.started":"2023-12-13T22:52:51.231116Z","shell.execute_reply":"2023-12-13T22:52:51.236876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Use 6 cores\nmultiprocess_image_downloader(6, list(df_train_valid.id_code.values))","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:52:54.823107Z","iopub.execute_input":"2023-12-13T22:52:54.823622Z","iopub.status.idle":"2023-12-13T22:53:32.998445Z","shell.execute_reply.started":"2023-12-13T22:52:54.823580Z","shell.execute_reply":"2023-12-13T22:53:32.997151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def crop_image_from_gray(img,tol=7):\n    if img.ndim ==2:\n        mask = img>tol\n        return img[np.ix_(mask.any(1),mask.any(0))]\n    elif img.ndim==3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img>tol\n        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # image is too dark so that we crop out everything,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]\n            img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]\n            img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]\n    #         print(img1.shape,img2.shape,img3.shape)\n            img = np.stack([img1,img2,img3],axis=-1)\n    #         print(img.shape)\n        return img\n\ndef circle_crop(img, sigmaX = 30):   \n    \"\"\"\n    Create circular crop around image centre    \n    \"\"\"    \n    img = crop_image_from_gray(img)    \n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    height, width, depth = img.shape    \n    \n    x = int(width/2)\n    y = int(height/2)\n    r = np.amin((x,y))\n    \n    circle_img = np.zeros((height, width), np.uint8)\n    cv2.circle(circle_img, (x,y), int(r), 1, thickness=-1)\n    img = cv2.bitwise_and(img, img, mask=circle_img)\n    img = crop_image_from_gray(img)\n    img=cv2.addWeighted(img,4, cv2.GaussianBlur( img , (0,0) , sigmaX) ,-4 ,128)\n    return img \n\ndef preprocess_image(file):\n    input_filepath = os.path.join('/kaggle/input/aptos2019-blindness-detection/train_images','{}.png'.format(file))\n    output_filepath = os.path.join('/kaggle/working/valid_images_split','{}.png'.format(file))\n    \n    img = cv2.imread(input_filepath)\n    img = circle_crop(img) \n    cv2.imwrite(output_filepath, cv2.resize(img, (IMG_SIZE,IMG_SIZE)))","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:57:24.964885Z","iopub.execute_input":"2023-12-13T22:57:24.965415Z","iopub.status.idle":"2023-12-13T22:57:24.985238Z","shell.execute_reply.started":"2023-12-13T22:57:24.965380Z","shell.execute_reply":"2023-12-13T22:57:24.983995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''This Function uses Multi processing for faster saving of images into folder'''\n\ndef multiprocess_image_processor(process:int, imgs:list):\n    \"\"\"\n    Inputs:\n        process: (int) number of process to run\n        imgs:(list) list of images\n    \"\"\"\n    print(f'MESSAGE: Running {process} process')\n    results = ThreadPool(process).map(preprocess_image, imgs)\n    return results","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:58:10.865623Z","iopub.execute_input":"2023-12-13T22:58:10.866075Z","iopub.status.idle":"2023-12-13T22:58:10.872524Z","shell.execute_reply.started":"2023-12-13T22:58:10.866042Z","shell.execute_reply":"2023-12-13T22:58:10.871608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Use 6 cores\nmultiprocess_image_processor(6, list(df_train_valid.id_code.values))","metadata":{"execution":{"iopub.status.busy":"2023-12-13T22:58:14.893868Z","iopub.execute_input":"2023-12-13T22:58:14.894282Z","iopub.status.idle":"2023-12-13T23:04:56.973567Z","shell.execute_reply.started":"2023-12-13T22:58:14.894251Z","shell.execute_reply":"2023-12-13T23:04:56.971858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_data():\n    file = open('df_train_train', 'rb')\n    df_train_train = pickle.load(file)\n    file.close()\n\n    file = open('df_train_valid', 'rb')\n    df_train_test = pickle.load(file)\n    file.close()\n    \n    return df_train_train,df_train_valid","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:12:31.045000Z","iopub.execute_input":"2023-12-13T23:12:31.045592Z","iopub.status.idle":"2023-12-13T23:12:31.054609Z","shell.execute_reply.started":"2023-12-13T23:12:31.045548Z","shell.execute_reply":"2023-12-13T23:12:31.052671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_train,df_train_valid = load_data()\nprint(df_train_train.shape,df_train_valid.shape,'\\n')\ndf_train_train.head(6)\n","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:12:35.876456Z","iopub.execute_input":"2023-12-13T23:12:35.877031Z","iopub.status.idle":"2023-12-13T23:12:35.902623Z","shell.execute_reply.started":"2023-12-13T23:12:35.876989Z","shell.execute_reply":"2023-12-13T23:12:35.901095Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 512","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:12:58.911676Z","iopub.execute_input":"2023-12-13T23:12:58.912281Z","iopub.status.idle":"2023-12-13T23:12:58.919701Z","shell.execute_reply.started":"2023-12-13T23:12:58.912230Z","shell.execute_reply":"2023-12-13T23:12:58.918109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def crop_image_from_gray(img,tol=7):\n    if img.ndim ==2:\n        mask = img>tol\n        return img[np.ix_(mask.any(1),mask.any(0))]\n    elif img.ndim==3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img>tol\n        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # image is too dark so that we crop out everything,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]\n            img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]\n            img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]\n    #         print(img1.shape,img2.shape,img3.shape)\n            img = np.stack([img1,img2,img3],axis=-1)\n    #         print(img.shape)\n        return img\n\ndef circle_crop(img, sigmaX = 30):   \n    \"\"\"\n    Create circular crop around image centre    \n    \"\"\"    \n    img = crop_image_from_gray(img)    \n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    height, width, depth = img.shape    \n    \n    x = int(width/2)\n    y = int(height/2)\n    r = np.amin((x,y))\n    \n    circle_img = np.zeros((height, width), np.uint8)\n    cv2.circle(circle_img, (x,y), int(r), 1, thickness=-1)\n    img = cv2.bitwise_and(img, img, mask=circle_img)\n    img = crop_image_from_gray(img)\n    img=cv2.addWeighted(img,4, cv2.GaussianBlur( img , (0,0) , sigmaX) ,-4 ,128)\n    return img \n\ndef preprocess_image(file):\n    input_filepath = os.path.join('/kaggle/input/aptos2019-blindness-detection/train_images','{}.png'.format(file))\n    output_filepath = os.path.join('/kaggle/working/valid_images_split','{}.png'.format(file))\n    \n    img = cv2.imread(input_filepath)\n    img = circle_crop(img) \n    cv2.imwrite(output_filepath, cv2.resize(img, (IMG_SIZE,IMG_SIZE)))","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:15:34.454497Z","iopub.execute_input":"2023-12-13T23:15:34.455061Z","iopub.status.idle":"2023-12-13T23:15:34.474566Z","shell.execute_reply.started":"2023-12-13T23:15:34.455023Z","shell.execute_reply":"2023-12-13T23:15:34.473514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''This Function uses Multi processing for faster saving of images into folder'''\n\ndef multiprocess_image_processor(process:int, imgs:list):\n    \"\"\"\n    Inputs:\n        process: (int) number of process to run\n        imgs:(list) list of images\n    \"\"\"\n    print(f'MESSAGE: Running {process} process')\n    results = ThreadPool(process).map(preprocess_image, imgs)\n    return results","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:15:53.518078Z","iopub.execute_input":"2023-12-13T23:15:53.518620Z","iopub.status.idle":"2023-12-13T23:15:53.525942Z","shell.execute_reply.started":"2023-12-13T23:15:53.518579Z","shell.execute_reply":"2023-12-13T23:15:53.524590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Model parameters\nBATCH_SIZE = 8\nEPOCHS = 40\nWARMUP_EPOCHS = 2\nLEARNING_RATE = 1e-4\nWARMUP_LEARNING_RATE = 1e-3\nHEIGHT = 320\nWIDTH = 320\nCANAL = 3\nN_CLASSES = df_train_train['diagnosis'].nunique()\nES_PATIENCE = 5\nRLROP_PATIENCE = 3\nDECAY_DROP = 0.5","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:16:17.146396Z","iopub.execute_input":"2023-12-13T23:16:17.146882Z","iopub.status.idle":"2023-12-13T23:16:17.156773Z","shell.execute_reply.started":"2023-12-13T23:16:17.146845Z","shell.execute_reply":"2023-12-13T23:16:17.154974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def img_generator(train,test):\n    train_datagen=ImageDataGenerator(rescale=1./255, validation_split=0.2,horizontal_flip=True)\n    \n    train_generator=train_datagen.flow_from_dataframe(dataframe=df_train_train,\n                                                      directory=\"/kaggle/working/train_images_split\",\n                                                      x_col=\"file_name\",\n                                                      y_col=\"diagnosis\",\n                                                      batch_size=BATCH_SIZE,\n                                                      class_mode=\"categorical\",\n                                                      target_size=(HEIGHT, WIDTH))\n    \n    valid_generator=train_datagen.flow_from_dataframe(dataframe=df_train_valid,\n                                                      directory=\"/kaggle/working/valid_images_split\",\n                                                      x_col=\"file_name\",\n                                                      y_col=\"diagnosis\",\n                                                      batch_size=BATCH_SIZE,\n                                                      class_mode=\"categorical\",    \n                                                      target_size=(HEIGHT, WIDTH))\n    \n    test_datagen = ImageDataGenerator(rescale=1./255)\n    test_generator = test_datagen.flow_from_dataframe(dataframe=df_test,\n                                                      directory = \"/kaggle/input/aptos2019-blindness-detection/test_images\",\n                                                      x_col=\"file_name\",\n                                                      target_size=(HEIGHT, WIDTH),\n                                                      batch_size=1,\n                                                      shuffle=False,\n                                                      class_mode=None)\n    \n    return train_generator,valid_generator,test_generator","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:22:58.651884Z","iopub.execute_input":"2023-12-13T23:22:58.652461Z","iopub.status.idle":"2023-12-13T23:22:58.664049Z","shell.execute_reply.started":"2023-12-13T23:22:58.652418Z","shell.execute_reply":"2023-12-13T23:22:58.662612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator,valid_generator,test_generator = img_generator(df_train_train,df_train_valid)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:23:03.405592Z","iopub.execute_input":"2023-12-13T23:23:03.406397Z","iopub.status.idle":"2023-12-13T23:23:07.562685Z","shell.execute_reply.started":"2023-12-13T23:23:03.406341Z","shell.execute_reply":"2023-12-13T23:23:07.561659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\n\nbase_model = tf.keras.applications.ResNet50(weights='imagenet', include_top=False)\nbase_model.save_weights('resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:33:46.596289Z","iopub.execute_input":"2023-12-13T23:33:46.596831Z","iopub.status.idle":"2023-12-13T23:33:50.709314Z","shell.execute_reply.started":"2023-12-13T23:33:46.596795Z","shell.execute_reply":"2023-12-13T23:33:50.707746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_model(input_shape, n_out):\n    input_tensor = Input(shape=input_shape)\n    base_model = applications.ResNet50(weights=None, include_top=False,input_tensor=input_tensor)\n    base_model.load_weights('resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')\n\n    x = GlobalAveragePooling2D()(base_model.output)\n    x = Dropout(0.5)(x)\n    x = Dense(2048, activation='relu')(x)\n    x = Dropout(0.5)(x)\n    final_output = Dense(n_out, activation='softmax', name='final_output')(x)\n    model = Model(input_tensor, final_output)\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:33:53.481313Z","iopub.execute_input":"2023-12-13T23:33:53.482040Z","iopub.status.idle":"2023-12-13T23:33:53.491693Z","shell.execute_reply.started":"2023-12-13T23:33:53.481997Z","shell.execute_reply":"2023-12-13T23:33:53.489811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model(input_shape=(HEIGHT, WIDTH, CANAL), n_out=N_CLASSES)\n\nfor layer in model.layers:\n    layer.trainable = False\n\nfor i in range(-5, 0):\n    model.layers[i].trainable = True\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:33:57.297790Z","iopub.execute_input":"2023-12-13T23:33:57.298293Z","iopub.status.idle":"2023-12-13T23:34:00.483875Z","shell.execute_reply.started":"2023-12-13T23:33:57.298252Z","shell.execute_reply":"2023-12-13T23:34:00.482633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEP_SIZE_TRAIN = train_generator.n//train_generator.batch_size\nSTEP_SIZE_VALID = valid_generator.n//valid_generator.batch_size\nprint(STEP_SIZE_TRAIN,STEP_SIZE_VALID)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:34:29.397356Z","iopub.execute_input":"2023-12-13T23:34:29.397927Z","iopub.status.idle":"2023-12-13T23:34:29.406923Z","shell.execute_reply.started":"2023-12-13T23:34:29.397881Z","shell.execute_reply":"2023-12-13T23:34:29.404899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer = optimizers.Adam(lr=WARMUP_LEARNING_RATE),loss = 'categorical_crossentropy',metrics = ['accuracy'])\n\nhistory_warmup = model.fit_generator(generator=train_generator,\n                                     steps_per_epoch=STEP_SIZE_TRAIN,\n                                     validation_data=valid_generator,validation_steps=STEP_SIZE_VALID,\n                                     epochs=WARMUP_EPOCHS,\n                                     verbose=1).history","metadata":{"execution":{"iopub.status.busy":"2023-12-13T23:34:44.452361Z","iopub.execute_input":"2023-12-13T23:34:44.452913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in model.layers:\n    layer.trainable = True\n\nes = EarlyStopping(monitor='val_loss', mode='min', patience=ES_PATIENCE, restore_best_weights=True, verbose=1)\nrlrop = ReduceLROnPlateau(monitor='val_loss', mode='min', patience=RLROP_PATIENCE, factor=DECAY_DROP, min_lr=1e-6, verbose=1)\n\ncallback_list = [es, rlrop]\noptimizer = optimizers.Adam(lr=LEARNING_RATE)\nmodel.compile(optimizer=optimizer, loss=\"binary_crossentropy\",  metrics=['accuracy'])\nmodel.summary()","metadata":{},"execution_count":null,"outputs":[]}]}