{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":87793,"databundleVersionId":11228175,"sourceType":"competition"}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import mean_absolute_error\nfrom sklearn.model_selection import train_test_split\n\n# Efficient One-Hot Encoding\ndef one_hot_encode(sequences, vocab_size=5):\n    return np.eye(vocab_size)[sequences]\n\n# Custom Dataset Class\nclass RNADataset:\n    def __init__(self, sequences, structures):\n        self.sequences = one_hot_encode(sequences, vocab_size=5).reshape(sequences.shape[0], -1)\n        self.structures = np.array(structures).reshape(-1, 3)\n    \n    def __len__(self):\n        return len(self.sequences)\n    \n    def __getitem__(self, idx):\n        return self.sequences[idx], self.structures[idx]\n\n# He Initialization for Better Gradient Flow\ndef initialize_weights(input_dim, hidden_dim1, hidden_dim2, hidden_dim3, hidden_dim4, output_dim):\n    weights = {\n        'W1': np.random.randn(input_dim, hidden_dim1) * np.sqrt(2.0 / input_dim),\n        'b1': np.zeros((hidden_dim1,)),\n        'W2': np.random.randn(hidden_dim1, hidden_dim2) * np.sqrt(2.0 / hidden_dim1),\n        'b2': np.zeros((hidden_dim2,)),\n        'W3': np.random.randn(hidden_dim2, hidden_dim3) * np.sqrt(2.0 / hidden_dim2),\n        'b3': np.zeros((hidden_dim3,)),\n        'W4': np.random.randn(hidden_dim3, hidden_dim4) * np.sqrt(2.0 / hidden_dim3),\n        'b4': np.zeros((hidden_dim4,)),\n        'W5': np.random.randn(hidden_dim4, output_dim) * np.sqrt(2.0 / hidden_dim4),\n        'b5': np.zeros((output_dim,))\n    }\n    return weights\n\n# Forward Pass with Batch Normalization & Leaky ReLU\ndef forward_pass(x, weights, dropout_rate=0.15):\n    def batch_norm(z):\n        return (z - np.mean(z, axis=0)) / (np.std(z, axis=0) + 1e-5)\n    \n    def leaky_relu(z, alpha=0.01):\n        return np.where(z > 0, z, alpha * z)\n    \n    z1 = np.dot(x, weights['W1']) + weights['b1']\n    a1 = leaky_relu(batch_norm(z1))\n    a1 *= np.random.binomial(1, 1 - dropout_rate, size=a1.shape) / (1 - dropout_rate)\n    \n    z2 = np.dot(a1, weights['W2']) + weights['b2']\n    a2 = leaky_relu(batch_norm(z2))\n    a2 *= np.random.binomial(1, 1 - dropout_rate, size=a2.shape) / (1 - dropout_rate)\n    \n    z3 = np.dot(a2, weights['W3']) + weights['b3']\n    a3 = leaky_relu(batch_norm(z3))\n    \n    z4 = np.dot(a3, weights['W4']) + weights['b4']\n    a4 = leaky_relu(batch_norm(z4))\n    \n    z5 = np.dot(a4, weights['W5']) + weights['b5']\n    y_pred = z5\n    \n    return y_pred, a1, a2, a3, a4\n\n# Compute Loss with L2 Regularization\ndef compute_loss(y_pred, y_true, weights, lambda_l2=0.00005):\n    mse_loss = np.mean((y_pred - y_true) ** 2)\n    l2_penalty = lambda_l2 * sum(np.sum(w ** 2) for w in weights.values() if 'W' in w)\n    return mse_loss + l2_penalty\n\n# Backward Pass with Adam Optimizer\ndef backward_pass(x, y_true, y_pred, a1, a2, a3, a4, weights, momentums, velocities, learning_rate, beta1=0.9, beta2=0.999, epsilon=1e-8):\n    dz5 = 2 * (y_pred - y_true)\n    dW5 = np.dot(a4.T, dz5)\n    db5 = np.sum(dz5, axis=0)\n    \n    da4 = np.dot(dz5, weights['W5'].T)\n    dW4 = np.dot(a3.T, da4)\n    db4 = np.sum(da4, axis=0)\n    \n    da3 = np.dot(da4, weights['W4'].T)\n    dW3 = np.dot(a2.T, da3)\n    db3 = np.sum(da3, axis=0)\n    \n    da2 = np.dot(da3, weights['W3'].T)\n    dW2 = np.dot(a1.T, da2)\n    db2 = np.sum(da2, axis=0)\n    \n    da1 = np.dot(da2, weights['W2'].T)\n    dW1 = np.dot(x.T, da1)\n    db1 = np.sum(da1, axis=0)\n    \n    for i, (dW, db) in enumerate([(dW1, db1), (dW2, db2), (dW3, db3), (dW4, db4), (dW5, db5)]):\n        momentums[i] = beta1 * momentums[i] + (1 - beta1) * dW\n        velocities[i] = beta2 * velocities[i] + (1 - beta2) * (dW ** 2)\n        corrected_momentum = momentums[i] / (1 - beta1)\n        corrected_velocity = velocities[i] / (1 - beta2)\n        weights[f'W{i+1}'] -= learning_rate * corrected_momentum / (np.sqrt(corrected_velocity) + epsilon)\n        weights[f'b{i+1}'] -= learning_rate * db\n\n# Train Model with Increased Epochs\ndef train_model(dataset, weights, epochs=100, batch_size=32, learning_rate=0.0015, decay=0.98, dropout_rate=0.15):\n    loss_history = []\n    accuracy_history = []\n    momentums = [np.zeros_like(weights[f'W{i+1}']) for i in range(5)]\n    velocities = [np.zeros_like(weights[f'W{i+1}']) for i in range(5)]\n    \n    for epoch in range(epochs):\n        total_loss = 0\n        total_correct = 0\n        total_samples = 0\n        \n        for i in range(0, len(dataset), batch_size):\n            batch = [dataset[j] for j in range(i, min(i + batch_size, len(dataset)))]\n            x_batch, y_batch = zip(*batch)\n            x_batch, y_batch = np.array(x_batch), np.array(y_batch).reshape(len(batch), -1)\n            y_pred, a1, a2, a3, a4 = forward_pass(x_batch, weights, dropout_rate)\n            \n            loss = compute_loss(y_pred, y_batch, weights)\n            backward_pass(x_batch, y_batch, y_pred, a1, a2, a3, a4, weights, momentums, velocities, learning_rate)\n            total_loss += loss\n            total_correct += np.sum(np.round(y_pred) == np.round(y_batch))\n            total_samples += y_batch.size\n        \n        avg_loss = total_loss / (len(dataset) / batch_size)\n        accuracy = total_correct / total_samples\n        loss_history.append(avg_loss)\n        accuracy_history.append(accuracy)\n        print(f\"Epoch {epoch+1}, Loss: {avg_loss:.4f}, Accuracy: {accuracy:.4f}\")\n        learning_rate *= decay\n\n    plt.plot(loss_history, label='Loss')\n    plt.plot(accuracy_history, label='Accuracy')\n    plt.legend()\n    plt.show()\n\ntrain_model(RNADataset(np.random.randint(0, 5, (1000, 100)), np.random.rand(1000, 3)), initialize_weights(500, 512, 256, 128, 64, 3))\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-03-10T16:55:23.140805Z","iopub.execute_input":"2025-03-10T16:55:23.141205Z","iopub.status.idle":"2025-03-10T16:56:03.872627Z","shell.execute_reply.started":"2025-03-10T16:55:23.141175Z","shell.execute_reply":"2025-03-10T16:56:03.871637Z"}},"outputs":[],"execution_count":null}]}