{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport pytorch_lightning as pl\nfrom sklearn.model_selection import train_test_split\nimport seaborn as sns\nimport torch\nimport torch.nn as nn\nfrom sklearn import preprocessing\nfrom scipy.stats import norm, skew #for some statistics\nfrom scipy import stats\n\nimport math\n%matplotlib inline\nplt.style.use('ggplot')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train = pd.read_csv(\"../input/predict-volcanic-eruptions-ingv-oe/train.csv\")\ndf_train.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.isnull().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.time_to_eruption.hist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.time_to_eruption.max()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.distplot(df_train.time_to_eruption , fit=norm);\n\n# Get the fitted parameters used by the function\n(mu, sigma) = norm.fit(df_train.time_to_eruption)\nprint( '\\n mu = {:.2f} and sigma = {:.2f}\\n'.format(mu, sigma))\n\n#Now plot the distribution\nplt.legend(['Normal dist. ($\\mu=$ {:.2f} and $\\sigma=$ {:.2f} )'.format(mu, sigma)],\n            loc='best')\nplt.ylabel('Frequency')\nplt.title('Time distribution')\n\n#Get also the QQ-plot\nfig = plt.figure()\nres = stats.probplot(df_train.time_to_eruption, plot=plt)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Read first value"},{"metadata":{"trusted":true},"cell_type":"code","source":"df_first = pd.read_csv(f\"../input/predict-volcanic-eruptions-ingv-oe/train/{df_train.segment_id[2]}.csv\")\ndf_first.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_first.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_first.sensor_2.hist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%matplotlib inline\n\n# calculate the correlation matrix\ncorr = df_first.corr()\n\n# plot the heatmap\nsns.heatmap(corr, \n        xticklabels=corr.columns,\n        yticklabels=corr.columns)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Deploy model"},{"metadata":{"trusted":true},"cell_type":"code","source":"# MEAN = df_train.time_to_eruption.mean()\n# NORM = np.linalg.norm(df_train.time_to_eruption.values)\n# df_train.time_to_eruption= (df_train.time_to_eruption - MEAN)/ NORM","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train, df_valid = train_test_split(df_train, test_size=0.2, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train[:60000]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nclass INDVDataset(torch.utils.data.Dataset):\n    def __init__(self, df):\n        self.segment = df.segment_id.values\n        self.time = df.time_to_eruption.values\n    def __len__(self):\n        return self.segment.shape[0]\n    def __getitem__(self, index):\n        df = pd.read_csv(f\"../input/predict-volcanic-eruptions-ingv-oe/train/{self.segment[index]}.csv\")\n        \n        df = df.fillna(0)\n        df = df[:60000].values.reshape(6000, 100)\n        label = self.time[index]\n        return df , label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE  = 5\nNUM_WORKERS = 2\nLR =1e-4\nEPOCHS = 5\nDEVICE= 'cuda:0'  if torch.cuda.is_available() else 'cpu'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch.nn import functional as F\n\nclass INGVNet(pl.LightningModule):\n    def __init__(self):\n        super().__init__()\n        self.lstm1 = nn.LSTM(100 , 200 , bidirectional=False, batch_first=True)\n        self.linear1 = nn.Linear(400, 400)\n        self.linear_aux_out = nn.Linear(400, 1)\n        self.critrion = nn.MSELoss(reduction='mean')\n        self.dropout = nn.Dropout(0.3)\n        \n    def forward(self, x):\n        lstm1, _ = self.lstm1(x)\n        avg_pool = torch.mean(lstm1, 1)\n        max_pool, _ = torch.max(lstm1, 1)\n        \n        h_conc = torch.cat((max_pool, avg_pool), 1)\n        h_conc_linear1  = self.linear1(h_conc)\n        \n        hidden = 1000*h_conc + h_conc_linear1\n        hidden = self.dropout(hidden)\n        hidden = nn.LeakyReLU()(hidden)\n        aux_result = 10*self.linear_aux_out(hidden)\n\n        return aux_result\n\n\n    def training_step(self, batch, batch_idx):\n        # training_step defined the train loop. It is independent of forward\n        x, y = [i.float().to(DEVICE) for i in batch]\n        x_pred = self(x)\n        loss = torch.sqrt(self.critrion(x_pred, y.reshape(-1, 1)))\n        with torch.no_grad():\n            logs = {\n                'loss': loss,\n                \n            }\n        return {'loss': loss, 'log': logs, \"progress_bar\": {\"MAE\": nn.L1Loss()(x_pred, y.reshape(-1, 1)) }}\n    @torch.no_grad()\n    def validation_step(self, batch, batch_idx):\n        x, y = [i.float().to(DEVICE) for i in batch]\n        x_pred = self(x)\n        loss = self.critrion(x_pred, y.reshape(-1,1))\n        logs = {\n                'val_loss': loss\n            }\n        return logs\n    def train_dataloader(self):\n        train_dataset = INDVDataset(df_train)\n        train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=BATCH_SIZE, \n                                                   pin_memory=True, num_workers = NUM_WORKERS, shuffle=True)\n        return train_loader\n    def val_dataloader(self):\n        valid_dataset = INDVDataset(df_valid)\n        valid_dataloader = torch.utils.data.DataLoader(valid_dataset, batch_size=BATCH_SIZE, \n                                                   pin_memory=True, num_workers = NUM_WORKERS, shuffle=False)\n        return valid_dataloader\n        \n    def configure_optimizers(self):\n        self.optimizer = torch.optim.Adam(self.parameters(), lr=LR, betas= (0.9,0.999), weight_decay= 5e-7, amsgrad=True) #, betas= (0.9,0.999), weight_decay= 5e-7, amsgrad=True\n        self.scheduler = torch.optim.lr_scheduler.StepLR(self.optimizer, step_size=3, gamma=0.6)\n        return [self.optimizer], [self.scheduler]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"net = INGVNet()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.backends.cudnn.benchmark =  True\n\ntrainer = pl.Trainer(max_epochs=EPOCHS ,gradient_clip_val=0, limit_val_batches=0.2, gpus=1)\ntrainer.fit(net)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Inference part"},{"metadata":{"trusted":true},"cell_type":"code","source":"df_test = pd.read_csv(\"../input/predict-volcanic-eruptions-ingv-oe/sample_submission.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class INDVTest(torch.utils.data.Dataset):\n    def __init__(self, df):\n        self.segment = df.segment_id.values\n    def __len__(self):\n        return self.segment.shape[0]\n    def __getitem__(self, index):\n        df = pd.read_csv(f\"../input/predict-volcanic-eruptions-ingv-oe/test/{self.segment[index]}.csv\")\n        df = df.fillna(0)\n        df = df[:60000].values.reshape(6000, 100)\n        return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm import tqdm\ntest_dataset = INDVTest(df_test)\ntest_loader = torch.utils.data.DataLoader(test_dataset, batch_size=BATCH_SIZE, \n                                                   pin_memory=True, num_workers = NUM_WORKERS, shuffle=True)\narr_time = []\nnet.cuda()\nfor batch in tqdm(test_loader):\n    arr_time= [*arr_time, *  (net(batch.float().to(DEVICE)).squeeze().detach().cpu().numpy())]\ndf_test.time_to_eruption = arr_time","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_test.to_csv(\"submission.csv\", index=False)","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}