# -*- coding: utf-8 -*-
"""Untitled2.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1pB_nkpzCVt-Q1VkEnjyaLYud1YxlF2sF
"""

import keras
import tensorflow
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten,GlobalAveragePooling2D
from keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.utils import to_categorical
from keras.preprocessing import image
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from tqdm import tqdm
from keras.layers.advanced_activations import PReLU
from tensorflow.keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator

"""導入需要之函數

"""

!pip install PyDrive

import os
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials
from google.colab import drive
drive.mount('/content/drive')

auth.authenticate_user() 
gauth = GoogleAuth() 
gauth.credentials = GoogleCredentials.get_application_default() 
drive = GoogleDrive(gauth)


download = drive.CreateFile({'id': '1ynnplS1gFJJPVlH6PorejahecdciSd4W'})
download.GetContentFile('2021VRDL_HW1_datasets.zip')
!unzip 2021VRDL_HW1_datasets.zip

"""連結google雲端，並解壓縮zip檔"""

def show_train_history(train_history, train, validation):
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[validation])
    plt.title('Train history')
    plt.ylabel(train)
    plt.xlabel('Epoch')
    legendLoc = 'lower right' if(train=='accuracy') else 'upper right'
    plt.legend(['train', 'validation'], loc=legendLoc)
    plt.show()

"""先定義之後顯示acc loss之函數"""

train = pd.read_csv('training_labels.txt', sep=" ", header=None)
train.columns = ["id", "label"]
print(train)

download = drive.CreateFile({'id': '1IEWAQeheDcENjN0JTB8B0DyV_Ab_Y8j9?usp=sharing'})
# We have grayscale images, so while loading the images we will keep grayscale=True, if you have RGB images, you should set grayscale as False
train_image = []
for i in tqdm(range(train.shape[0])):
    img = image.load_img( '/content/drive/MyDrive/training_images/' + str(train['id'][i]) , target_size = (250,250,3)) #grayscale=True   #224
    img = image.img_to_array(img)
    img = img/255
    train_image.append(img)

X = np.array(train_image)

"""
將trainlabel.txt讀取，並分成id及label以便讀取檔案並標示類別
將id 裡的內容在for迴圈中使用load_img讀取
並在最後以(250,250,3)的方式記成array加入X中
"""

y = train['label'].values


integer_mapping = {x: i for i,x in enumerate(y)}
vec = [integer_mapping[word] for word in y]
y = np.array(y)
label_encoder = LabelEncoder()
vec = label_encoder.fit_transform(y)

y = to_categorical(vec)


X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 1, test_size = 0.2)

"""將y中的標籤以to_categorical的方式記成等等使用model.fit的形式
並在此時切割測試集和驗證集
"""

from tensorflow.keras.applications import ResNet50V2
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

"""導入model的函數"""

resnet = ResNet50V2(include_top=False, pooling="avg")
resnet.trainable = False

"""用ResNet50V2建構等等要使用的model"""

model = Sequential()
model.add(resnet)
model.add(Dense(200, activation='softmax'))
model.compile(loss='categorical_crossentropy', 
              optimizer='adam', 
              metrics=['accuracy'])
model.summary()

"""建構model並顯示其layer以便在錯誤時方便觀察"""

train_history=model.fit(X_train, y_train, batch_size = 8, epochs=20,verbose=1,  validation_data = (X_test, y_test)) #16,10

show_train_history(train_history, 'accuracy', 'val_accuracy')
show_train_history(train_history, 'loss', 'val_loss')

"""以圖表方式呈現訓練結果

"""

test = pd.read_csv('testing_img_order.txt', header=None)
test.columns = ["id"]

test_image = []
for i in tqdm(range(test.shape[0])):
    img = image.load_img('/content/drive/MyDrive/testing_images/' + str(test['id'][i]), target_size=(250,250,3)) #224
    img = image.img_to_array(img)
    img = img/255
    test_image.append(img)
test = np.array(test_image)

"""讀取 testing_img_order.txt 並記下id順序
並依照順序讀取內容
"""

predict = model.predict(test) 
classes_x = np.argmax(predict,axis=1)


vec = label_encoder.inverse_transform(classes_x)

"""將預測結果轉回原本應輸入之XXX.YYYYY形式"""

test = pd.read_csv('testing_img_order.txt', header=None)
test.columns = ["id"]
test['label'] = ''
for i in tqdm(range(test.shape[0])):
  #test['label'][i] = int(classes_x[i])
  test['label'][i] = vec[i]


test.to_csv('answer.txt', sep=" " ,header=None, index=None)
!cp answer.txt "drive/My Drive/"

"""
將檔案輸出在雲端硬碟中
等待下載並壓縮
"""
