{"cells":[{"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\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 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 numpy as np\n\ndataset_prefix = \"fashionmnist\" \n\ntrain_data = np.load(\"/kaggle/input/2020-mpcs53111-hw5-fashionmnist/{}_train.npy\".format(dataset_prefix))\ntest_data = np.load(\"/kaggle/input/2020-mpcs53111-hw5-fashionmnist/{}_test.npy\".format(dataset_prefix))\n\ntrain_images = train_data[:, :-1].reshape(-1, 1, 28, 28)\ntrain_labels = train_data[:, -1]\ntest_images = test_data.reshape(-1, 1, 28, 28)/255","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torchvision\nfrom PIL import Image\n\npil_images = [Image.fromarray((image.reshape(image.shape[1:])*255).astype(\"uint8\"), 'L') for image in train_images]\ndef pil_to_np(images):\n    images = np.array([np.array(image) for image in images])\n    return images.reshape(-1, 1, 28, 28)/255.\nmodified_images = [torchvision.transforms.functional.hflip(image) for image in pil_images]\ntrain_images = np.concatenate([train_images, pil_to_np(modified_images)], axis=0)\nmodified_images = [torchvision.transforms.functional.affine(image, 0, (-2, 0), 1, 0) for image in pil_images]\ntrain_images = np.concatenate([train_images, pil_to_np(modified_images)], axis=0)\nmodified_images = [torchvision.transforms.functional.affine(image, 0, (+2, 0), 1, 0) for image in pil_images]\ntrain_images = np.concatenate([train_images, pil_to_np(modified_images)], axis=0)\n#modified_images = [torchvision.transforms.functional.affine(image, 0, (0, -2), 1, 0) for image in pil_images]\n#train_images = np.concatenate([train_images, pil_to_np(modified_images)], axis=0)\n#modified_images = [torchvision.transforms.functional.affine(image, 0, (0, +2), 1, 0) for image in pil_images]\n#train_images = np.concatenate([train_images, pil_to_np(modified_images)], axis=0)\nmodified_images = None\npil_images = None\ntrain_labels = np.concatenate([train_labels]*4, axis=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.utils as utils\nimport torch.nn.functional as F\n\nclass Net(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.cnn_layers = nn.Sequential(\n            nn.Conv2d(1, 64, 3, padding=1),\n            nn.ReLU(),\n            nn.Conv2d(64, 128, 3, padding=1),\n            nn.ReLU(),\n            nn.BatchNorm2d(128),\n            nn.MaxPool2d(2, 2),\n            nn.Dropout2d(p=0.2),\n            nn.Conv2d(128, 128, 3, padding=1),\n            nn.ReLU(),\n            nn.Conv2d(128, 256, 3, padding=1),\n            nn.ReLU(),\n            nn.BatchNorm2d(256),\n            nn.MaxPool2d(2, 2),\n            nn.Dropout2d(p=0.2),\n            nn.Conv2d(256, 256, 3, padding=1),\n            nn.ReLU(),\n            nn.Conv2d(256, 256, 3, padding=1),\n            nn.ReLU(),\n            nn.Conv2d(256, 512, 3, padding=1),\n            nn.ReLU(),\n            nn.BatchNorm2d(512),\n            nn.MaxPool2d(2, 2),\n            nn.Dropout2d(p=0.2),\n        )\n        self.linear_layers = nn.Sequential(\n            nn.Linear(4608, 2048),\n            nn.ReLU(),\n            nn.Dropout(p=0.2),\n            nn.Linear(2048, 512),\n            nn.ReLU(),\n            nn.Linear(512, 10),\n        )\n\n    def forward(self, x):\n        x1 = self.cnn_layers(x).view(x.shape[0], -1)\n        return self.linear_layers(x1)\n\nclass Model:\n    def fit(self, X, y, lr=0.001, n_epochs=50, test_data=None):\n        self.net = Net()\n        self.device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\n        self.net = self.net.to(self.device)\n        self.loss = nn.CrossEntropyLoss()\n        self.optimizer = optim.Adam(self.net.parameters(), lr=lr)\n        train_data = (X, y)\n        X = torch.from_numpy(X).float().to(self.device)\n        y = torch.from_numpy(y).long().to(self.device)\n        data = utils.data.TensorDataset(X, y)\n        data_loader = utils.data.DataLoader(data, batch_size=512, shuffle=True)\n        for ep in range(n_epochs):\n            self.net.train()\n            for batch_X, batch_y in data_loader:\n                self.optimizer.zero_grad()\n                y_hat = self.net(batch_X)\n                loss = self.loss(y_hat, batch_y)\n                loss.backward()\n                self.optimizer.step()\n            if ep % 1 == 0:\n                print(f'Epoch: {ep}, Loss: {loss}')\n                print(f'Train Accuracy: {self.score(*train_data)}')\n                if test_data: print(f'Test Accuracy: {self.score(*test_data)}')\n    def predict(self, X):\n        with torch.no_grad():\n            self.net.eval()\n            X = torch.from_numpy(X).float().to(self.device)\n            data = utils.data.TensorDataset(X)\n            data_loader = utils.data.DataLoader(data, batch_size=512)\n            outputs = []\n            for batch, in data_loader:\n                outputs.append(self.net(batch))\n            out = torch.cat(outputs)\n            return torch.argmax(out, axis=1)\n    def score(self, X, y):\n        y_hat = self.predict(X)\n        y = torch.from_numpy(y).long().to(self.device)\n        return int((y == y_hat).sum())/y.shape[0]\n    def get_params(self, deep=True): return {}\n    def set_params(self, **__): pass","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Model()\nmodel.fit(train_images, train_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"out = model.predict(test_images)\nimport csv\nwith open(f'{dataset_prefix}_out.csv', mode='w', newline='') as out_file:\n    fieldnames = ['Id', 'Category']\n    writer = csv.DictWriter(out_file, fieldnames=fieldnames)\n\n    writer.writeheader()\n    for i, j in enumerate(out):\n        writer.writerow({'Id': i, 'Category': int(j)})","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}