{"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":"gpu","dataSources":[{"sourceId":18647,"databundleVersionId":1126921,"sourceType":"competition"}],"dockerImageVersionId":30559,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nfrom tqdm.notebook import tqdm\nimport zipfile","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:49.239771Z","iopub.execute_input":"2024-06-08T14:25:49.240118Z","iopub.status.idle":"2024-06-08T14:25:49.337453Z","shell.execute_reply.started":"2024-06-08T14:25:49.240087Z","shell.execute_reply":"2024-06-08T14:25:49.336485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import time\nimport skimage.io\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport PIL.Image\nfrom sklearn.model_selection import StratifiedKFold\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import cohen_kappa_score\nfrom tqdm import tqdm_notebook as tqdm","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:49.62059Z","iopub.execute_input":"2024-06-08T14:25:49.621491Z","iopub.status.idle":"2024-06-08T14:25:51.051218Z","shell.execute_reply.started":"2024-06-08T14:25:49.621446Z","shell.execute_reply":"2024-06-08T14:25:51.050134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir = '../input/prostate-cancer-grade-assessment'\ndf_train = pd.read_csv(os.path.join(data_dir, 'train.csv'))\n","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:51.053362Z","iopub.execute_input":"2024-06-08T14:25:51.053952Z","iopub.status.idle":"2024-06-08T14:25:51.095127Z","shell.execute_reply.started":"2024-06-08T14:25:51.053916Z","shell.execute_reply":"2024-06-08T14:25:51.094281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def sample_equal_instances(df, target_column, sample_size):\n    sampled_df = df.groupby(target_column).apply(lambda x: x.sample(sample_size, replace=True)).reset_index(drop=True)\n    return sampled_df","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:51.096291Z","iopub.execute_input":"2024-06-08T14:25:51.096734Z","iopub.status.idle":"2024-06-08T14:25:51.102346Z","shell.execute_reply.started":"2024-06-08T14:25:51.0967Z","shell.execute_reply":"2024-06-08T14:25:51.101464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gleason_6 = df_train[df_train['isup_grade'].isin([0, 1, 2, 3, 4, 5])]\n\n# Select 100 rows from the filtered DataFrame\nselected_data = gleason_6.head(80)","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:51.250652Z","iopub.execute_input":"2024-06-08T14:25:51.250977Z","iopub.status.idle":"2024-06-08T14:25:51.263862Z","shell.execute_reply.started":"2024-06-08T14:25:51.250953Z","shell.execute_reply":"2024-06-08T14:25:51.262469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Total samples: {selected_data.shape[0]}')","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:51.629231Z","iopub.execute_input":"2024-06-08T14:25:51.63007Z","iopub.status.idle":"2024-06-08T14:25:51.634474Z","shell.execute_reply.started":"2024-06-08T14:25:51.630037Z","shell.execute_reply":"2024-06-08T14:25:51.6337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Image ids in NAME variable with their respective classes in CLASS variable\nNAME= selected_data['image_id'].tolist()\nCLASS=selected_data['isup_grade'].tolist()\nNAME","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:51.898743Z","iopub.execute_input":"2024-06-08T14:25:51.899392Z","iopub.status.idle":"2024-06-08T14:25:51.908188Z","shell.execute_reply.started":"2024-06-08T14:25:51.899346Z","shell.execute_reply":"2024-06-08T14:25:51.907278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df=[]\ncount=0\nfor i in NAME:\n df.append(df_train[df_train['image_id']==i])\n count+=1\ndf_train=pd.DataFrame(np.array(df).reshape(80,4),columns=['image_id','data_provider','isup_grade','gleason_score'])\ndf_train","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:52.226482Z","iopub.execute_input":"2024-06-08T14:25:52.226871Z","iopub.status.idle":"2024-06-08T14:25:52.425402Z","shell.execute_reply.started":"2024-06-08T14:25:52.226842Z","shell.execute_reply":"2024-06-08T14:25:52.424429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN = '../input/prostate-cancer-grade-assessment/train_images/'\nMASKS = '../input/prostate-cancer-grade-assessment/train_label_masks/'\nOUT_TRAIN = 'train.zip'\nOUT_MASKS = 'masks.zip'\nsz = 256 # Size of each tile\nN = 36 # Total no of tiles","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:52.930249Z","iopub.execute_input":"2024-06-08T14:25:52.930605Z","iopub.status.idle":"2024-06-08T14:25:52.935484Z","shell.execute_reply.started":"2024-06-08T14:25:52.930574Z","shell.execute_reply":"2024-06-08T14:25:52.934571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def tile(img, mask, sz=256, N=16, cutoff_threshold=0.9):\n    result = []\n    shape = img.shape\n    pad0, pad1 = (sz - shape[0] % sz) % sz, (sz - shape[1] % sz) % sz\n    img = np.pad(img, [[pad0 // 2, pad0 - pad0 // 2], [pad1 // 2, pad1 - pad1 // 2], [0, 0]],\n                 constant_values=255)\n    mask = np.pad(mask, [[pad0 // 2, pad0 - pad0 // 2], [pad1 // 2, pad1 - pad1 // 2], [0, 0]],\n                  constant_values=0)\n    img = img.reshape(img.shape[0] // sz, sz, img.shape[1] // sz, sz, 3)\n    img = img.transpose(0, 2, 1, 3, 4).reshape(-1, sz, sz, 3)\n    mask = mask.reshape(mask.shape[0] // sz, sz, mask.shape[1] // sz, sz, 3)\n    mask = mask.transpose(0, 2, 1, 3, 4).reshape(-1, sz, sz, 3)\n\n    # Filter tiles using tile_cutoff\n    valid_tiles = tile_cutoff(img, cutoff_threshold)\n    img = img[valid_tiles]\n    mask = mask[valid_tiles]\n\n    if len(img) < N:\n        mask = np.pad(mask, [[0, N - len(img)], [0, 0], [0, 0], [0, 0]], constant_values=0)\n        img = np.pad(img, [[0, N - len(img)], [0, 0], [0, 0], [0, 0]], constant_values=255)\n    idxs = np.argsort(img.reshape(img.shape[0], -1).sum(-1))[:N]\n    img = img[idxs]\n    mask = mask[idxs]\n    for i in range(len(img)):\n        augmented_img, augmented_mask = augment_tile(img[i], mask[i])\n        result.append({'img': augmented_img, 'mask': augmented_mask, 'idx': i})\n    return result\n\ndef tile_cutoff(img_tiles, threshold):\n    \"\"\"Filter out tiles that are predominantly white or gray.\"\"\"\n    valid_tiles = []\n    for i, tile in enumerate(img_tiles):\n        if np.mean(tile) / 255.0 < threshold:\n            valid_tiles.append(i)\n    return np.array(valid_tiles)\n\ndef augment_tile(img, mask):\n    \"\"\"Apply augmentations to a tile.\"\"\"\n    # Random horizontal flip\n    if np.random.rand() > 0.5:\n        img = np.fliplr(img)\n        mask = np.fliplr(mask)\n    # Random vertical flip\n    if np.random.rand() > 0.5:\n        img = np.flipud(img)\n        mask = np.flipud(mask)\n    # Random rotation\n    if np.random.rand() > 0.5:\n        k = np.random.randint(0, 4)\n        img = np.rot90(img, k)\n        mask = np.rot90(mask, k)\n    # Additional augmentations can be added here\n    return img, mask\n","metadata":{"execution":{"iopub.status.busy":"2024-06-08T13:42:20.886312Z","iopub.execute_input":"2024-06-08T13:42:20.886597Z","iopub.status.idle":"2024-06-08T13:42:20.903558Z","shell.execute_reply.started":"2024-06-08T13:42:20.886571Z","shell.execute_reply":"2024-06-08T13:42:20.902694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_tot,x2_tot = [],[]\nnames = [name[:-10] for name in os.listdir(MASKS)]\nwith zipfile.ZipFile(OUT_TRAIN, 'w') as img_out,\\\n zipfile.ZipFile(OUT_MASKS, 'w') as mask_out:\n    for name in tqdm(NAME):\n        img = skimage.io.MultiImage(os.path.join(TRAIN,name+'.tiff'))[-1]\n        mask = skimage.io.MultiImage(os.path.join(MASKS,name+'_mask.tiff'))[-1]\n        tiles = tile(img,mask)\n        for t in tiles:\n            img,mask,idx = t['img'],t['mask'],t['idx']\n            x_tot.append((img/255.0).reshape(-1,3).mean(0))\n            x2_tot.append(((img/255.0)**2).reshape(-1,3).mean(0)) \n            #if read with PIL RGB turns into BGR\n            img = cv2.imencode('.png',cv2.cvtColor(img, cv2.COLOR_RGB2BGR))[1]\n            img_out.writestr(f'{name}_{idx}.png', img)\n            mask = cv2.imencode('.png',mask[:,:,0])[1]\n            mask_out.writestr(f'{name}_{idx}.png', mask)","metadata":{"execution":{"iopub.status.busy":"2024-06-08T13:18:44.385289Z","iopub.execute_input":"2024-06-08T13:18:44.386217Z","iopub.status.idle":"2024-06-08T13:18:52.418448Z","shell.execute_reply.started":"2024-06-08T13:18:44.38618Z","shell.execute_reply":"2024-06-08T13:18:52.417173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!unzip -o /kaggle/working/train.zip","metadata":{"execution":{"iopub.status.busy":"2024-05-26T13:54:24.018446Z","iopub.execute_input":"2024-05-26T13:54:24.018935Z","iopub.status.idle":"2024-05-26T13:54:26.467715Z","shell.execute_reply.started":"2024-05-26T13:54:24.018893Z","shell.execute_reply":"2024-05-26T13:54:26.466448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# loading all the tile images into img_train array with 12 rows\nimport cv2\nout_dir='/kaggle/working/'\nimg_train=np.empty((80,4*256,4*256,3))\ncount=-1\nfor i in NAME:\n    img_var=[]\n    count+=1\n    for j in range(0,16): \n        img_var.append(cv2.imread(out_dir+str(i)+'_'+str(j)+'.png'))\n    img_var=np.array(img_var)\n    img_var=img_var.reshape(4*256,4*256,3)\n    img_train[count]=img_var\n\n","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:25:57.514561Z","iopub.execute_input":"2024-06-08T14:25:57.514895Z","iopub.status.idle":"2024-06-08T14:26:00.345529Z","shell.execute_reply.started":"2024-06-08T14:25:57.514869Z","shell.execute_reply":"2024-06-08T14:26:00.344654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_train=img_train.reshape(80,-1) # for smote function to work, it requires only 2 dimensional array","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:26:00.347271Z","iopub.execute_input":"2024-06-08T14:26:00.347587Z","iopub.status.idle":"2024-06-08T14:26:00.351993Z","shell.execute_reply.started":"2024-06-08T14:26:00.34756Z","shell.execute_reply":"2024-06-08T14:26:00.351068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 12 to 24 images using smote analysis\nfrom collections import Counter\nfrom imblearn.over_sampling import SMOTE\ncounter = Counter(CLASS)\nprint('Before',counter)\n# oversampling the train dataset using SMOTE\nsmt = SMOTE(sampling_strategy={0:30,1:30,2:30,3:30,4:30,5:30},k_neighbors=3)\n#X_train, y_train = smt.fit_resample(X_train, y_train)\nX_train_sm, y_train_sm = smt.fit_resample(img_train, CLASS)\n\ncounter = Counter(y_train_sm)\nprint('After',counter)","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:26:00.353155Z","iopub.execute_input":"2024-06-08T14:26:00.353422Z","iopub.status.idle":"2024-06-08T14:26:10.793634Z","shell.execute_reply.started":"2024-06-08T14:26:00.353397Z","shell.execute_reply":"2024-06-08T14:26:10.792638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X_train_sm.shape)\nprint(X_train_sm.size)\n","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:26:10.795613Z","iopub.execute_input":"2024-06-08T14:26:10.796034Z","iopub.status.idle":"2024-06-08T14:26:10.800927Z","shell.execute_reply.started":"2024-06-08T14:26:10.796007Z","shell.execute_reply":"2024-06-08T14:26:10.799909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\n\n# Define the desired dimensions for each image\nnew_width = 256\nnew_height = 256\n\n# List to store resized images\nresized_images = []\n\n# Loop through each image in X_train_sm and resize\nfor img_data in X_train_sm:\n    # Reshape the 1D array back into image dimensions\n    img = img_data.reshape(4*256, 4*256, 3)\n    \n    # Convert numpy array to PIL Image\n    pil_img = Image.fromarray(img.astype('uint8'))\n    \n    # Resize the image\n    resized_img = pil_img.resize((new_width, new_height))\n    \n    # Convert back to numpy array\n    resized_img_data = np.array(resized_img)\n    \n    # Append resized image to the list\n    resized_images.append(resized_img_data)\n\n# Convert the list of resized images back to numpy array\nX_train_resized = np.array(resized_images)\n\n# Check the shape of the resized array\nprint(X_train_resized.shape)\n","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:26:10.802084Z","iopub.execute_input":"2024-06-08T14:26:10.802615Z","iopub.status.idle":"2024-06-08T14:26:13.618019Z","shell.execute_reply.started":"2024-06-08T14:26:10.802578Z","shell.execute_reply":"2024-06-08T14:26:13.617022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Y_train=pd.get_dummies(y_train_sm).values # onehotencoding","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:26:13.619226Z","iopub.execute_input":"2024-06-08T14:26:13.619543Z","iopub.status.idle":"2024-06-08T14:26:13.628643Z","shell.execute_reply.started":"2024-06-08T14:26:13.619502Z","shell.execute_reply":"2024-06-08T14:26:13.627727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install git+https://github.com/qubvel/classification_models.git","metadata":{"execution":{"iopub.status.busy":"2024-05-26T13:55:16.983231Z","iopub.execute_input":"2024-05-26T13:55:16.983641Z","iopub.status.idle":"2024-05-26T13:55:33.591664Z","shell.execute_reply.started":"2024-05-26T13:55:16.983603Z","shell.execute_reply":"2024-05-26T13:55:33.590631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom classification_models.tfkeras import Classifiers\n\n# Get the model and preprocessing function\nResNeXt50, preprocess_input = Classifiers.get('resnext50')\n\n# Create the model with desired input shape and weights (optional)\nres_model = ResNeXt50(\n    include_top=False,  # Set to True for classification (optional)\n    input_shape=(256, 256, 3),\n    weights='imagenet'  # Load pre-trained weights (optional)\n)","metadata":{"execution":{"iopub.status.busy":"2024-05-26T13:55:33.593173Z","iopub.execute_input":"2024-05-26T13:55:33.593496Z","iopub.status.idle":"2024-05-26T13:55:51.920053Z","shell.execute_reply.started":"2024-05-26T13:55:33.593468Z","shell.execute_reply":"2024-05-26T13:55:51.91908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Defining the model\nimport tensorflow.keras as K\nfrom tensorflow.keras.layers import Input\n\n# Define the input shape based on the resized image dimensions\ninput_t = Input(shape=(256, 256, 3))\n\n# Load ResNet50 model with the updated input shape\n# res_model = K.applications.ResNeXt50(include_top=False, weights=\"imagenet\", input_tensor=input_t)\n\n# Build the rest of the model\nmodel = K.models.Sequential()\nmodel.add(res_model)\nmodel.add(K.layers.Flatten())\nmodel.add(K.layers.Dense(6, activation='softmax'))\nmodel.compile(loss='categorical_crossentropy',optimizer=K.optimizers.RMSprop(lr=0.01),metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-05-26T13:55:51.921337Z","iopub.execute_input":"2024-05-26T13:55:51.92163Z","iopub.status.idle":"2024-05-26T13:55:54.673852Z","shell.execute_reply.started":"2024-05-26T13:55:51.921604Z","shell.execute_reply":"2024-05-26T13:55:54.672812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train_resized[1,:]","metadata":{"execution":{"iopub.status.busy":"2024-05-26T13:55:54.675396Z","iopub.execute_input":"2024-05-26T13:55:54.675834Z","iopub.status.idle":"2024-05-26T13:55:54.685149Z","shell.execute_reply.started":"2024-05-26T13:55:54.67578Z","shell.execute_reply":"2024-05-26T13:55:54.683979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import KFold\nk= 9# Number of folds\nkf = KFold(n_splits=k, shuffle=True, random_state=2)\nfold_no = 1\nscores = []\n\nfor train_index, test_index in kf.split(X_train_resized):\n    print(f'Fold {fold_no}')\n\n    X_train, X_test = X_train_resized[train_index], X_train_resized[test_index]\n    y_train, y_test = Y_train[train_index], Y_train[test_index]\n\n    model.fit(X_train, y_train, epochs=10)\n\n    score = model.evaluate(X_test, y_test)\n    scores.append(score)\n    print(f'Score for fold {fold_no}: {model.metrics_names[1]} of {score[1]*100}%')\n    fold_no += 1\n\nprint(f'Average accuracy: {np.mean([s[1] for s in scores])*100}%')\n","metadata":{"execution":{"iopub.status.busy":"2024-05-26T13:55:54.686529Z","iopub.execute_input":"2024-05-26T13:55:54.686946Z","iopub.status.idle":"2024-05-26T14:01:38.895814Z","shell.execute_reply.started":"2024-05-26T13:55:54.686918Z","shell.execute_reply":"2024-05-26T14:01:38.894753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Method 2 With datagen","metadata":{}},{"cell_type":"code","source":"import tensorflow.keras as K\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport numpy as np\nfrom sklearn.model_selection import KFold\n\n# Define the input shape based on the resized image dimensions\ninput_t = Input(shape=(256, 256, 3))\n\n# Load ResNet50 model with the updated input shape\nres_model = K.applications.ResNet50(include_top=False, weights=\"imagenet\", input_tensor=input_t)\n\n# Freeze earlier layers for fine-tuning (optional)\nfor layer in res_model.layers[:100]:  # Freeze the first 100 layers\n    layer.trainable = False\n\n# Build the rest of the model\nmodel = K.models.Sequential()\nmodel.add(res_model)\nmodel.add(K.layers.Flatten())\nmodel.add(K.layers.Dense(6, activation='softmax'))\n\n# Hyperparameter Tuning\noptimizer = K.optimizers.RMSprop(learning_rate=0.001)  # Lower learning rate\n\n# Regularization (L2 regularization)\nmodel.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])\n\n# Assuming X_train_resized and Y_train are already defined\nk = 9  # Number of folds\nkf = KFold(n_splits=k, shuffle=True, random_state=42)\nfold_no = 1\nscores = []\n\n# Early Stopping (monitor validation loss)\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5)  # Stop training after 5 epochs of no improvement in validation loss\n\nfor train_index, test_index in kf.split(X_train_resized):\n    print(f'Fold {fold_no}')\n\n    X_train, X_test = X_train_resized[train_index], X_train_resized[test_index]\n    y_train, y_test = Y_train[train_index], Y_train[test_index]\n\n    # Decode one-hot encoded labels to categorical labels\n    y_train_cat = np.argmax(y_train, axis=1)\n    y_test_cat = np.argmax(y_test, axis=1)\n\n    # Ensure `classes` contains unique class labels\n    classes = list(set(y_train_cat))\n\n    # Data Augmentation\n    datagen = ImageDataGenerator(\n        rotation_range=20,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        fill_mode='nearest'\n    )\n\n    train_generator = datagen.flow(\n        X_train, y_train,\n        batch_size=32\n    )\n\n    validation_generator = datagen.flow(\n        X_test, y_test,\n        batch_size=32,\n        shuffle=False\n    )\n\n    # Fit the model with augmented training data and early stopping\n    model.fit(train_generator, steps_per_epoch=len(train_generator), epochs=10, validation_data=validation_generator, callbacks=[early_stopping])\n\n    score = model.evaluate(X_test, y_test)\n    scores.append(score)\n    print(f'Score for fold {fold_no}: {model.metrics_names[1]} of {score[1]*100}%')\n    fold_no += 1\n\nprint(f'Average accuracy: {np.mean([s[1] for s in scores])*100}%')\n","metadata":{"execution":{"iopub.status.busy":"2024-05-26T14:09:02.87036Z","iopub.execute_input":"2024-05-26T14:09:02.871424Z","iopub.status.idle":"2024-05-26T14:13:10.049028Z","shell.execute_reply.started":"2024-05-26T14:09:02.871389Z","shell.execute_reply":"2024-05-26T14:13:10.048073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow.keras as K\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport numpy as np\nfrom tensorflow.keras.applications import VGG16\nfrom sklearn.model_selection import KFold\n\n# Define the input shape based on the resized image dimensions\ninput_t = Input(shape=(256, 256, 3))\n\n# Load ResNet50 model with the updated input shape\nbase_model = VGG16(include_top=False, input_shape=(256, 256, 3))\n    # Unfreeze some of the deeper layers\nfor layer in base_model.layers[-4:]:\n    layer.trainable = True\n# Build the rest of the model\nmodel1 = K.models.Sequential()\nmodel1.add(base_model)\nmodel1.add(K.layers.Flatten())\nmodel1.add(K.layers.Dense(6, activation='softmax'))\n\n# Hyperparameter Tuning\noptimizer = K.optimizers.RMSprop(learning_rate=0.001)  # Lower learning rate\n\n# Regularization (L2 regularization)\nmodel1.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])\n\n# Assuming X_train_resized and Y_train are already defined\nk = 9  # Number of folds\nkf = KFold(n_splits=k, shuffle=True, random_state=42)\nfold_no = 1\nscores = []\n\n# Early Stopping (monitor validation loss)\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5)  # Stop training after 5 epochs of no improvement in validation loss\n\nfor train_index, test_index in kf.split(X_train_resized):\n    print(f'Fold {fold_no}')\n\n    X_train, X_test = X_train_resized[train_index], X_train_resized[test_index]\n    y_train, y_test = Y_train[train_index], Y_train[test_index]\n\n    # Decode one-hot encoded labels to categorical labels\n    y_train_cat = np.argmax(y_train, axis=1)\n    y_test_cat = np.argmax(y_test, axis=1)\n\n    # Ensure `classes` contains unique class labels\n    classes = list(set(y_train_cat))\n\n    # Data Augmentation\n    datagen = ImageDataGenerator(\n        rotation_range=20,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        fill_mode='nearest'\n    )\n\n    train_generator = datagen.flow(\n        X_train, y_train,\n        batch_size=32\n    )\n\n    validation_generator = datagen.flow(\n        X_test, y_test,\n        batch_size=32,\n        shuffle=False\n    )\n\n    # Fit the model with augmented training data and early stopping\n    model1.fit(train_generator, steps_per_epoch=len(train_generator), epochs=25, validation_data=validation_generator, callbacks=[early_stopping],verbose=1)\n\n    score = model1.evaluate(X_test, y_test)\n    scores.append(score)\n    print(f'Score for fold {fold_no}: {model1.metrics_names[1]} of {score[1]*100}%')\n    fold_no += 1\n\nprint(f'Average accuracy: {np.mean([s[1] for s in scores])*100}%')\n","metadata":{"execution":{"iopub.status.busy":"2024-05-26T14:34:27.921802Z","iopub.execute_input":"2024-05-26T14:34:27.922158Z","iopub.status.idle":"2024-05-26T14:38:07.763237Z","shell.execute_reply.started":"2024-05-26T14:34:27.92213Z","shell.execute_reply":"2024-05-26T14:38:07.762356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow.keras as K\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport numpy as np\nfrom tensorflow.keras.applications import VGG19\nfrom sklearn.model_selection import KFold\n\n# Define the input shape based on the resized image dimensions\ninput_t = Input(shape=(256, 256, 3))\n\n# Load ResNet50 model with the updated input shape\nbase_model = VGG19(include_top=False, input_shape=(256, 256, 3))\n    # Unfreeze some of the deeper layers\nfor layer in base_model.layers[-4:]:\n    layer.trainable = True\n# Build the rest of the model\nmodel2 = K.models.Sequential()\nmodel2.add(base_model)\nmodel2.add(K.layers.Flatten())\nmodel2.add(K.layers.Dense(6, activation='softmax'))\n\n# Hyperparameter Tuning\noptimizer = K.optimizers.RMSprop(learning_rate=0.001)  # Lower learning rate\n\n# Regularization (L2 regularization)\nmodel2.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])\n\n# Assuming X_train_resized and Y_train are already defined\nk = 7  # Number of folds\nkf = KFold(n_splits=k, shuffle=True, random_state=42)\nfold_no = 1\nscores = []\n\n# Early Stopping (monitor validation loss)\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5)  # Stop training after 5 epochs of no improvement in validation loss\n\nfor train_index, test_index in kf.split(X_train_resized):\n    print(f'Fold {fold_no}')\n\n    X_train, X_test = X_train_resized[train_index], X_train_resized[test_index]\n    y_train, y_test = Y_train[train_index], Y_train[test_index]\n\n    # Decode one-hot encoded labels to categorical labels\n    y_train_cat = np.argmax(y_train, axis=1)\n    y_test_cat = np.argmax(y_test, axis=1)\n\n    # Ensure `classes` contains unique class labels\n    classes = list(set(y_train_cat))\n\n    # Data Augmentation\n    datagen = ImageDataGenerator(\n        rotation_range=20,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        fill_mode='nearest'\n    )\n\n    train_generator = datagen.flow(\n        X_train, y_train,\n        batch_size=32\n    )\n\n    validation_generator = datagen.flow(\n        X_test, y_test,\n        batch_size=32,\n        shuffle=False\n    )\n\n    # Fit the model with augmented training data and early stopping\n    model2.fit(train_generator, steps_per_epoch=len(train_generator), epochs=25, validation_data=validation_generator, callbacks=[early_stopping],verbose=1)\n\n    score = model2.evaluate(X_test, y_test)\n    scores.append(score)\n    print(f'Score for fold {fold_no}: {model2.metrics_names[1]} of {score[1]*100}%')\n    fold_no += 1\n\nprint(f'Average accuracy: {np.mean([s[1] for s in scores])*100}%')\n","metadata":{"execution":{"iopub.status.busy":"2024-05-26T14:40:00.241319Z","iopub.execute_input":"2024-05-26T14:40:00.242161Z","iopub.status.idle":"2024-05-26T14:43:07.495404Z","shell.execute_reply.started":"2024-05-26T14:40:00.242128Z","shell.execute_reply":"2024-05-26T14:43:07.494377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow.keras as K\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport numpy as np\nfrom tensorflow.keras.applications import VGG19\nfrom sklearn.model_selection import KFold\n\n# Define the input shape based on the resized image dimensions\ninput_t = Input(shape=(256, 256, 3))\n\nmodel3 = Sequential([\n        Conv2D(32, (3, 3), activation='relu', input_shape=(img_width, img_height, 3)),\n        MaxPooling2D((2, 2)),\n        Conv2D(64, (3, 3), activation='relu'),\n        MaxPooling2D((2, 2)),\n        Conv2D(128, (3, 3), activation='relu'),\n        MaxPooling2D((2, 2)),\n        Conv2D(256, (3, 3), activation='relu'),\n        MaxPooling2D((2, 2)),\n        Flatten(),\n        Dense(512, activation='relu'),\n        Dropout(0.5),\n        Dense(6, activation='sigmoid')\n    ])\n# Hyperparameter Tuning\noptimizer = K.optimizers.RMSprop(learning_rate=0.001)  # Lower learning rate\n\n# Regularization (L2 regularization)\nmodel3.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])\n\n# Assuming X_train_resized and Y_train are already defined\nk = 7  # Number of folds\nkf = KFold(n_splits=k, shuffle=True, random_state=42)\nfold_no = 1\nscores = []\n\n# Early Stopping (monitor validation loss)\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5)  # Stop training after 5 epochs of no improvement in validation loss\n\nfor train_index, test_index in kf.split(X_train_resized):\n    print(f'Fold {fold_no}')\n\n    X_train, X_test = X_train_resized[train_index], X_train_resized[test_index]\n    y_train, y_test = Y_train[train_index], Y_train[test_index]\n\n    # Decode one-hot encoded labels to categorical labels\n    y_train_cat = np.argmax(y_train, axis=1)\n    y_test_cat = np.argmax(y_test, axis=1)\n\n    # Ensure `classes` contains unique class labels\n    classes = list(set(y_train_cat))\n\n    # Data Augmentation\n    datagen = ImageDataGenerator(\n        rotation_range=20,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        fill_mode='nearest'\n    )\n\n    train_generator = datagen.flow(\n        X_train, y_train,\n        batch_size=32\n    )\n\n    validation_generator = datagen.flow(\n        X_test, y_test,\n        batch_size=32,\n        shuffle=False\n    )\n\n    # Fit the model with augmented training data and early stopping\n    model3.fit(train_generator, steps_per_epoch=len(train_generator), epochs=25, validation_data=validation_generator, callbacks=[early_stopping],verbose=1)\n\n    score = model3.evaluate(X_test, y_test)\n    scores.append(score)\n    print(f'Score for fold {fold_no}: {model3.metrics_names[1]} of {score[1]*100}%')\n    fold_no += 1\n\nprint(f'Average accuracy: {np.mean([s[1] for s in scores])*100}%')\n","metadata":{"execution":{"iopub.status.busy":"2024-05-26T14:46:54.216881Z","iopub.execute_input":"2024-05-26T14:46:54.217271Z","iopub.status.idle":"2024-05-26T14:50:29.40988Z","shell.execute_reply.started":"2024-05-26T14:46:54.21724Z","shell.execute_reply":"2024-05-26T14:50:29.409018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train_resized","metadata":{"execution":{"iopub.status.busy":"2024-05-26T15:05:12.325866Z","iopub.execute_input":"2024-05-26T15:05:12.326245Z","iopub.status.idle":"2024-05-26T15:05:12.337483Z","shell.execute_reply.started":"2024-05-26T15:05:12.326214Z","shell.execute_reply":"2024-05-26T15:05:12.336581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nfrom tensorflow.keras.applications import VGG16, ResNet50, ResNet50V2\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.applications.vgg16 import preprocess_input\nfrom tensorflow.keras.models import Model\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import accuracy_score\n\n# Load pre-trained models\nvgg_model = VGG16(weights='imagenet', include_top=False)\nresnet_model = ResNet50(weights='imagenet', include_top=False)\nresnext_model = ResNet50V2(weights='imagenet', include_top=False)\n\n# Extract features from your training data using each model\ndef extract_features(model, img_paths):\n    features = []\n    for img_pat in img_paths:\n        x = np.expand_dims(img_pat, axis=0)\n        x = preprocess_input(x)\n        features.append(model.predict(x))\n    return np.array(features)\n\n# Sample code to load your training data\n# img_paths = [...]  # List of paths to your training images\n# labels = [...]  # List of corresponding labels\n\n# Extract features using each model\nvgg_features = extract_features(vgg_model, img_train)\nresnet_features = extract_features(resnet_model, img_data)\nresnext_features = extract_features(resnext_model, img_data)\n\n# Combine features\ncombined_features = np.concatenate((vgg_features, resnet_features, resnext_features), axis=1)\n\n# Split data into train and test sets\nX_train, X_test, y_train, y_test = train_test_split(combined_features, labels, test_size=0.2, random_state=42)\n\n# Train meta-learner\nmeta_learner = LogisticRegression()\nmeta_learner.fit(X_train, y_train)\n\n# Make predictions\ny_pred = meta_learner.predict(X_test)\n\n# Evaluate accuracy\naccuracy = accuracy_score(y_test, y_pred)\nprint(\"Ensemble Accuracy:\", accuracy)","metadata":{"execution":{"iopub.status.busy":"2024-05-26T15:05:41.624813Z","iopub.execute_input":"2024-05-26T15:05:41.625196Z","iopub.status.idle":"2024-05-26T15:05:45.86597Z","shell.execute_reply.started":"2024-05-26T15:05:41.625165Z","shell.execute_reply":"2024-05-26T15:05:45.864506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install efficientnet","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:26:24.915568Z","iopub.execute_input":"2024-06-08T14:26:24.916201Z","iopub.status.idle":"2024-06-08T14:26:38.507588Z","shell.execute_reply.started":"2024-06-08T14:26:24.91617Z","shell.execute_reply":"2024-06-08T14:26:38.506395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import efficientnet.keras as efn ","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:26:38.510054Z","iopub.execute_input":"2024-06-08T14:26:38.510439Z","iopub.status.idle":"2024-06-08T14:26:46.074143Z","shell.execute_reply.started":"2024-06-08T14:26:38.510402Z","shell.execute_reply":"2024-06-08T14:26:46.07317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow.keras as K\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport numpy as np\nfrom sklearn.model_selection import KFold\nfrom keras.layers import Dense, Flatten, Dropout\nfrom keras.optimizers import Adam","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:26:46.075339Z","iopub.execute_input":"2024-06-08T14:26:46.075946Z","iopub.status.idle":"2024-06-08T14:26:46.369304Z","shell.execute_reply.started":"2024-06-08T14:26:46.075908Z","shell.execute_reply":"2024-06-08T14:26:46.368556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow.keras as K\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport numpy as np\nfrom sklearn.model_selection import KFold\n\n# Define the input shape based on the resized image dimensions\ninput_t = Input(shape=(256, 256, 3))\n    # Full Training Model\n\n# Load ResNet50 model with the updated input shape\nbase_model = efn.EfficientNetB4(weights = 'imagenet', include_top = False, pooling = 'avg', input_shape = (256,256,3))\n    # Unfreeze some of the deeper layers\nfor base_layer in base_model.layers[:-1]:\n    base_layer.trainable = True\n    \n# Build the rest of the model\nmodel = K.models.Sequential()\nmodel.add(base_model)\nmodel.add(K.layers.Flatten())\nmodel.add(K.layers.Dense(6, activation='softmax'))\n\n# Hyperparameter Tuning\noptimizer = K.optimizers.RMSprop(learning_rate=0.001)  # Lower learning rate\n\n# Regularization (L2 regularization)\nmodel.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])\n\n# Assuming X_train_resized and Y_train are already defined\nk = 7  # Number of folds\nkf = KFold(n_splits=k, shuffle=True, random_state=42)\nfold_no = 1\nscores = []\n\n# Early Stopping (monitor validation loss)\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5)  # Stop training after 5 epochs of no improvement in validation loss\n\nfor train_index, test_index in kf.split(X_train_resized):\n    print(f'Fold {fold_no}')\n\n    X_train, X_test = X_train_resized[train_index], X_train_resized[test_index]\n    y_train, y_test = Y_train[train_index], Y_train[test_index]\n\n    # Decode one-hot encoded labels to categorical labels\n    y_train_cat = np.argmax(y_train, axis=1)\n    y_test_cat = np.argmax(y_test, axis=1)\n\n    # Ensure `classes` contains unique class labels\n    classes = list(set(y_train_cat))\n\n    # Data Augmentation\n    datagen = ImageDataGenerator(\n        rotation_range=20,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        fill_mode='nearest'\n    )\n\n    train_generator = datagen.flow(\n        X_train, y_train,\n        batch_size=32\n    )\n\n    validation_generator = datagen.flow(\n        X_test, y_test,\n        batch_size=32,\n        shuffle=False\n    )\n\n    # Fit the model with augmented training data and early stopping\n    model.fit(train_generator, steps_per_epoch=len(train_generator), epochs=25, validation_data=validation_generator, callbacks=[early_stopping],verbose=1)\n\n    score = model.evaluate(X_test, y_test)\n    scores.append(score)\n    print(f'Score for fold {fold_no}: {model.metrics_names[1]} of {score[1]*100}%')\n    fold_no += 1\n\nprint(f'Average accuracy: {np.mean([s[1] for s in scores])*100}%')\n","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:12:43.360725Z","iopub.execute_input":"2024-06-08T14:12:43.361019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow.keras as K\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport numpy as np\nfrom sklearn.model_selection import KFold\n\n# Define the input shape based on the resized image dimensions\ninput_t = Input(shape=(256, 256, 3))\n    # Full Training Model\n\n# Load ResNet50 model with the updated input shape\nbase_model = efn.EfficientNetB5(weights = 'imagenet', include_top = False, pooling = 'avg', input_shape = (256,256,3))\n    # Unfreeze some of the deeper layers\nfor base_layer in base_model.layers[:-1]:\n    base_layer.trainable = True\n    \n# Build the rest of the model\nmodel = K.models.Sequential()\nmodel.add(base_model)\nmodel.add(K.layers.Flatten())\nmodel.add(K.layers.Dense(6, activation='softmax'))\n\n# Hyperparameter Tuning\noptimizer = K.optimizers.RMSprop(learning_rate=0.001)  # Lower learning rate\n\n# Regularization (L2 regularization)\nmodel.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])\n\n# Assuming X_train_resized and Y_train are already defined\nk = 7  # Number of folds\nkf = KFold(n_splits=k, shuffle=True, random_state=42)\nfold_no = 1\nscores = []\n\n# Early Stopping (monitor validation loss)\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5)  # Stop training after 5 epochs of no improvement in validation loss\n\nfor train_index, test_index in kf.split(X_train_resized):\n    print(f'Fold {fold_no}')\n\n    X_train, X_test = X_train_resized[train_index], X_train_resized[test_index]\n    y_train, y_test = Y_train[train_index], Y_train[test_index]\n\n    # Decode one-hot encoded labels to categorical labels\n    y_train_cat = np.argmax(y_train, axis=1)\n    y_test_cat = np.argmax(y_test, axis=1)\n\n    # Ensure `classes` contains unique class labels\n    classes = list(set(y_train_cat))\n\n    # Data Augmentation\n    datagen = ImageDataGenerator(\n        rotation_range=20,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        fill_mode='nearest'\n    )\n\n    train_generator = datagen.flow(\n        X_train, y_train,\n        batch_size=32\n    )\n\n    validation_generator = datagen.flow(\n        X_test, y_test,\n        batch_size=32,\n        shuffle=False\n    )\n\n    # Fit the model with augmented training data and early stopping\n    model.fit(train_generator, steps_per_epoch=len(train_generator), epochs=25, validation_data=validation_generator, callbacks=[early_stopping],verbose=1)\n\n    score = model.evaluate(X_test, y_test)\n    scores.append(score)\n    print(f'Score for fold {fold_no}: {model.metrics_names[1]} of {score[1]*100}%')\n    fold_no += 1\n\nprint(f'Average accuracy: {np.mean([s[1] for s in scores])*100}%')\n","metadata":{"execution":{"iopub.status.busy":"2024-06-08T13:51:51.834038Z","iopub.execute_input":"2024-06-08T13:51:51.83444Z","iopub.status.idle":"2024-06-08T13:59:02.295193Z","shell.execute_reply.started":"2024-06-08T13:51:51.834409Z","shell.execute_reply":"2024-06-08T13:59:02.294343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow.keras as K\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport numpy as np\nfrom sklearn.model_selection import KFold\n\n# Define the input shape based on the resized image dimensions\ninput_t = Input(shape=(256, 256, 3))\n    # Full Training Model\n\n# Load ResNet50 model with the updated input shape\nbase_model = efn.EfficientNetB7(weights = 'imagenet', include_top = False, pooling = 'avg', input_shape = (256,256,3))\n    # Unfreeze some of the deeper layers\nfor base_layer in base_model.layers[:-1]:\n    base_layer.trainable = True\n    \n# Build the rest of the model\nmodel = K.models.Sequential()\nmodel.add(base_model)\nmodel.add(K.layers.Flatten())\nmodel.add(K.layers.Dense(6, activation='softmax'))\n\n# Hyperparameter Tuning\noptimizer = K.optimizers.RMSprop(learning_rate=0.001)  # Lower learning rate\n\n# Regularization (L2 regularization)\nmodel.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])\n\n# Assuming X_train_resized and Y_train are already defined\nk = 7  # Number of folds\nkf = KFold(n_splits=k, shuffle=True, random_state=42)\nfold_no = 1\nscores = []\n\n# Early Stopping (monitor validation loss)\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5)  # Stop training after 5 epochs of no improvement in validation loss\n\nfor train_index, test_index in kf.split(X_train_resized):\n    print(f'Fold {fold_no}')\n\n    X_train, X_test = X_train_resized[train_index], X_train_resized[test_index]\n    y_train, y_test = Y_train[train_index], Y_train[test_index]\n\n    # Decode one-hot encoded labels to categorical labels\n    y_train_cat = np.argmax(y_train, axis=1)\n    y_test_cat = np.argmax(y_test, axis=1)\n\n    # Ensure `classes` contains unique class labels\n    classes = list(set(y_train_cat))\n\n    # Data Augmentation\n    datagen = ImageDataGenerator(\n        rotation_range=20,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        fill_mode='nearest'\n    )\n\n    train_generator = datagen.flow(\n        X_train, y_train,\n        batch_size=32\n    )\n\n    validation_generator = datagen.flow(\n        X_test, y_test,\n        batch_size=32,\n        shuffle=False\n    )\n\n    # Fit the model with augmented training data and early stopping\n    model.fit(train_generator, steps_per_epoch=len(train_generator), epochs=25, validation_data=validation_generator, callbacks=[early_stopping],verbose=1)\n\n    score = model.evaluate(X_test, y_test)\n    scores.append(score)\n    print(f'Score for fold {fold_no}: {model.metrics_names[1]} of {score[1]*100}%')\n    fold_no += 1\n\nprint(f'Average accuracy: {np.mean([s[1] for s in scores])*100}%')\n","metadata":{"execution":{"iopub.status.busy":"2024-06-08T14:31:22.845092Z","iopub.execute_input":"2024-06-08T14:31:22.846069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}