{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n'''\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n'''\n# 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\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#load train.csv\n\ntrain_df = pd.read_csv('../input/plant-pathology-2021-fgvc8/train.csv')\ntrain_df.head(5)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#문자 라벨을 숫자 라벨로 변환\n#make string label to numeric label\nfrom sklearn.preprocessing import LabelEncoder\n\nlabel = LabelEncoder()\nlabel.fit(train_df['labels'])\ntrain_df['label_id'] = label.transform(train_df['labels'])\nlabel_dic = dict(sorted(train_df[['label_id', 'labels']].values.tolist())) #save for submission\nprint(label_dic)\nclasses = len(train_df['labels'].value_counts()) #12\n\ndel train_df['labels'] #we don't need this Series anymore\n\nimage_names = np.array(train_df['image'].values)\nimage_labels = np.array(train_df['label_id'].values)\n\nprint(image_names.shape) #18632","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom glob import glob\nimport cv2, torch\nimport torchvision.transforms as transforms\nfrom tqdm.notebook import tqdm\nfrom torch.utils.data import Dataset, DataLoader\n\ndevice = torch.device('cuda' if torch.cuda.is_available else 'cpu')\n\ntransform = transforms.Compose(\n    [transforms.ToTensor(),\n    transforms.Resize((224, 224)),\n    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n\n#커스텀 데이터셋 설정\n#dataset and dataloader for train\nclass dataset(Dataset) :\n    def __init__(self, image_list, image_names, image_labels, transform, device) :\n        self.image_list = image_list\n        self.image_names = image_names\n        self.image_labels = image_labels\n        self.transform = transform\n    \n    def __len__(self) :\n        return len(self.image_list)\n    \n    def __getitem__(self, index) :\n        x = cv2.imread(self.image_list[index])\n        x = self.transform(x).to(device)\n        \n        image_name = image_list[index][49:]\n        y = self.image_labels[np.where(image_names == image_name)]\n        y = torch.LongTensor([y,]).to(device)\n        \n        return x, y\n\n\n#load train_images\nimage_list = glob('../input/plant-pathology-2021-fgvc8/train_images/*.jpg')\n\n\ntrain_data = dataset(image_list, image_names, image_labels, transform, device)\ntrain_data = DataLoader(train_data, batch_size = 32, shuffle = True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#! pip install torchsummaryX","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn\nfrom torch.optim import Adam\nfrom torchvision.models import resnet34\n#from torchsummaryX import summary\n\nclass resnet(nn.Module) :\n    def __init__(self, output) :\n        super().__init__()\n        self.model = resnet34(pretrained=False) #use ResNet\n        self.model.fc = torch.nn.Linear(512, output) #change the last FC layer\n    def forward(self, x) :\n        output = self.model(x)\n        \n        return output\n\nmodel = resnet(classes).to(device)\ncriterion = nn.CrossEntropyLoss().to(device)\noptimizer = torch.optim.Adam(model.parameters(), lr = 0.01)\n\n#summary(model, torch.rand((1, 3, 224, 224)).float().to(device))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#load model that I trained on local\nmodel.load_state_dict(torch.load('../input/modelpt/model.pt'))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\nn_epoch = 10\ntorch.cuda.empty_cache()\n\nmodel.train()\nprint('batchs : ', len(train_data))\n\nfor epoch in range(n_epoch) :\n    epoch_loss = 0\n    epoch_acc = 0\n    for i, (x, y) in tqdm(enumerate(train_data)) :\n        y = y.reshape(-1)\n        \n        predict = model(x)\n        loss = criterion(predict, y)\n        \n        epoch_loss += loss / len(train_data)\n        correct_prediction = torch.argmax(predict, 1) == y\n        correct_prediction = correct_prediction.sum()\n        epoch_acc += correct_prediction\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n    epoch_acc = epoch_acc / (32 * len(train_data))\n    print('Epoch : {}/{},   loss : {:.5f},    acc : {:.5f}'.format(epoch+1, n_epoch, epoch_loss, epoch_acc))\n    \n    if epoch_acc > 0.98 : break\n        \n#계속 죽으니까 10번씩 돌리고 저장\n#save model to continue learning\ntorch.save(model.state_dict(), 'model.pt')\n'''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_image_list = glob('../input/plant-pathology-2021-fgvc8/test_images/*.jpg')\n\n\n#TEN_CROP\nvalid_transform = transforms.Compose([\n      transforms.ToTensor(),\n      transforms.Resize(256),\n      transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),\n      transforms.TenCrop([224, 224])])\n\nmodel.eval()\npredict_list = []\nimage_name_list = []\nfor i, image in tqdm(enumerate(valid_image_list)) :\n    image_name = image[48:]\n    \n    img = cv2.imread(image)\n    img = valid_transform(img)\n    \n    result_list = torch.FloatTensor(np.zeros((classes))).to(device)\n    for j, x in enumerate(img) :\n        x = x.to(device)\n        x = x.reshape(-1, 3, 224, 224)\n        predict = model(x)\n        predict = predict.reshape(-1)\n        result_list += predict\n    \n    predict_list.append(torch.argmax(result_list).item())\n    image_name_list.append(image_name)\n    \npredict_list = np.array(predict_list)\nimage_name_list = np.array(image_name_list)\nprint(image_name_list)\n\nsubmission_df = pd.DataFrame()\nsubmission_df['image'] = image_name_list\nsubmission_df['label_id'] = predict_list\nsubmission_df['labels'] = submission_df['label_id'].map(label_dic)\ndel submission_df['label_id']\nsubmission_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.to_csv(\"submission.csv\", index = False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}