{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"! git clone https://github.com/dwgoon/jpegio\n# Once downloaded install the package\n!pip install jpegio/.\nimport jpegio as jpio","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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#for 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 5GB 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","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import jpegio as jpio\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nfrom torchvision import transforms,datasets\n\nfrom tqdm.notebook import tqdm\nimport sys\n\nREBUILD_DATA= True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def JPEGdecompressYCbCr(jpegStruct):\n    \n    nb_colors=len(jpegStruct.coef_arrays)           #nb_colors=3=number of channels\n    \n    [Col,Row] = np.meshgrid( range(8) , range(8) )\n    T = 0.5 * np.cos(np.pi * (2*Col + 1) * Row / (2 * 8))\n    T[0,:] = T[0,:] / np.sqrt(2)    #T is of shape [8 , 8] \n    \n    sz = np.array(jpegStruct.coef_arrays[0].shape)    #shape of coef_arrays[0] is 512,512. So sz is 2D list --512 512\n    imDecompressYCbCr = np.zeros([sz[0], sz[1], nb_colors]);    #imgdecompressYCbCr is a 3D array of zeros of size 512,512,3\n    szDct = (sz/8).astype('int')     # 2D list --- sz/8 ---- [64 64]\n\n    \n    \n    \n    for ColorChannel in range(nb_colors):\n        tmpPixels = np.zeros(sz) #zero 2D vector of size (512, 512)\n    \n        DCTcoefs = jpegStruct.coef_arrays[ColorChannel]; #DCT Co-efficients of the image's color channel...size [512,512]\n        if ColorChannel==0:\n            QM = jpegStruct.quant_tables[ColorChannel];\n        else:\n            QM = jpegStruct.quant_tables[1];     #quantization table maybe\n        \n        for idxRow in range(szDct[0]):     #range---64\n            for idxCol in range(szDct[1]):  #range----64\n                D = DCTcoefs[idxRow*8:(idxRow+1)*8 , idxCol*8:(idxCol+1)*8]     #size of D [8, 8]- D takes 8*8 blocks from DCTcoefs\n                tmpPixels[idxRow*8:(idxRow+1)*8 , idxCol*8:(idxCol+1)*8] = np.dot( np.transpose(T) , np.dot( QM * D , T ) )\n        imDecompressYCbCr[:,:,ColorChannel] = tmpPixels;\n    return imDecompressYCbCr","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\ndevice","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BASE_PATH = \"/kaggle/input/alaska2-image-steganalysis\"\ntrain_imageids = pd.Series(os.listdir(BASE_PATH + '/Cover')).sort_values(ascending=True).reset_index(drop=True)\ntest_imageids = pd.Series(os.listdir(BASE_PATH + '/Test')).sort_values(ascending=True).reset_index(drop=True)\nsub = pd.read_csv('/kaggle/input/alaska2-image-steganalysis/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(test_imageids.head(3))\ntrain_imageids.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://www.kaggle.com/xhlulu/alaska2-efficientnet-on-tpus\ndef append_path(pre):\n    return np.vectorize(lambda file: os.path.join(BASE_PATH, pre, file))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_filenames = np.array(os.listdir(\"/kaggle/input/alaska2-image-steganalysis/Cover/\"))\nprint(len(train_filenames))\ntrain_filenames","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://www.kaggle.com/xhlulu/alaska2-efficientnet-on-tpus\nnp.random.seed(0)\npositives = train_filenames.copy()\nnegatives = train_filenames.copy()\nnp.random.shuffle(positives)\nnp.random.shuffle(negatives)\n\njmipod = append_path('JMiPOD')(positives[:10000])\njuniward = append_path('JUNIWARD')(positives[10000:20000])\nuerd = append_path('UERD')(positives[20000:30000])\n\npos_paths = np.concatenate([jmipod, juniward, uerd])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_paths = append_path('Test')(sub.Id.values)\nneg_paths = append_path('Cover')(negatives[:30000])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_paths = np.concatenate([pos_paths, neg_paths])\ntrain_labels = np.array([1] * len(pos_paths) + [0] * len(neg_paths))\nprint(train_paths)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(test_paths)\ntest_labels = np.array( [0] * len(test_paths))\nprint(len(test_paths))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom sklearn.model_selection import StratifiedKFold","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"n_splits = 10 # Number of K-fold Splits\n\nsplits = list(StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=4590).split(train_paths, train_labels))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://www.kaggle.com/xhlulu/alaska2-efficientnet-on-tpus\n'''train_paths, valid_paths, train_labels, valid_labels = train_test_split(\n    train_paths, train_labels, test_size=0.15, random_state=2020)'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''l=np.array([train_paths,train_labels])\ntraindataset = pd.DataFrame({ 'images': list(train_paths), 'label': train_labels},columns=['images','label'])\ntestdataset = pd.DataFrame({ 'images': list(test_paths), 'label': test_labels},columns=['images','label'])'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''val_l=np.array([valid_paths,valid_labels])\nvaliddataset=dataset = pd.DataFrame({ 'images': list(valid_paths), 'label': valid_labels},columns=['images','label'])'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''from PIL import Image, ImageFile\nimport scipy                        # for cosine similarity\nfrom scipy import fftpack'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Image preprocessing modules\ntrain_transform = transforms.Compose([\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomVerticalFlip(p=0.5),\n    transforms.Resize(512, 512),\n    transforms.ToTensor()])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_transform=transforms.Compose([\n    transforms.Resize(512, 512),\n    transforms.ToTensor()])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# add image augmen tation\nclass train_images(torch.utils.data.Dataset):\n\n    def __init__(self, csv_file):\n\n        self.data = csv_file\n\n    def __len__(self):\n        return len(self.data)\n\n    def __getitem__(self, idx):\n        #print(idx)\n        img_name =  self.data.loc[idx][0]\n        jpegStruct = jpio.read(img_name)\n        YCbCr_img=JPEGdecompressYCbCr(jpegStruct)\n        #image = Image.open(img_name)\n        label = self.data.loc[idx][1] #torch.tensor(self.data.loc[idx, 'label'])\n       \n\n# ## https://pytorch.org/docs/stable/torchvision/transforms.html\n# transforms.Compose([\n# transforms.CenterCrop(10),\n# transforms.ToTensor(),\n# ])\n        \n#         return {'image': transforms.ToTensor()(image), # ORIG\n        return {'image': YCbCr_img,\n            'label': label\n            }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# add image augmen tation\nclass test_images(torch.utils.data.Dataset):\n\n    def __init__(self, csv_file):\n\n        self.data = csv_file\n\n    def __len__(self):\n        return len(self.data)\n\n    def __getitem__(self, idx):\n        #print(idx)\n        img_name =  self.data.loc[idx][0]\n        jpegStruct = jpio.read(img_name)\n        YCbCr_img=JPEGdecompressYCbCr(jpegStruct)\n        #image = Image.open(img_name)\n       \n\n# ## https://pytorch.org/docs/stable/torchvision/transforms.html\n# transforms.Compose([\n# transforms.CenterCrop(10),\n# transforms.ToTensor(),\n# ])\n        \n#         return {'image': transforms.ToTensor()(image), # ORIG\n        return {'image': YCbCr_img\n   }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''train_dataset = train_images(traindataset)\nvalid_dataset = test_images(validdataset)\nprint(type(train_dataset))\nlen(train_dataset)'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 32\nepochs = 2\nlearning_rate = 0.001","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# For updating learning rate\ndef update_lr(optimizer, lr):    \n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''train_loader = torch.utils.data.DataLoader(train_dataset, batch_size = batch_size, shuffle=True, num_workers=4)\nvalid_loader = torch.utils.data.DataLoader(valid_dataset, batch_size = batch_size, shuffle=True, num_workers=4)'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(os.listdir(\"../input/\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"package_path = '../input/efficientnet/efficientnet-pytorch/EfficientNet-PyTorch/'\nsys.path.append(package_path)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"!pip install --upgrade efficientnet-pytorch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from efficientnet_pytorch import EfficientNet","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_classes = 1\nmodel = (EfficientNet.from_name('efficientnet-b0')).to(device)\nmodel.load_state_dict(torch.load('../input/efficientnet-pytorch/efficientnet-b0-08094119.pth'))\nin_features = model._fc.in_features\nmodel._fc = nn.Linear(in_features, num_classes)\nmodel.cuda()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\n\nprint(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i, (train_idx, valid_idx) in enumerate(splits):\n    valid_preds = []\n    x_train = np.array(train_paths)\n    y_train = np.array(train_labels)   \n    #x_train , y_train = augment(x_train , y_train)\n    \n    x_train_fold = x_train[train_idx.astype(int)]\n    y_train_fold = y_train[train_idx.astype(int)]\n    \n    x_val_fold = x_train[valid_idx.astype(int)]\n    y_val_fold = y_train[valid_idx.astype(int)]\n    \n    \n    traindataset = pd.DataFrame({ 'images': list(x_train_fold), 'label': y_train_fold},columns=['images','label'])\n    validdataset = pd.DataFrame({ 'images': list(x_val_fold), 'label': y_val_fold},columns=['images','label'])\n    traindataset = train_images(traindataset)\n    validdataset = test_images(validdataset)\n    \n    train_loader = torch.utils.data.DataLoader(traindataset, batch_size = batch_size, shuffle=True, num_workers=4)\n    valid_loader = torch.utils.data.DataLoader(validdataset, batch_size = batch_size, shuffle=True, num_workers=4)\n    \n    total_step = len(train_loader)\n    curr_lr = learning_rate\n    \n    for epoch in range(epochs):\n\n        tk0 = tqdm(train_loader, total=int(len(train_loader)))\n        counter = 0\n        epoch_loss = 0\n        for bi, d in enumerate(tk0):\n                inputs = d[\"image\"]\n                labels = d[\"label\"].view(-1, 1)\n                print(inputs.shape)\n\n                inputs = inputs.to(device, dtype=torch.float)\n                labels = labels.to(device, dtype=torch.long)\n                #labels = labels.squeeze(1)\n\n                inputs = inputs.view(-1,3,512,512)\n                #print(inputs.shape)\n\n                # Forward pass\n                outputs = model(inputs)\n                loss  = criterion(outputs,labels)\n\n                # Backward and optimize\n                optimizer.zero_grad()\n                loss.backward()\n                optimizer.step()\n                epoch_loss =epoch_loss + loss.item()\n\n        epoch_loss = epoch_loss / (len(train_loader)/batch_size)\n        print (\"Epoch [{}/{}] Loss: {:.4f}\".format(epoch+1, epochs, epoch_loss))\n\n        # Decay learning rate\n        curr_lr /= 3  \n        update_lr(optimizer, curr_lr)\n        \n        torch.save(model.state_dict(), 'effnet.ckpt')\n        \n        model.eval()\n        with torch.no_grad():\n            correct = 0\n            total = 0\n            tk0 = tqdm(valid_loader, total=int(len(valid_loader)))\n            counter = 0\n            for bi, d in enumerate(tk0):\n                    inputs = d[\"image\"]\n                    labels = d[\"label\"].view(-1, 1)\n\n                    inputs = inputs.to(device, dtype=torch.float)\n                    labels = labels.to(device, dtype=torch.long)\n                    inputs = inputs.view(-1,3,512,512)\n\n                    outputs = model(inputs)\n                    print(outputs.shape)\n                    total += labels.size(0)\n                    correct += (outputs == labels).sum().item()\n                    \n            print(\"correct\",correct)\n            print(\"total\", total)\n            print('Accuracy of the model on the valid images: {} %'.format(100 * correct / total))\n        \n        \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"total_step = len(train_loader)\ncurr_lr = learning_rate\nfor epoch in range(epochs):\n\n    tk0 = tqdm(train_loader, total=int(len(train_loader)))\n    counter = 0\n    epoch_loss = 0\n    for bi, d in enumerate(tk0):\n            inputs = d[\"image\"]\n            labels = d[\"label\"].view(-1, 1)\n    \n            inputs = inputs.to(device, dtype=torch.float)\n            labels = labels.to(device, dtype=torch.long)\n            #labels = labels.squeeze(1)\n        \n            inputs = inputs.view(-1,3,512,512)\n            #print(inputs.shape)\n            \n            # Forward pass\n            outputs = model(inputs)\n            loss  = criterion(outputs, torch.max(labels, 1)[1])\n\n            # Backward and optimize\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n            epoch_loss =epoch_loss + loss.item()\n            \n    epoch_loss = epoch_loss / (len(train_loader)/batch_size)\n    print (\"Epoch [{}/{}] Loss: {:.4f}\".format(epoch+1, epochs, epoch_loss))\n\n    # Decay learning rate\n    curr_lr /= 3  \n    update_lr(optimizer, curr_lr)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.save(model.state_dict(), 'effnet.ckpt')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = torch.load('effnet.ckpt')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.eval()\nwith torch.no_grad():\n    correct = 0\n    total = 0\n    tk0 = tqdm(valid_loader, total=int(len(valid_loader)))\n    counter = 0\n    for bi, d in enumerate(tk0):\n            inputs = d[\"image\"]\n            labels = d[\"label\"].view(-1, 1)\n    \n            inputs = inputs.to(device, dtype=torch.float)\n            labels = labels.to(device, dtype=torch.long)\n            inputs = inputs.view(-1,3,512,512)\n   \n            outputs = model(inputs)\n            _, predicted = torch.max(outputs.data, 1)\n            print(predicted.shape)\n            total += labels.size(0)\n            correct += (predicted[0] == labels).sum().item()\n            for i,val in enumerate(predicted):\n                print(val)\n    print(\"correct\",correct)\n    print(\"total\", total)\n    print('Accuracy of the model on the test images: {} %'.format(100 * correct / total))  ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del train_dataset","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del train_loader","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dataset = test_images(testdataset)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_loader = torch.utils.data.DataLoader(test_dataset,\n                                          batch_size=batch_size,\n                                          num_workers=4,\n                                          shuffle=False,\n                                          drop_last=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.DataFrame({'ImageFileName': list(\n    test_paths)}, columns=['ImageFileName'])\n\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.eval()\n\npreds = []\ntk0 = tqdm(test_loader)\nwith torch.no_grad():\n    for i, im in enumerate(tk0):\n        inputs = im[\"image\"]\n        inputs = inputs.to(device, dtype=torch.float)\n        inputs = inputs.view(-1,3,512,512)\n        # flip vertical\n        im = inputs.flip(2)\n        outputs = model(im)\n        for i,val in enumerate(outputs):\n            print(val)\n        # fliplr\n        im = inputs.flip(3)\n        outputs = (0.25*outputs + 0.25*model(im))\n        outputs = (outputs + 0.5*model(inputs))        \n        preds.extend(F.softmax(outputs, 1).cpu().numpy())\n\npreds = np.array(preds)\nlabels = preds.argmax(1)\nnew_preds = np.zeros((len(preds),))\nnew_preds[labels != 0] = preds[labels != 0, 1:].sum(1)\nnew_preds[labels == 0] = 1 - preds[labels == 0, 0]\n\ntest_df['Id'] = test_df['ImageFileName'].apply(lambda x: x.split(os.sep)[-1])\ntest_df['Label'] = new_preds\n\ntest_df = test_df.drop('ImageFileName', axis=1)\ntest_df.to_csv('submission_eb0.csv', index=False)\nprint(test_df.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}