image_output_11.png image_output_24.png image_output_46.png image_output_25.png image_output_47.png image_output_17.png image_output_30.png image_output_14.png image_output_39.png image_output_28.png image_output_23.png image_output_34.png image_output_13.png image_output_40.png image_output_5.png image_output_48.png image_output_18.png image_output_21.png image_output_7.png image_output_31.png image_output_20.png image_output_32.png image_output_4.png image_output_42.png image_output_35.png image_output_41.png image_output_36.png image_output_8.png image_output_37.png image_output_16.png image_output_27.png image_output_6.png image_output_45.png image_output_12.png image_output_22.png image_output_3.png image_output_29.png image_output_44.png image_output_43.png image_output_2.png image_output_1.png image_output_10.png image_output_33.png image_output_50.png image_output_15.png image_output_49.png image_output_9.png image_output_19.png image_output_38.png image_output_26.png
from tensorflow.keras.applications.vgg16 import VGG16

from tensorflow.keras.backend import clear_session

from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

from tensorflow.keras.layers import Convolution2D,MaxPooling2D, Dense, Flatten, InputLayer

from tensorflow.keras.models import Sequential, Model, load_model

from tensorflow.keras.optimizers import SGD

from tensorflow.keras.preprocessing.image import ImageDataGenerator

import matplotlib.pyplot as plt

import numpy as np

import pandas as pd

import zipfile

import zipfile
input_path = '/kaggle/input/dogs-vs-cats'
work_path = '/kaggle/working/data'
train_path = os.path.join(input_path, 'train.zip')
test_path = os.path.join(input_path, 'test1.zip')
with zipfile.ZipFile(train_path, 'r') as zip_ref:
    zip_ref.extractall(work_path)
with zipfile.ZipFile(test_path, 'r') as zip_ref:
    zip_ref.extractall(work_path)

data_dir = work_path
train_dir = data_dir + '/train'
test_dir = data_dir + '/test1'

df = pd.DataFrame()
fnames = os.listdir(train_dir)
class_name = []
for name in fnames:
    class_name.append(name.split('.')[0])
data = {'filename': fnames, 'class': class_name}
df = pd.DataFrame(data)
df = df.sample(frac=1)
train_datagen = ImageDataGenerator(rescale=1 / 255, rotation_range=20, shear_range=0.2, width_shift_range=0.2, height_shift_range=0.2, horizontal_flip=True, zoom_range=0.2)
valid_datagen = ImageDataGenerator(rescale=1 / 255)
idx = int(0.8 * len(df))
train_df = df.iloc[:idx]
valid_df = df.iloc[idx:]
target = (224, 224)
train_set = train_datagen.flow_from_dataframe(train_df, directory=train_dir, shuffle=True, target_size=target, batch_size=64, class_mode='binary')
valid_set = valid_datagen.flow_from_dataframe(valid_df, directory=train_dir, shuffle=False, target_size=target, batch_size=32, class_mode='binary')

clear_session()
model = Sequential([InputLayer(input_shape=target + (3,)), Convolution2D(16, 3, activation='relu'), MaxPooling2D(2), Convolution2D(32, 3, activation='relu'), MaxPooling2D(2), Convolution2D(64, 3, activation='relu'), MaxPooling2D(2), Flatten(), Dense(512, activation='relu'), Dense(1, activation='sigmoid')])
model.summary()
opt = SGD(learning_rate=0.05, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['acc'])
model.optimizer.get_config()

clear_session()
model = VGG16(include_top=False, input_shape=target + (3,))
for layer in model.layers:
    layer.trainable = False
flat1 = Flatten()(model.layers[-1].output)
class1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)
output = Dense(1, activation='sigmoid')(class1)
model = Model(inputs=model.inputs, outputs=output)
model.summary()
opt = SGD(learning_rate=0.001, momentum=0.9)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['acc'])
model.optimizer.get_config()

checkpoint = ModelCheckpoint('temp_model.h5', monitor='val_acc', verbose=1, save_best_only=True, save_weights_only=False, mode='auto')
early = EarlyStopping(monitor='val_acc', min_delta=0, patience=10, verbose=1, mode='auto')
history = model.fit(train_set, validation_data=valid_set, steps_per_epoch=train_set.n // train_set.batch_size, validation_steps=valid_set.n // valid_set.batch_size, epochs=50, callbacks=[checkpoint, early])

legend = ['train', 'validation']

model.save('my_model-3_block-aug-50_epoch.h5')

model = load_model('temp_model.h5')

layer_outputs = []
for layer in model.layers:
    if 'conv' not in layer.name:
        continue
    layer_outputs.append(layer.output)
activation_model = Model(inputs=model.input, outputs=layer_outputs)

def preprocess(img):
    img = cv2.resize(img,target)
    img = img/255
    return np.array(img)
    
def predict(img):
    img = preprocess(img)
    img = img.reshape((1,)+img.shape)
    probability = model.predict(img)
    return probability

def getLabel(probability):
    if probability<0.5:
        probability=0
    else:
        probability=1
    return list(train_set.class_indices)[probability]

def visualize(img):
    img = preprocess(img)
    img = img.reshape((1,)+img.shape)
    fmaps = activation_model.predict(img)

    for i in range(len(fmaps)):
        activation = fmaps[i]
        
        fig = plt.figure(figsize=(20,15))
        fig.suptitle(layer_outputs[i].name)
        
        for j in range(min(8*8,activation.shape[-1])):
            plt.subplot(8,8,j+1)
            plt.imshow(activation[0,:,:,j],cmap='gray')
    plt.show()

WIN_SIZES=[]
for i in range(100,260,20):
    WIN_SIZES.append(i)
    
def get_box(img,step=20,win_sizes=WIN_SIZES):
    best_box = None
    best_distance = 1
    raw_prob = predict(img)
    if (raw_prob<0.5):
        raw_prob=0
    else:
        raw_prob=1
        
    for win in win_sizes:
        print("Run with window size:",str(win))
        for top in range(0,img.shape[0]-win+1,step):
            for left in range(0,img.shape[1]-win+1,step):
                box = (left,top,left+win,top+win)
                crop = img[box[1]:box[3],box[0]:box[2]]
                prob = predict(crop)
                distance = abs(raw_prob-prob)
                if (distance<best_distance):
                    best_box = box
                    best_distance = distance
    return (best_box, best_distance)

test_fnames = os.listdir(test_dir)
random.shuffle(test_fnames)
result = []
nPic = 50
for fnames in test_fnames:
    pred_path = os.path.join(test_dir, fnames)
    img = cv2.imread(pred_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    title = getLabel(predict(img))
    plt.imshow(img)
    plt.title(title)
    plt.show()
    nPic -= 1
    if nPic == 0:
        break