{"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":"import pandas as pd \nimport numpy as np \nimport tensorflow as tf\nimport matplotlib.pyplot as plt \nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import log_loss\nimport os\nimport time\nimport math","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PATH = \"../input/applications-of-deep-learning-wustl-spring-2021b/mc/\"\nPATH_TRAIN = os.path.join(PATH, \"train.csv\")\nPATH_TEST = os.path.join(PATH, \"test.csv\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(PATH_TRAIN)\ndf_test = pd.read_csv(PATH_TEST)\ndf_train['fake'] = df_train['fake'].astype('str')\ndf_train.head()","metadata":{"_kg_hide-output":false,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data (Image Augmentation) Visualization","metadata":{}},{"cell_type":"code","source":"fig,ax = plt.subplots(figsize=(8,5))\nax.bar(df_train.fake.value_counts().index,df_train.fake.value_counts().values,width=0.5)\nax.set_title('Target')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Relatively balanced dataset","metadata":{}},{"cell_type":"markdown","source":"## Original Picture","metadata":{}},{"cell_type":"code","source":"img = Image.open('../input/applications-of-deep-learning-wustl-spring-2021b/mc/mc-1.jpg')\n#img = img.resize((512,512),Image.ANTIALIAS)\nimg_arr = np.asarray(img)\nfig,ax = plt.subplots(figsize=(6,6))\nax.imshow(img_arr)\nax.set_title('Original Figure')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Horizontal/Vertical Flip","metadata":{}},{"cell_type":"code","source":"datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n            horizontal_flip = True,\n            vertical_flip = True,\n            fill_mode = 'nearest')\naug_iter = datagen.flow(np.expand_dims(img_arr,axis=0), batch_size=1)\n\nfig, ax = plt.subplots(nrows=1,ncols=5,figsize=(15,15))\n# generate batch of images\nfor i in range(5):\n    image = next(aug_iter)[0].astype('uint8')\n    ax[i].imshow(image)\n    ax[i].axis('off')\n    ax[i].set_title('Horizonal/Vertical Flipped')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Horizontal Flipping could be a good augmentation method.","metadata":{}},{"cell_type":"markdown","source":"## Horizontal/Vertical Shift","metadata":{}},{"cell_type":"code","source":"datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n            width_shift_range=0.1, \n            height_shift_range=0.1,\n            fill_mode = 'nearest')\naug_iter = datagen.flow(np.expand_dims(img_arr,axis=0), batch_size=1)\n\nfig, ax = plt.subplots(nrows=1,ncols=3,figsize=(15,15))\n# generate batch of images\nfor i in range(3):\n    image = next(aug_iter)[0].astype('uint8')\n    ax[i].imshow(image)\n    ax[i].axis('off')\n    ax[i].set_title('Vertical/Horizontal Shift')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Not sure. But worth a try.","metadata":{}},{"cell_type":"markdown","source":"## Rotation","metadata":{}},{"cell_type":"code","source":"datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n            rotation_range = 45,\n            fill_mode = 'nearest')\naug_iter = datagen.flow(np.expand_dims(img_arr,axis=0), batch_size=1)\n\nfig, ax = plt.subplots(nrows=1,ncols=5,figsize=(15,15))\n# generate batch of images\nfor i in range(5):\n    image = next(aug_iter)[0].astype('uint8')\n    ax[i].imshow(image)\n    ax[i].axis('off')\n    ax[i].set_title('Rotation')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Seems not bad","metadata":{}},{"cell_type":"markdown","source":"## Brightness","metadata":{}},{"cell_type":"code","source":"datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n            brightness_range = [0.8,1.1],\n            fill_mode = 'nearest')\naug_iter = datagen.flow(np.expand_dims(img_arr,axis=0), batch_size=1)\n\nfig, ax = plt.subplots(nrows=1,ncols=5,figsize=(15,15))\n# generate batch of images\nfor i in range(5):\n    image = next(aug_iter)[0].astype('uint8')\n    ax[i].imshow(image)\n    ax[i].axis('off')\n    ax[i].set_title('Brighten')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's see how brighten affect dark images","metadata":{}},{"cell_type":"code","source":"img2 = Image.open('../input/applications-of-deep-learning-wustl-spring-2021b/mc/mc-1000.jpg')\n#img = img.resize((IMAGE_WIDTH,IMAGE_HEIGHT),Image.ANTIALIAS)\nimg2_arr = np.asarray(img2)\nfig,ax = plt.subplots(figsize=(6,6))\nax.imshow(img2_arr)\nax.set_title('Original Figure')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n            brightness_range = [0.8,1.1],\n            fill_mode = 'nearest')\naug_iter = datagen.flow(np.expand_dims(img2_arr,axis=0), batch_size=1)\n\nfig, ax = plt.subplots(nrows=1,ncols=5,figsize=(15,15))\n# generate batch of images\nfor i in range(5):\n    image = next(aug_iter)[0].astype('uint8')\n    ax[i].imshow(image)\n    ax[i].axis('off')\n    ax[i].set_title('Brighten')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Zoom ","metadata":{}},{"cell_type":"code","source":"datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n            zoom_range = [0.5,1.5],\n            fill_mode = 'nearest')\naug_iter = datagen.flow(np.expand_dims(img_arr,axis=0), batch_size=1)\n\nfig, ax = plt.subplots(nrows=1,ncols=5,figsize=(15,15))\n# generate batch of images\nfor i in range(5):\n    image = next(aug_iter)[0].astype('uint8')\n    ax[i].imshow(image)\n    ax[i].axis('off')\n    ax[i].set_title('Zoom')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Preparation","metadata":{}},{"cell_type":"code","source":"train_X,val_X,train_y,val_y = train_test_split(df_train.drop(columns='fake',axis=1),\n                                               df_train['fake'],\n                                               test_size=0.2,\n                                               shuffle=True,\n                                               random_state=98)\ndf_train_cut = pd.concat([train_X,train_y],axis=1)\ndf_val_cut = pd.concat([val_X,val_y],axis=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def DataGeneration(Height, Width, BatchSize):\n    start_time = time.time()\n    training_datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n                rescale = 1./255,\n                horizontal_flip = True,\n                #vertical_flip = True,\n                #rotation_range = 30,\n                #brightness_range = [0.8,1.5],\n                #zoom_range = [0.8,1.2],\n                fill_mode = 'nearest')\n    train_generator = training_datagen.flow_from_dataframe(\n            dataframe = df_train_cut,\n            directory = PATH,\n            x_col = \"filename\",\n            y_col = \"fake\",\n            target_size = (Height, Width),\n            batch_size = BatchSize,\n            class_mode = 'binary',\n            shuffle = True,\n            seed = 98)\n\n    validation_datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n                rescale = 1./255)\n    val_generator = validation_datagen.flow_from_dataframe(\n            dataframe = df_val_cut,\n            directory = PATH,\n            x_col = \"filename\",\n            y_col = \"fake\",\n            target_size = (Height, Width),\n            batch_size = BATCH_SIZE,\n            class_mode = 'binary',\n            shuffle = True,\n            seed = 98)\n\n    print(f'----{time.time()-start_time} seconds----')\n    return train_generator, val_generator","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Warmup with Expotential Decay Learning Rate Scheduler\ndef scheduler(epoch):\n    if epoch<= WARMUP_EPOCH:\n        lr = INITIAL_LEARNINGRATE *epoch/WARMUP_EPOCH\n    \n    else:\n        lr = INITIAL_LEARNINGRATE * DECAY_RATE**(epoch-WARMUP_EPOCH)\n    \n    return lr","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CNN Stater","metadata":{}},{"cell_type":"code","source":"HEIGHT = 128\nWIDTH = 128\nBATCH_SIZE = 128\n\ntrain_generator, val_generator = DataGeneration(Height = HEIGHT, \n                                                Width = WIDTH,\n                                                BatchSize = BATCH_SIZE)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator[0][0][0].shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.backend.clear_session()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"CNN Model from scratch is trained to compare the effects of implementing different real-time image augmentation methods because it is fast to train. Thanks for the professor's starter notebook.","metadata":{}},{"cell_type":"code","source":"EPOCHS = 50\n#STEPS_PER_EPOCH = train_generator.n//BATCH_SIZE\nSTEPS_PER_EPOCH = 50\n#VALIDATION_STEPS = val_generator.n//BATCH_SIZE\nVALIDATION_STEPS = 25\nLEARNING_RATE = 1e-3\n\nmodel = tf.keras.models.Sequential([\n\n    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(HEIGHT, WIDTH, 3)),\n    tf.keras.layers.MaxPooling2D(2,2),\n    \n    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n    tf.keras.layers.Dropout(0.5),\n    #tf.keras.layers.BatchNormalization(),\n    tf.keras.layers.MaxPooling2D(2,2),\n    \n    #tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n    #tf.keras.layers.Dropout(0.5),\n    #tf.keras.layers.BatchNormalization(),\n    #tf.keras.layers.MaxPooling2D(2,2),\n    \n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dropout(0.5),\n    tf.keras.layers.Dense(512, activation='relu'),\n    tf.keras.layers.Dense(1, activation='sigmoid')\n])\n\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(loss = 'binary_crossentropy', \n              optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),\n              metrics = 'accuracy')\nmonitor = tf.keras.callbacks.EarlyStopping(monitor='val_loss', \n                                           min_delta=1e-4, \n                                           patience=10, \n                                           verbose=1, \n                                           mode='min',\n                                           restore_best_weights=True)\n#lr_scheduler = tf.keras.callbacks.LearningRateScheduler(scheduler,verbose=1)\nlr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor=\"val_loss\",\n                                                    factor=0.2,\n                                                    patience=5,\n                                                    verbose=1,\n                                                    mode='min',\n                                                    min_delta=1e-4,\n                                                    cooldown=0,\n                                                    min_lr=1e-5,)\n\ncheckpoint = tf.keras.callbacks.ModelCheckpoint('CNN_best_weight.h5', \n                                                monitor='val_loss', \n                                                verbose=1, \n                                                save_best_only=True, \n                                                save_weights_only=True, \n                                                mode='min',\n                                                save_freq = 'epoch')\n\nhistory = model.fit(train_generator, \n                    epochs=EPOCHS, \n                    steps_per_epoch=STEPS_PER_EPOCH, \n                    validation_data = val_generator, \n                    verbose = 1, \n                    validation_steps=VALIDATION_STEPS,\n                    callbacks = [monitor,lr_scheduler,checkpoint])","metadata":{"_kg_hide-input":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Transfer Learning","metadata":{}},{"cell_type":"code","source":"def BuildModel(ModelName):\n    print('--------------Building The Model...--------------')\n    if ModelName == 'ResNet50' or ModelName == 'Xception':\n        if ModelName == 'ResNet50':\n            base_model = tf.keras.applications.ResNet50(include_top=False,\n                                                    weights='imagenet',\n                                                    input_shape=(HEIGHT,WIDTH,3))\n        \n        elif ModelName == 'Xception':\n            base_model = tf.keras.applications.Xception(include_top=False,\n                                                weights='imagenet',\n                                                input_shape=(HEIGHT,WIDTH,3))\n        \n        base_model.trainable = True\n        print(\"\\nNumber of layers in the base model: \", len(base_model.layers))\n        #print(base_model.layers[0].output_shape)\n        x = base_model.output\n        x = tf.keras.layers.GlobalAveragePooling2D()(x)\n        x = tf.keras.layers.Dense(1024,activation='relu')(x)\n        #x = tf.keras.layers.BatchNormalization()(x)\n        x = tf.keras.layers.Dense(512,activation='relu')(x)\n        #x = tf.keras.layers.Dropout(0.5)(x)\n        x = tf.keras.layers.Dense(64,activation='relu')(x)\n        out = tf.keras.layers.Dense(1, activation='sigmoid')(x)\n        model = tf.keras.models.Model(inputs=base_model.input, outputs=out)\n    \n    elif ModelName == 'EfficientNetB0':\n        base_model = tf.keras.applications.EfficientNetB0(include_top=False,\n                                                weights='imagenet',\n                                                input_shape=(HEIGHT,WIDTH,3))\n        base_model.trainable = True\n        print(\"\\nNumber of layers in the base model: \", len(base_model.layers))\n        #print(base_model.layers[0].output_shape)\n        x = base_model.output\n        x = tf.keras.layers.GlobalAveragePooling2D()(x)\n        x = tf.keras.layers.Dense(512,activation='relu')(x)\n        #x = tf.keras.layers.BatchNormalization()(x)\n        x = tf.keras.layers.Dense(64,activation='relu')(x)\n        out = tf.keras.layers.Dense(1, activation='sigmoid')(x)\n        model = tf.keras.models.Model(inputs=base_model.input, outputs=out)\n    \n    print('\\n--------------Done!--------------')\n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def ModelDeployment(model, LearningRate, ModelName,  NbOfEpoch, StepsPerEpoch, ValidationSteps):\n    ## Freeze all the layers before the `fine_tune_at` layer\n    #for layer in base_model.layers[:fine_tune_at]:\n    #    layer.trainable =  False\n    print('--------------Deploying the Model...--------------')\n    model.compile(loss = 'binary_crossentropy', \n                  optimizer=tf.keras.optimizers.Adam(learning_rate=LearningRate),\n                  metrics = 'accuracy')\n    monitor = tf.keras.callbacks.EarlyStopping(monitor='val_loss', \n                                               min_delta=1e-4, \n                                               patience=10, \n                                               verbose=1, \n                                               mode='min',\n                                               restore_best_weights=True)\n    #lr_scheduler = tf.keras.callbacks.LearningRateScheduler(scheduler,verbose=1)\n    lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor=\"val_loss\",\n                                                        factor=0.5,\n                                                        patience=3,\n                                                        verbose=1,\n                                                        mode='min',\n                                                        min_delta=1e-4,\n                                                        cooldown=0,\n                                                        min_lr=MIN_LR,)\n\n    filepath= ModelName+\"-{epoch:02d}-{val_loss:.4f}.hdf5\"\n    checkpoint = tf.keras.callbacks.ModelCheckpoint(filepath, \n                                                    monitor='val_loss', \n                                                    verbose=1, \n                                                    save_best_only=False, \n                                                    save_weights_only=True, \n                                                    mode='min',\n                                                    save_freq = 'epoch')\n    print('--------------Deployed Successfully--------------')\n    print('--------------Training Begins--------------')\n    history = model.fit(train_generator, \n                            epochs = NbOfEpoch, \n                            steps_per_epoch = StepsPerEpoch, \n                            validation_data = val_generator, \n                            verbose = 1, \n                            validation_steps = ValidationSteps,\n                            callbacks = [monitor,lr_scheduler,checkpoint])\n    return history","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def HistoryPlotting(history):\n    fig,ax = plt.subplots(figsize=(8,5))\n    ax.plot(history.history['loss'],label='train',color='blue')\n    ax.plot(history.history['val_loss'],label='val',color='green')\n    ax.set_title('model loss',fontsize=14)\n    #ax.set_yticks()\n    ax.set_ylabel('loss')\n    ax.set_xlabel('epoch')\n    #ax.set_xticks(range(0,20))\n    ax.legend(loc='upper right',fontsize=13)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ResNet50","metadata":{}},{"cell_type":"code","source":"HEIGHT = 256\nWIDTH = 256\nBATCH_SIZE = 32\n\ntrain_generator, val_generator = DataGeneration(Height = HEIGHT, \n                                                Width = WIDTH,\n                                                BatchSize = BATCH_SIZE)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.backend.clear_session()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Resnet_based_model = BuildModel(ModelName='ResNet50')\nResnet_based_model.summary()","metadata":{"_kg_hide-output":true,"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEPS_PER_EPOCH = train_generator.n//BATCH_SIZE\n#STEPS_PER_EPOCH = 200\nVALIDATION_STEPS = val_generator.n//BATCH_SIZE\n#VALIDATION_STEPS = 50\nLEARNING_RATE = 1e-5\nNB_EPOCH = 50\n#FINETUNE_LEARNING_RATE = LEARNING_RATE/10\n#MIN_LR = 1e-8 \n#fine_tune_at = 200\nResnet50_history = ModelDeployment(model = Resnet_based_model, \n                                   LearningRate = LEARNING_RATE, \n                                   ModelName = 'ResNet50',  \n                                   NbOfEpoch = NB_EPOCH, \n                                   StepsPerEpoch = STEPS_PER_EPOCH, \n                                   ValidationSteps = VALIDATION_STEPS)","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Xception","metadata":{}},{"cell_type":"code","source":"tf.keras.backend.clear_session()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"HEIGHT = 256\nWIDTH = 256\nBATCH_SIZE = 32\n\ntrain_generator, val_generator = DataGeneration(Height = HEIGHT, \n                                                Width = WIDTH,\n                                                BatchSize = BATCH_SIZE)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Xception_based_model = BuildModel(ModelName='Xception')\nXception_based_model.summary()","metadata":{"_kg_hide-output":true,"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEPS_PER_EPOCH = train_generator.n//BATCH_SIZE\n#STEPS_PER_EPOCH = 200\nVALIDATION_STEPS = val_generator.n//BATCH_SIZE\n#VALIDATION_STEPS = 50\nLEARNING_RATE = 1e-5\nNB_EPOCH = 50\n\nXception_history = ModelDeployment(model = Xception_based_model, \n                                   LearningRate = LEARNING_RATE, \n                                   ModelName = 'Xception',  \n                                   NbOfEpoch = NB_EPOCH, \n                                   StepsPerEpoch = STEPS_PER_EPOCH, \n                                   ValidationSteps = VALIDATION_STEPS)","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## EfficientNet","metadata":{}},{"cell_type":"code","source":"tf.keras.backend.clear_session()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"HEIGHT = 256\nWIDTH = 256\nBATCH_SIZE = 32\n\ntrain_generator, val_generator = DataGeneration(Height = HEIGHT, \n                                                Width = WIDTH,\n                                                BatchSize = BATCH_SIZE)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EfficientNet_based_model = BuildModel(ModelName='EfficientNetB0')\nEfficientNet_based_model.summary()","metadata":{"_kg_hide-output":true,"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEPS_PER_EPOCH = train_generator.n//BATCH_SIZE\n#STEPS_PER_EPOCH = 200\nVALIDATION_STEPS = val_generator.n//BATCH_SIZE\n#VALIDATION_STEPS = 50\nLEARNING_RATE = 1e-5\nNB_EPOCH = 50\n\nEfficientNet_history = ModelDeployment(model = EfficientNet_based_model, \n                                   LearningRate = LEARNING_RATE, \n                                   ModelName = 'EfficientNetB0',  \n                                   NbOfEpoch = NB_EPOCH, \n                                   StepsPerEpoch = STEPS_PER_EPOCH, \n                                   ValidationSteps = VALIDATION_STEPS)","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Validation Evaluation","metadata":{}},{"cell_type":"markdown","source":"Visualize the validation result and test different clipping strategy.","metadata":{}},{"cell_type":"code","source":"val_datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n        rescale = 1./255)\nval_generator = val_datagen.flow_from_dataframe(\n        dataframe = df_val_cut,\n        directory = PATH,\n        x_col=\"filename\",\n        target_size = (HEIGHT, WIDTH),\n        batch_size = 1,\n        shuffle = False,\n        class_mode = None)\n## very important\nval_generator.reset()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Resnet_based_model = BuildModel(ModelName='ResNet50')\nXception_based_model = BuildModel(ModelName='Xception')\nEfficientNet_based_model = BuildModel(ModelName='EfficientNetB0')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Resnet_based_model.load_weights('../input/resnet50bestweight2/ResNet50-02-0.1628.hdf5')\nXception_based_model.load_weights('../input/xceptionbestweight/Xception-02-0.14.hdf5')\nEfficientNet_based_model.load_weights('../input/efficientnetb0bestweight/EfficientNetB0-24-0.1663.hdf5')\n\nResnet_val_pred = Resnet_based_model.predict(val_generator,steps=len(df_val_cut))\nXception_val_pred = Xception_based_model.predict(val_generator,steps=len(df_val_cut))\nEfficientNet_val_pred = EfficientNet_based_model.predict(val_generator,steps=len(df_val_cut))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_y = df_val_cut['fake'].astype(np.float32).values\nResnet_val_logloss = log_loss(val_y,Resnet_val_pred.flatten())\nXception_val_logloss = log_loss(val_y,Xception_val_pred.flatten())\nEfficientNet_val_logloss = log_loss(val_y,EfficientNet_val_pred.flatten())\nprint(f'Before Clipping,\\nResnet_Logloss: {Resnet_val_logloss}\\nXception_Logloss: {Xception_val_logloss}\\nEfficientNet_Logloss: {EfficientNet_val_logloss}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Blending + Clipping","metadata":{}},{"cell_type":"code","source":"ensemble_pred_1 = 0.3*Resnet_val_pred + 0.4*Xception_val_pred+0.3*EfficientNet_val_pred\nprint(f'Before Clipping, Blending_Logloss: {log_loss(val_y,ensemble_pred_1)}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"clipped_ensemble_pred_1 = np.clip(ensemble_pred_1,0.03,0.97)\nprint(f'After Clipping, Blending_Logloss: {log_loss(val_y,clipped_ensemble_pred_1)}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Clipping + Blending","metadata":{}},{"cell_type":"markdown","source":"clipping strategy:\n\n(0.03,0.97) for ResNet50 & Xception, (0.04,0.96) for EfficientNetB0","metadata":{}},{"cell_type":"code","source":"Resnet_clipped_val_pred = np.clip(Resnet_val_pred.flatten(),0.04,0.96)\nXception_clipped_val_pred = np.clip(Xception_val_pred.flatten(),0.03,0.97)\nEfficientNet_clipped_val_pred = np.clip(EfficientNet_val_pred.flatten(),0.04,0.96)\n\nResnet_val_logloss = log_loss(val_y,Resnet_clipped_val_pred)\nXception_val_logloss = log_loss(val_y,Xception_clipped_val_pred)\nEfficientNet_val_logloss = log_loss(val_y,EfficientNet_clipped_val_pred)\nprint(f'After Clipping,\\nResnet_Logloss: {Resnet_val_logloss}\\nXception_Logloss: {Xception_val_logloss}\\nEfficientNet_Logloss: {EfficientNet_val_logloss}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ensemble_pred_2 = 0.3*Resnet_clipped_val_pred + 0.4*Xception_clipped_val_pred + 0.3*EfficientNet_clipped_val_pred\n#ensemble_pred_2 = (Resnet_clipped_val_pred + Xception_clipped_val_pred + EfficientNet_clipped_val_pred)/3\nlog_loss(val_y,ensemble_pred_2)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_class = np.round(ensemble_pred.flatten())\nwrong_idx = np.argwhere(val_y!=pred_class).flatten()\ndf_val_cut = df_val_cut.reset_index(drop=True)\nval_image_paths = [os.path.join(PATH, filename) for filename in df_val_cut.filename[wrong_idx[:10]]]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Take a look at first ten misclassified pictures.","metadata":{}},{"cell_type":"code","source":"fig,ax = plt.subplots(nrows=2,ncols=5,figsize=(25,10))\nfor idx,path in enumerate(val_image_paths):\n    img = Image.open(path)\n    #img = img.resize((IMAGE_WIDTH,IMAGE_HEIGHT),Image.ANTIALIAS)\n    img_arr = np.asarray(img)\n    ax[divmod(idx,5)[0],divmod(idx,5)[1]].imshow(img_arr)\n    ax[divmod(idx,5)[0],divmod(idx,5)[1]].set_title(f'Pred:{pred_class[wrong_idx[idx]]}  Real:{1-pred_class[wrong_idx[idx]]}')\n    ax[divmod(idx,5)[0],divmod(idx,5)[1]].axis('off')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#  Submission","metadata":{}},{"cell_type":"code","source":"start_time = time.time()\ntest_datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n        rescale = 1./255)\ntest_generator = test_datagen.flow_from_dataframe(\n        dataframe = df_test,\n        directory = PATH,\n        x_col=\"filename\",\n        target_size = (HEIGHT, WIDTH),\n        batch_size = 1,\n        shuffle = False,\n        class_mode = None)\nprint(f'----{time.time()-start_time} seconds----')\n## very important\ntest_generator.reset()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Xception_based_model.load_weights('./Xception-02-0.16.hdf5')\n#Resnet_based_model.load_weights('./ResNet50-02-0.1628.hdf5')\n#EfficientNet_based_model.load_weights('../input/efficientnetb0bestweight/EfficientNetB0-24-0.1663.hdf5')\n\nResnet_pred = Resnet_based_model.predict(test_generator,steps=len(df_test))\nXception_pred = Xception_based_model.predict(test_generator,steps=len(df_test))\nEfficientNet_pred = EfficientNet_based_model.predict(test_generator,steps=len(df_test))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ensemble_pred = 0.3*Resnet_pred + 0.4*Xception_pred + 0.3*EfficientNet_pred\n#clipped_ensemble_pred = np.clip(ensemble_pred,0.03,0.97)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Resnet_clipped_pred = np.clip(Resnet_pred.flatten(),0.04,0.96)\nXception_clipped_pred = np.clip(Xception_pred.flatten(),0.03,0.97)\nEfficientNet_clipped_pred = np.clip(EfficientNet_pred.flatten(),0.04,0.96)\n\nensemble_pred = 0.3*Resnet_clipped_pred + 0.4*Xception_clipped_pred + 0.3*EfficientNet_clipped_pred\n#ensemble_pred = (Resnet_clipped_pred + Xception_clipped_pred + EfficientNet_clipped_pred)/3","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Take a loot at first ten test images prediction result","metadata":{}},{"cell_type":"code","source":"test_image_paths = [os.path.join(PATH, filename) for filename in df_test.filename[:10]]\nfig,ax = plt.subplots(nrows=2,ncols=5,figsize=(25,10))\nfor idx,path in enumerate(test_image_paths):\n    img = Image.open(path)\n    #img = img.resize((IMAGE_WIDTH,IMAGE_HEIGHT),Image.ANTIALIAS)\n    img_arr = np.asarray(img)\n    ax[divmod(idx,5)[0],divmod(idx,5)[1]].imshow(img_arr)\n    #ax[divmod(idx,5)[0],divmod(idx,5)[1]].set_title(np.round(ensemble_pred.flatten())[idx])\n    ax[divmod(idx,5)[0],divmod(idx,5)[1]].set_title(np.round(Xception_pred.flatten())[idx])\n    ax[divmod(idx,5)[0],divmod(idx,5)[1]].axis('off')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#df_submit = pd.DataFrame({\"id\":df_test['id'],'fake':pred.flatten()})\n#df_submit['fake'] = np.clip(df_submit['fake'],0.04,0.96)\n#df_submit = pd.DataFrame({\"id\":df_test['id'],'fake':Resnet_pred.flatten()})\ndf_submit = pd.DataFrame({\"id\":df_test['id'],'fake':ensemble_pred.flatten()})\n#df_submit = pd.DataFrame({\"id\":df_test['id'],'fake': clipped_ensemble_pred.flatten()})\ndf_submit.to_csv(\"submision.csv\",index = False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.min(df_submit['fake']),np.max(df_submit['fake'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submit.head(20)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}