[{'role': 'system', 'content': "You are an expert in machine learning and your task is to classify code snippets into one of the following categories: ['helper_functions', 'load_data', 'data_exploration', 'data_preprocessing', 'evaluation', 'modelling', 'prediction', 'result_visualization', 'save_results', 'comment_only']."}, {'role': 'user', 'content': "Identify the single most appropriate category to which the provided code belongs. Provide your response as a single category label without any additional information, commentary, or personal opinions.\\nPython Code:import numpy as np\nimport impl.loss as loss_fun\nimport impl.layer as l\nimport impl.regularization as reg\nimport impl.utils as util\nimport impl.NN as nn\nclass LSTM(nn.NN):\ndef __init__(self, D, H, char2idx, idx2char):\nself.D = D\nself.H = H\nself.char2idx = char2idx\nself.idx2char = idx2char\nself.vocab_size = len(char2idx)\nsuper().__init__(D, D, H, None, None, loss='cross_ent', nonlin='relu')\ndef initial_state(self):\nreturn (np.zeros((1, self.H)), np.zeros((1, self.H)))\ndef forward(self, X, h):\nm = self.model\nWf, Wi, Wc, Wo, Wy = m['Wf'], m['Wi'], m['Wc'], m['Wo'], m['Wy']\nbf, bi, bc, bo, by = m['bf'], m['bi'], m['bc'], m['bo'], m['by']\nh_old, c_old = h\nX_one_hot = X.copy()\nX = np.column_stack((h_old, X_one_hot))\nhf, hf_cache = l.fc_forward(X, Wf, bf)\nhf, hf_sigm_cache = l.sigmoid_forward(hf)\nhi, hi_cache = l.fc_forward(X, Wi, bi)\nhi, hi_sigm_cache = l.sigmoid_forward(hi)\nho, ho_cache = l.fc_forward(X, Wo, bo)\nho, ho_sigm_cache = l.sigmoid_forward(ho)\nhc, hc_cache = l.fc_forward(X, Wc, bc)\nhc, hc_tanh_cache = l.tanh_forward(hc)\nc = hf * c_old + hi * hc\nc, c_tanh_cache = l.tanh_forward(c)\nh = ho * c\ny, y_cache = l.fc_forward(h, Wy, by)\ncache = (\nX, hf, hi, ho, hc, hf_cache, hf_sigm_cache, hi_cache, hi_sigm_cache, ho_cache,\nho_sigm_cache, hc_cache, hc_tanh_cache, c_old, c, c_tanh_cache, y_cache\n)\nh_ = (h, c)\nreturn y, h_, cache\ndef backward(self, dy, dh_next_, cache):\nX, hf, hi, ho, hc, hf_cache, hf_sigm_cache, hi_cache, hi_sigm_cache, ho_cache, ho_sigm_cache, hc_cache, hc_tanh_cache, c_old, c, c_tanh_cache, y_cache = cache\ndh_next, dc_next = dh_next_\ndh, dWy, dby = l.fc_backward(dy, y_cache)\ndh += dh_next\ndho = c * dh\ndho = l.sigmoid_backward(dho, ho_sigm_cache)\ndc = ho * dh\ndc = l.tanh_backward(dc, c_tanh_cache)\ndc = dc + dc_next\ndhf = c_old * dc\ndhf = l.sigmoid_backward(dhf, hf_sigm_cache)\ndhi = hc * dc\ndhi = l.sigmoid_backward(dhi, hi_sigm_cache)\ndhc = hi * dc\ndhc = l.tanh_backward(dhc, hc_tanh_cache)\ndXo, dWo, dbo = l.fc_backward(dho, ho_cache)\ndXc, dWc, dbc = l.fc_backward(dhc, hc_cache)\ndXi, dWi, dbi = l.fc_backward(dhi, hi_cache)\ndXf, dWf, dbf = l.fc_backward(dhf, hf_cache)\ndX = dXo + dXc + dXi + dXf\ndh_next = dX[:, :self.H]\ndc_next = hf * dc\ndX = dX[:, self.H:]\ngrad = dict(Wf=dWf, Wi=dWi, Wc=dWc, Wo=dWo, Wy=dWy, bf=dbf, bi=dbi, bc=dbc, bo=dbo, by=dby)\ndh_next_ = (dh_next, dc_next)\nreturn dX, dh_next_, grad\ndef _init_model(self, D, C, H):\nZ = H + D\nself.model = dict(\nWf=np.random.randn(Z, H) / np.sqrt(Z / 2.),\nWi=np.random.randn(Z, H) / np.sqrt(Z / 2.),\nWc=np.random.randn(Z, H) / np.sqrt(Z / 2.),\nWo=np.random.randn(Z, H) / np.sqrt(Z / 2.),\nWy=np.random.randn(H, D) / np.sqrt(D / 2.),\nbf=np.zeros((1, H)),\nbi=np.zeros((1, H)),\nbc=np.zeros((1, H)),\nbo=np.zeros((1, H)),\nby=np.zeros((1, D)))\ndef train_step_fwd(self, X_train, h):\nys, caches = [], []\nfor X in X_train:\nX_one_hot = np.zeros(self.D)\nX_one_hot[X] = 1.\nx = X_one_hot.reshape(1, -1)\ny, h, cache = self.forward(x, h)\nys.append(y)\ncaches.append(cache)\nreturn ys, caches\ndef train_step_bwd(self, y_train, ys, caches):\nloss, dys = 0.0, []\nfor y_pred, y in zip(ys, y_train):\nloss += loss_fun.cross_entropy(self.model, y_pred, y, lam=0)/ y_train.shape[0]\ndy = loss_fun.dcross_entropy(y_pred, y)\ndys.append(dy)\ndh_next = np.zeros((1, self.H))\ndc_next = np.zeros((1, self.H))\ndh_next_ = (dh_next, dc_next)\ngrads = {key: np.zeros_like(val) for key, val in self.model.items()}\nfor t in reversed(range(len(dys))):\ndX, dh_next_, grad = self.backward(dys[t], dh_next_, caches[t])\nfor k in grad.keys():\ngrads[k] += grad[k]\nreturn grads, loss"}, {'role': 'assistant', 'content': 'modelling'}]