{"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":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#most skeletal code taken from https://pyimagesearch.com/2021/07/19/pytorch-training-your-first-convolutional-neural-network-cnn/\nimport matplotlib.pyplot as plt\ntrain=pd.read_csv('/kaggle/input/ultra-mnist/train.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_dir='/kaggle/input/ultra-mnist/train/'\nexample_img=plt.imread(img_dir+train.id[0]+'.jpeg')\nplt.imshow(example_img)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nfrom torch.nn import Module\nfrom torch.nn import Conv2d\nfrom torch.nn import Linear\nfrom torch.nn import MaxPool2d\nfrom torch.nn import ReLU\nfrom torch.nn import LogSoftmax\nfrom torch import flatten","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Mod_LeNet(Module):\n    def __init__(self, numChannels, classes):\n        # call the parent constructor\n        super(Mod_LeNet, self).__init__()\n        # initialize first set of CONV => RELU => POOL layers\n        self.conv1 = Conv2d(in_channels=numChannels, out_channels=20,\n            kernel_size=(5, 5))\n        self.relu1 = ReLU()\n        self.maxpool1 = MaxPool2d(kernel_size=(2, 2), stride=(2, 2))\n        # initialize second set of CONV => RELU => POOL layers\n        self.conv2 = Conv2d(in_channels=20, out_channels=10,\n            kernel_size=(5, 5))\n        self.relu2 = ReLU()\n        self.maxpool2 = MaxPool2d(kernel_size=(2, 2), stride=(2, 2))\n        self.conv3 = Conv2d(in_channels=10, out_channels=10,\n            kernel_size=(3, 3))\n        self.relu3 = ReLU()\n        self.maxpool3 = MaxPool2d(kernel_size=(2, 2), stride=(2, 2))\n        self.conv4 = Conv2d(in_channels=10, out_channels=10,\n            kernel_size=(3, 3))\n        self.relu4 = ReLU()\n        self.maxpool4 = MaxPool2d(kernel_size=(2, 2), stride=(2, 2))\n        \n        self.conv5 = Conv2d(in_channels=10, out_channels=10,\n            kernel_size=(3, 3))\n        self.relu5 = ReLU()\n        self.maxpool5 = MaxPool2d(kernel_size=(2, 2), stride=(2, 2))\n        \n        self.conv6 = Conv2d(in_channels=10, out_channels=1,\n            kernel_size=(3, 3))\n        self.relu6 = ReLU()\n        self.maxpool6 = MaxPool2d(kernel_size=(2, 2), stride=(2, 2))\n        # initialize first (and only) set of FC => RELU layers\n        self.fc1 = Linear(in_features=3600, out_features=500)\n        self.relu3 = ReLU()\n        # initialize our softmax classifier\n        self.fc2 = Linear(in_features=500, out_features=classes)\n        self.logSoftmax = LogSoftmax(dim=1)\n        \n    def forward(self, x):\n        # pass the input through our first set of CONV => RELU =>\n        # POOL layers\n        x = self.conv1(x)\n#         print(x.shape)\n        x = self.relu1(x)\n        x = self.maxpool1(x)\n#         print(x.shape)\n        # pass the output from the previous layer through the second\n        # set of CONV => RELU => POOL layers\n        x = self.conv2(x)\n#         print(x.shape)\n        x = self.relu2(x)\n        x = self.maxpool2(x)\n#         print(x.shape)\n        x = self.conv3(x)\n#         print(x.shape)\n        x = self.relu3(x)\n        x = self.maxpool3(x)\n#         print(x.shape)\n        x = self.conv4(x)\n        x = self.relu4(x)\n        x = self.maxpool4(x)\n#         print(x.shape)\n        \n        x = self.conv5(x)\n        x = self.relu5(x)\n        x = self.maxpool5(x)\n#         print(x.shape)\n        \n        x = self.conv6(x)\n        x = self.relu6(x)\n        x = self.maxpool6(x)\n#         print(x.shape)\n        # flatten the output from the previous layer and pass it\n        # through our only set of FC => RELU layers\n        x = flatten(x, 1)\n        x = self.fc1(x)\n        x = self.relu3(x)\n        # pass the output to our softmax classifier to get our output\n        # predictions\n        x = self.fc2(x)\n        output = self.logSoftmax(x)\n        # return the output predictions\n        return output","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INIT_LR = 1e-3\nBATCH_SIZE = 3\nEPOCHS = 10\n# define the train and val splits\nTRAIN_SPLIT = 0.75\nVAL_SPLIT = 1 - TRAIN_SPLIT\n# set the device we will be using to train the model\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.optim import Adam\nfrom torch import nn\nmodel = Mod_LeNet(\n\tnumChannels=1,\n\tclasses=28).to(device)\n# initialize our optimizer and loss function\nopt = Adam(model.parameters(), lr=INIT_LR)\nlossFn = nn.NLLLoss()\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import gc\nimport time\nfrom tqdm import tqdm\nfrom sklearn.utils import shuffle\n\nnbatches=int(len(train)/BATCH_SIZE)\nfor e in range(0, EPOCHS):\n    e_start_time=time.time()\n    # initialize the total training and validation loss\n    totalTrainLoss = 0\n    totalValLoss = 0\n    # initialize the number of correct predictions in the training\n    # and validation step\n    trainCorrect = 0\n    valCorrect = 0\n    # loop over the training set\n    for i in tqdm(range(nbatches),desc='all batch_time'):\n        pred=torch.empty((BATCH_SIZE,28),dtype=torch.float32).to(device)\n        y=[]\n        for j in range(BATCH_SIZE):\n            a=plt.imread(img_dir+train.id[j+i*BATCH_SIZE]+'.jpeg')\n            a.resize(1,1,4000,4000)\n            a=torch.from_numpy(a/255.0).float().to(device)\n            pred[j,:]=model(a).to(device)\n            del a\n            gc.collect()\n            torch.cuda.empty_cache()   \n        loss = lossFn(pred,torch.from_numpy(train.digit_sum[i*BATCH_SIZE:(i+1)*BATCH_SIZE].values).to(device))\n        # zero out the gradients, perform the backpropagation step,\n        # and update the weights\n        opt.zero_grad()\n        loss.backward()\n        opt.step()\n        # add the loss to the total training loss so far and\n        # calculate the number of correct predictions\n        totalTrainLoss += loss\n        trainCorrect += (pred.argmax(1) == torch.from_numpy(train.digit_sum[i*BATCH_SIZE:(i+1)*BATCH_SIZE].values).to(device)).type(\n            torch.float).sum().item()\n        del pred\n        del y\n        gc.collect()\n        torch.cuda.empty_cache()\n        \n    train=shuffle(train)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test=pd.read_csv('/kaggle/input/ultra-mnist/sample_submission.csv')\ntest.head()\ntest_batch_size=2\nfor i in tqdm(range(int(len(test)/test_batch_size))):\n    img=[]\n    for j in range(test_batch_size):\n        img.append(plt.imread('/kaggle/input/ultra-mnist/test/'+test.id[i*test_batch_size+j]+'.jpeg')/255.0)\n    img=np.array(img)\n    img.resize(test_batch_size,1,4000,4000)\n    img=torch.from_numpy(img).float().to(device)\n    test.loc[i*test_batch_size+(i+1)*test_batch_size]['digit_sum']=model(img).to(device).argmax(1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}