{"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":"markdown","source":"베이스코드와 다른점 : 현재 베이스코드 라인이 공유되지 않아서, 제가 구현한 방법을 소개하겠습니다.\n\n1. 이미지 사이즈가 매우 커서 메모리 out이 발생하였음 -> opencv를 이용하여 32*32로 resize 진행. (보간법은 디폴트값 사용) 이 때, opencv로 열면 BGR로 열리므로, RGB로 변환해주었음.\n\n2. 이후 파일경로에서 레이블을 추출하고, 사전학습모델 실험을 위하여 (227,227)로 변환 및 정규화 진행\n\n3. SGD Optimizer와 스케쥴러 사용\n\n(다른 사전학습 모델을 실험할 수 있도록 코드를 작성하였습니다. 추후 활용하시면 좋을 듯 합니다.)\n\n\n===========================================================================\n\n베이스코드가 올라와서 수정합니다.\n\n베이스코드와 다른점\n\n1. BCELoss를 사용하지 않고, CrossEntropyLoss를 사용하였습니다.\n2. Optimizer를 SGD를 사용하였습니다.\n3. 사전학습모델로 resnet18을 사용하였습니다.","metadata":{}},{"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\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        pass\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","execution":{"iopub.status.busy":"2022-11-14T17:55:03.763240Z","iopub.execute_input":"2022-11-14T17:55:03.763757Z","iopub.status.idle":"2022-11-14T17:55:08.713832Z","shell.execute_reply.started":"2022-11-14T17:55:03.763648Z","shell.execute_reply":"2022-11-14T17:55:08.712935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#랜덤시드고정\n\nimport random\nimport torch\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\nprint(device)\nseed = 42\nrandom.seed(seed)\nnp.random.seed(seed)\ntorch.manual_seed(seed)\nif torch.cuda.is_available():\n    torch.cuda.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\ntorch.backends.cudnn.benchmark = False\ntorch.backends.cudnn.deterministic = True ","metadata":{"execution":{"iopub.status.busy":"2022-11-14T17:55:08.716256Z","iopub.execute_input":"2022-11-14T17:55:08.716939Z","iopub.status.idle":"2022-11-14T17:55:10.403918Z","shell.execute_reply.started":"2022-11-14T17:55:08.716899Z","shell.execute_reply":"2022-11-14T17:55:10.402939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#필요한 모듈 호출\nimport torchvision\nimport torchvision.models as models\nimport torchvision.transforms as transforms\n\nfrom torch.utils.data import DataLoader,TensorDataset, Dataset\n\nfrom PIL import Image\n\nfrom glob import glob\nfrom os.path import join\n\nimport cv2\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2022-11-14T17:55:10.405521Z","iopub.execute_input":"2022-11-14T17:55:10.406013Z","iopub.status.idle":"2022-11-14T17:55:10.749523Z","shell.execute_reply.started":"2022-11-14T17:55:10.405965Z","shell.execute_reply":"2022-11-14T17:55:10.747246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# glob과 join으로 영상 경로를 연결하여 저장한다.\ntrain_path = \"../input/2022-ai-tp-18011637/Train_Images/Train_Dataset\"\ntest_path = \"../input/2022-ai-tp-18011637/Test_Images/Test\"\ntrain = glob(join(train_path,'*','*'))\ntest = glob(join(test_path,'*'))\n\n# 테스트 데이터가 0부터 정렬된 것이 아니라 순서가 뒤죽박죽이므로\n# 순서를 맞춰서 test 데이터를 받아야 한다.\ntest_sort = []\nfor i in range(len(test)):\n    test_sort.append(test_path+'/'+str(i)+'.jpg')","metadata":{"execution":{"iopub.status.busy":"2022-11-14T17:55:10.752491Z","iopub.execute_input":"2022-11-14T17:55:10.752866Z","iopub.status.idle":"2022-11-14T17:55:10.851459Z","shell.execute_reply.started":"2022-11-14T17:55:10.752830Z","shell.execute_reply":"2022-11-14T17:55:10.846108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample = pd.read_csv(\"../input/2022-ai-tp-18011637/submit.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-11-14T17:55:10.853233Z","iopub.execute_input":"2022-11-14T17:55:10.853588Z","iopub.status.idle":"2022-11-14T17:55:10.880895Z","shell.execute_reply.started":"2022-11-14T17:55:10.853541Z","shell.execute_reply":"2022-11-14T17:55:10.879826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 79\nnb_epoch = 1\nlr = 1e-3","metadata":{"execution":{"iopub.status.busy":"2022-11-14T17:55:10.884911Z","iopub.execute_input":"2022-11-14T17:55:10.887458Z","iopub.status.idle":"2022-11-14T17:55:10.893341Z","shell.execute_reply.started":"2022-11-14T17:55:10.887419Z","shell.execute_reply":"2022-11-14T17:55:10.892276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"size_check = cv2.imread('../input/2022-ai-tp-18011637/Train_Images/Train_Dataset/fish_trap/bundle of ropes_circular fish trap_043_00262.jpg')\nsize_check.shape","metadata":{"execution":{"iopub.status.busy":"2022-11-14T17:55:10.896584Z","iopub.execute_input":"2022-11-14T17:55:10.898606Z","iopub.status.idle":"2022-11-14T17:55:10.975894Z","shell.execute_reply.started":"2022-11-14T17:55:10.898570Z","shell.execute_reply":"2022-11-14T17:55:10.975033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train이미지와 Test이미지를 벡터로 저장한다.\n# BGR to RGB (opencv로 열면 BGR로 열린다.)\ntrain_img=[]\nfor idx in tqdm(train):\n    img = cv2.imread(idx)\n    img = cv2.resize(img,(32,32))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = np.array(img)\n    train_img.append(img)\n    \ntest_img=[]\nfor idx in tqdm(test_sort):\n    img = cv2.imread(idx)\n    img = cv2.resize(img,(32,32))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = np.array(img)\n    test_img.append(img)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T17:55:10.980042Z","iopub.execute_input":"2022-11-14T17:55:10.980758Z","iopub.status.idle":"2022-11-14T18:00:58.001215Z","shell.execute_reply.started":"2022-11-14T17:55:10.980721Z","shell.execute_reply":"2022-11-14T18:00:58.000060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_img[0].shape","metadata":{"execution":{"iopub.status.busy":"2022-11-14T18:00:58.002864Z","iopub.execute_input":"2022-11-14T18:00:58.003263Z","iopub.status.idle":"2022-11-14T18:00:58.009956Z","shell.execute_reply.started":"2022-11-14T18:00:58.003223Z","shell.execute_reply":"2022-11-14T18:00:58.008926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kk = '../input/2022-ai-tp-18011637/Train_Images/Train_Dataset/remainer/bundle of ropes_002_00012.jpg'\nkk.split('/')[-2]","metadata":{"execution":{"iopub.status.busy":"2022-11-14T18:00:58.013428Z","iopub.execute_input":"2022-11-14T18:00:58.014050Z","iopub.status.idle":"2022-11-14T18:00:58.021680Z","shell.execute_reply.started":"2022-11-14T18:00:58.014014Z","shell.execute_reply":"2022-11-14T18:00:58.020675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class EJ_Loader(torch.utils.data.Dataset):\n    def __init__(self,data,save_img,flag=\"\",transform=None):\n        self.transform = transform\n        self.CIFAR = data\n        self.flag = flag\n        self.images = save_img\n        \n        if self.flag == \"train\":\n            label , image = [],[]\n            \n            for img in self.CIFAR:\n                # 파일 경로에서 '/'를 기준으로 분리하고 레이블만 떼온다.\n                if img.split('/')[-2] == 'fish_trap':\n                    data_label = 1\n                else:\n                    data_label=0\n                label.append(data_label)\n                            \n            self.labels = np.array(label)\n    def __len__(self):\n        return len(self.images)\n    \n    def __getitem__(self,idx):\n        \n        if self.flag == \"train\":\n            label = self.labels[idx]\n            image = self.images[idx]\n            \n            pil_image = Image.fromarray(np.uint8(image))\n            image = self.transform(pil_image)\n            \n            return image,torch.from_numpy(np.array(label))\n        \n        else:\n            image = self.images[idx]\n            \n            pil_image = Image.fromarray(np.uint8(image))\n            image = self.transform(pil_image)\n            \n            return image\n        \ntransform = transforms.Compose(\n    [transforms.Resize((227,227)),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5,),(0.5,))])\n\ntrain_dataset = EJ_Loader(train,train_img,flag=\"train\",transform=transform)\ntest_dataset = EJ_Loader(test,test_img,flag=\"test\",transform=transform)\n\ntrain_loader = DataLoader(train_dataset,batch_size=batch_size,shuffle=True,num_workers=2)\ntest_loader = DataLoader(test_dataset,batch_size=batch_size,shuffle=False,num_workers=2)      ","metadata":{"execution":{"iopub.status.busy":"2022-11-14T18:00:58.023585Z","iopub.execute_input":"2022-11-14T18:00:58.024173Z","iopub.status.idle":"2022-11-14T18:00:58.042000Z","shell.execute_reply.started":"2022-11-14T18:00:58.024129Z","shell.execute_reply":"2022-11-14T18:00:58.041018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def pretrained_model(method):\n    if method == \"resnet\":\n        model = models.resnet18(pretrained=True)\n        model.fc = torch.nn.Linear(512,2)\n    elif method == \"googlenet\":\n        model = models.googlenet(pretrained=True)\n        model.fc = torch.nn.Linear(1024,2)\n    elif method == \"vgg\":\n        model = models.vgg16(pretrained=True)\n        model.classifier[6] = torch.nn.Linear(4096,2)\n    else:\n        raise ValueError(\"Check method!\")\n        \n    return model","metadata":{"execution":{"iopub.status.busy":"2022-11-14T18:00:58.044600Z","iopub.execute_input":"2022-11-14T18:00:58.045049Z","iopub.status.idle":"2022-11-14T18:00:58.055591Z","shell.execute_reply.started":"2022-11-14T18:00:58.045004Z","shell.execute_reply":"2022-11-14T18:00:58.054690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pre_model = ['googlenet','resnet','vgg']\n\npre_model = ['resnet']\n\ntotal_batch = len(train_loader)\n\nfor method in pre_model:\n    model = pretrained_model(method)\n    print(method)\n    model = model.to(device)\n    model.train()\n    \n    loss = torch.nn.CrossEntropyLoss().to(device)\n    \n    optimizer = torch.optim.SGD(model.parameters(),lr=1e-3,weight_decay=1e-5,momentum=0.9)\n    \n    scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer=optimizer,\n                                                 lr_lambda=lambda epoch: 0.95 ** epoch,\n                                                 last_epoch = -1,\n                                                 verbose = False)\n    \n    for epoch in tqdm(range(1+nb_epoch)):\n        avg_cost = 0\n        for batch_idx , samples in enumerate(train_loader):\n            \n            X_train_batch , Y_train_batch = samples\n            \n            X_train_batch = X_train_batch.to(device)\n            Y_train_batch = Y_train_batch.to(device)\n            \n            optimizer.zero_grad()\n            \n            H = model(X_train_batch)\n            \n            cost = loss(H,Y_train_batch)\n            \n            cost.backward()\n            \n            optimizer.step()\n            \n            avg_cost += cost.item()/total_batch\n        \n        scheduler.step()\n        \n        print(\"Epoch :\",epoch,\"Cost :\",avg_cost)\n        \n    with torch.no_grad():\n        model.eval()\n        Y_test = []\n        for batch_idx , samples in enumerate(test_loader):\n            X_test_batch = samples\n            \n            X_test_batch = X_test_batch.to(device)\n            \n            result = model(X_test_batch)\n            \n            predict = torch.argmax(result,dim=1)\n            predict = predict.cpu().detach().numpy()\n            \n            for value in predict:\n                Y_test.append(value)\n                \n        sample['Target'] = Y_test\n        sample.to_csv(method+\".csv\",mode='w',index=False)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T18:03:47.086155Z","iopub.execute_input":"2022-11-14T18:03:47.086530Z","iopub.status.idle":"2022-11-14T18:04:56.316994Z","shell.execute_reply.started":"2022-11-14T18:03:47.086498Z","shell.execute_reply":"2022-11-14T18:04:56.315846Z"},"trusted":true},"execution_count":null,"outputs":[]}]}