{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":56537,"databundleVersionId":8015876,"sourceType":"competition"}],"dockerImageVersionId":30698,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import random, sys, gc, warnings, math\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom time import time\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.callbacks import LearningRateScheduler, EarlyStopping\nfrom tensorflow.keras.optimizers.schedules import ExponentialDecay\nfrom tensorflow.keras.layers import Input, Dense, Concatenate, Dropout\nfrom tensorflow.keras.utils import Sequence\n\nt0 = time()\nnp.random.seed(13)\nrandom.seed(13)\nmin_std = 1e-8","metadata":{"execution":{"iopub.status.busy":"2024-04-23T21:29:27.907928Z","iopub.execute_input":"2024-04-23T21:29:27.908228Z","iopub.status.idle":"2024-04-23T21:29:40.466025Z","shell.execute_reply.started":"2024-04-23T21:29:27.908203Z","shell.execute_reply":"2024-04-23T21:29:40.465101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load train data\ndf = pd.read_csv(\"/kaggle/input/leap-atmospheric-physics-ai-climsim/train.csv\", nrows=25000)\nx = df.iloc[:,1:557].to_numpy().astype(np.float32)\ny = df.iloc[:,557:].to_numpy().astype(np.float32)","metadata":{"execution":{"iopub.status.busy":"2024-04-23T21:32:27.785028Z","iopub.execute_input":"2024-04-23T21:32:27.785346Z","iopub.status.idle":"2024-04-23T21:35:34.99869Z","shell.execute_reply.started":"2024-04-23T21:32:27.785322Z","shell.execute_reply":"2024-04-23T21:35:34.996594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# read test\ndf = pd.read_csv(\"/kaggle/input/leap-atmospheric-physics-ai-climsim/test.csv\")\nxt = df.iloc[:,1:557].to_numpy().astype(np.float32)\ndel df\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-04-23T21:35:35.001368Z","iopub.execute_input":"2024-04-23T21:35:35.001774Z","iopub.status.idle":"2024-04-23T21:37:29.20986Z","shell.execute_reply.started":"2024-04-23T21:35:35.001739Z","shell.execute_reply":"2024-04-23T21:37:29.208752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# norm X\nmx = x.mean(axis=0)\nsx = np.maximum(x.std(axis=0), min_std)\nx = (x - mx.reshape(1,-1)) / sx.reshape(1,-1)\nxt = (xt - mx.reshape(1,-1)) / sx.reshape(1,-1)","metadata":{"execution":{"iopub.status.busy":"2024-04-23T21:37:29.211072Z","iopub.execute_input":"2024-04-23T21:37:29.211361Z","iopub.status.idle":"2024-04-23T21:37:30.523197Z","shell.execute_reply.started":"2024-04-23T21:37:29.211339Z","shell.execute_reply":"2024-04-23T21:37:30.522261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# norm Y\nmy = y.mean(axis=0)\nsy = np.maximum(np.sqrt((y*y).mean(axis=0)), min_std)\ny = (y - my.reshape(1,-1)) / sy.reshape(1,-1)","metadata":{"execution":{"iopub.status.busy":"2024-04-23T21:37:30.525188Z","iopub.execute_input":"2024-04-23T21:37:30.525425Z","iopub.status.idle":"2024-04-23T21:37:31.024451Z","shell.execute_reply.started":"2024-04-23T21:37:30.525404Z","shell.execute_reply":"2024-04-23T21:37:31.02357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data generator\nclass data_gen(Sequence): # constructor: save all data locally\n    def __init__(self, i1, i2, batch_size):\n        self.i1, self.i2 = i1, i2\n        self.batch_size = batch_size\n        return\n\n    def __len__(self): # returns number of batches\n        return math.ceil((self.i2 - self.i1) / self.batch_size)\n\n    def __getitem__(self, idx): # returns one batch\n        index = np.arange(self.i1 + idx * self.batch_size, min(self.i2, self.i1 + (idx + 1) * self.batch_size))\n        batch_x = x[index]\n        batch_y = y[index]\n        return (batch_x, batch_y)","metadata":{"execution":{"iopub.status.busy":"2024-04-23T21:37:31.025589Z","iopub.execute_input":"2024-04-23T21:37:31.02581Z","iopub.status.idle":"2024-04-23T21:37:31.032834Z","shell.execute_reply.started":"2024-04-23T21:37:31.025791Z","shell.execute_reply":"2024-04-23T21:37:31.031676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# NN\nBS  = 1024 * 8  # batch size\nD1  = 512       # width\n#creates a boolean array where each element is True if the corresponding index is less than half the number of rows in x, and False otherwise.\ntr_idx = np.arange(x.shape[0]) < x.shape[0]//2\n#creates a boolean array where each element is True if the corresponding index is greater than or equal to half the length of x, and False otherwise.\nva_idx = np.arange(x.shape[0]) >= x.shape[0]//2\nwith tf.device('/GPU:0'):\n    i1 = Input(shape=(x.shape[1],), dtype='float32')\n    d1 = Dense(D1, activation='selu')(i1)\n    o  = Dense(y.shape[1], activation=None)(d1)\n\n    # compile the model\n    model = tf.keras.Model(inputs=i1, outputs=o)\n    model.compile(tf.keras.optimizers.Adam(0.001), loss='MSE')\n    print(model.summary())\n    es = EarlyStopping(monitor='val_loss', min_delta=.0001, patience=5, verbose=0, mode='min', restore_best_weights=True)\n    tr = data_gen(0, x.shape[0]//2, BS)\n    va = data_gen(x.shape[0]//2, x.shape[0], BS)\n    model.fit(x=tr, validation_data=va, epochs=5, callbacks=[es], verbose=2)\n\n    # predict in batches to avoid OOM\n    predt = np.zeros([xt.shape[0], y.shape[1]], dtype=np.float32)\n    i1 = 0\n    BS2 = 1024 * 128\n    for i in range(10000):\n        i2 = np.minimum(i1 + BS2, xt.shape[0])\n        predt[i1:i2,:] = model.predict(xt[i1:i2,:], verbose=0)\n        i1 = i2\n        print(np.round(i2/predt.shape[0], 2)) # pct completion\n        if i2 >= xt.shape[0]:\n            break","metadata":{"execution":{"iopub.status.busy":"2024-04-23T21:37:31.033862Z","iopub.execute_input":"2024-04-23T21:37:31.034098Z","iopub.status.idle":"2024-04-23T21:38:54.527185Z","shell.execute_reply.started":"2024-04-23T21:37:31.034078Z","shell.execute_reply":"2024-04-23T21:38:54.525859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # submit\n# # override constant columns\n# for i in range(sy.shape[0]):\n#     if sy[i] < min_std * 1.1:\n#         predt[:,i] = 0\n\n# # undo y scaling\n# predt = predt * sy.reshape(1,-1) + my.reshape(1,-1)\n\n# ss = pd.read_csv(\"/kaggle/input/leap-atmospheric-physics-ai-climsim/sample_submission.csv\")\n# ss.iloc[:,1:] *= predt\n# ss.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2024-04-23T21:38:54.529196Z","iopub.execute_input":"2024-04-23T21:38:54.529587Z","iopub.status.idle":"2024-04-23T21:44:05.004445Z","shell.execute_reply.started":"2024-04-23T21:38:54.529554Z","shell.execute_reply":"2024-04-23T21:44:05.003429Z"},"trusted":true},"execution_count":null,"outputs":[]}]}