# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load


import keras
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Model, Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
from keras.optimizers import RMSprop
from keras.applications.resnet50 import ResNet50, preprocess_input

import pandas as pd
import numpy as np


#initialize the CNN by creating an object
nasnet = keras.applications.NASNetLarge(include_top=True, weights='imagenet')


x=nasnet.layers[-2].output
predict=Dense(5,activation='sigmoid')(x)



model = Model(inputs=nasnet.input, outputs=predict)

for l in model.layers[:-5]:
    #print(l)
    l.trainable = False


# view the structure of the model
model.summary()

model.compile(loss='categorical_crossentropy', optimizer=optimizers.Adam(lr=1e-4), metrics=['accuracy'])



#fitting
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import pandas as pd
import numpy as np
import io

model = Sequential()
model.add(Conv2D(32, (5,5),padding = 'Same', activation ='relu', input_shape = (331,331,3)))
model.add(Conv2D(32, (5,5),padding = 'Same', activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3,3),padding = 'Same', activation ='relu'))
model.add(Conv2D(64, (3,3),padding = 'Same', activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation = "relu"))
model.add(Dropout(0.1))
model.add(Dense(5, activation = "sigmoid"))
model.compile(loss='categorical_crossentropy', optimizer='SGD', metrics=['accuracy'])
model.summary()



train_df=pd.read_csv('../input/cassava-leaf-disease-classification/train.csv', dtype=str)
data_dir='../input/cassava-leaf-disease-classification/train_images'
train_datagen=ImageDataGenerator(rescale=1./255.,
                           shear_range = 0.2,
                           zoom_range = 0.2,
                           horizontal_flip = True,
                           validation_split=0.25)

from sklearn.model_selection import StratifiedKFold

train_df['Kfold']=-1

train_df.head()

train_df=train_df.sample(frac=1).reset_index(drop=True)

train_df.tail()

y=train_df['label']

kf=StratifiedKFold(n_splits=5)

for f,(t_,v_) in enumerate(kf.split(X=train_df,y=y)):

    train_df.loc[v_,'Kfold']=f

train_df.head()

train=train_df[train_df['Kfold']!=4]

valid=train_df[train_df['Kfold']==4]

valid.tail()

valid['label'].value_counts()

train_generator=train_datagen.flow_from_dataframe(dataframe=train_df,
                                            
                                            directory=data_dir,
                                            x_col='image_id',
                                            y_col='label',
                                            subset="training",
                                            batch_size=128,
                                            validate_filenames=False,
                                            seed=42,
                                            shuffle=True,
                                            class_mode="categorical",
                                            target_size=(331,331))

valid_generator=train_datagen.flow_from_dataframe(dataframe=train_df,
                                            
                                            directory=data_dir,
                                            x_col='image_id',
                                            y_col='label',
                                            subset="validation",
                                            validate_filenames=False,
                                            batch_size=128,
                                            seed=42,
                                            shuffle=True,
                                            class_mode="categorical",
                                            target_size=(331,331))

test_datagen=ImageDataGenerator(rescale=1./255.)
test_generator=test_datagen.flow_from_directory(
                                                
                                                directory="../input/cassava-leaf-disease-classification/"
                                                
                                                ,batch_size=128,
                                                seed=42,
                                                shuffle=False,
                                                
                                                classes=['test_images'],
                                                target_size=(331,331))

results = model.fit_generator(generator = train_generator, validation_data = valid_generator, epochs = 20)

from keras_unet.utils import plot_segm_history
plot_segm_history(results, metrics = ['accuracy','val_accuracy'], losses=['loss', 'val_loss'])            

model.save_weights('cassava.h5')
model.load_weights('cassava.h5')
model.evaluate_generator(generator=valid_generator,
steps=None, verbose=1)


pred=model.predict_generator(test_generator,
steps=None,
verbose=1)

predicted_class_indices=np.argmax(pred,axis=1)


labels = (train_generator.class_indices)
labels = dict((v,k) for k,v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]

filenames=test_generator.filenames
results=pd.DataFrame({"Filename":filenames,
                      "Predictions":predictions})
results.to_csv("results.csv",index=False)

df= pd.read_csv('./results.csv')
df





# 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" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session