{ "cells": [ { "cell_type": "markdown", "id": "ba43ee2e-6672-4647-8150-a3889306951e", "metadata": {}, "source": [ "# Evaluating Channel Estimation Performance Using NMSE\n", "\n", "This notebook evaluates the trained channel estimation model on the test dataset using **Normalized Mean Squared Error (NMSE)**. NMSE measures the difference between the predicted channel estimates and the corresponding ground-truth channels, providing a direct assessment of estimation accuracy.\n", "\n", "The evaluation uses the trained `ChEstNet` model together with the test dataset generated during the dataset creation stage. The resulting NMSE values can be compared with those obtained from conventional channel estimation methods to quantify the accuracy improvements provided by the neural network.\n", "\n", "Unlike the BLER and HARQ evaluations presented in the subsequent notebooks, this analysis focuses solely on channel estimation quality and does not include end-to-end communication performance metrics." ] }, { "cell_type": "code", "execution_count": 1, "id": "2415601e", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import os\n", "import matplotlib.pyplot as plt\n", "import torch\n", "\n", "from ChEstNet import ChEstNet, ChEstDataset\n", "from ChEstUtils import toComplex" ] }, { "cell_type": "code", "execution_count": 2, "id": "12efc621", "metadata": {}, "outputs": [], "source": [ "# Load the trained model\n", "modelPath = 'Models/Pretrained.pth' # Use the pre-trained model\n", "# modelPath = 'Models/Trained.pth' # Use the model trained in the previous step (see MLChEstTrain.ipynb)\n", "device = \"cuda:0\" if torch.cuda.is_available() else \"mps\" if torch.backends.mps.is_available() else \"cpu\"\n", "model = ChEstNet(device) # Instantiate the model on the target device\n", "model.loadParams(modelPath); # Load the trained model parameters" ] }, { "cell_type": "code", "execution_count": 3, "id": "cb65e837-866e-41ab-a7cf-0aca1cff2892", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "numGood: 0 1 2 3\n", "MSE: 0.405214 0.135565 0.071499 0.052737\n", "MAE: 0.547839 0.306795 0.231227 0.199122\n", "NMSE: 0.298225 0.103242 0.054076 0.040313\n", "\n" ] }, { "data": { "image/png": "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6GV8EqIlIiMjERoaCi8vLzRp0gSxsbEqQ8lWqVIFMTExAJ733fDy8oKrqytyc3OxadMmLFu2DHPnzgUAKBQKDB48GD/88ANq1KiB6tWrY9SoUXBwcFDq/E5EREREVFIMQrRE165dcefOHURFRSE1NRUeHh6Ij4+XOpanpKQo/ZhdTk4O+vfvjxs3bsDY2Bi1a9fG8uXL0bVrVynPsGHDkJOTgz59+iAzMxPNmjVDfHw8jIyMZF8/IiIiItIeHKKXylRZDvHHPiHlh31CiIi0G4fopbLGPiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFaZPbs2XB2doaRkRG8vb1x8ODBIvMuWLAAfn5+sLKygpWVFQICAlTyh4WFQaFQKH1atWpV1qtBRERERFqOQYiWiIuLQ2RkJKKjo3HkyBE0bNgQQUFBSE9PV5s/MTER3bt3x86dO5GUlARHR0cEBgbi5s2bSvlatWqF27dvS58VK1bIsTpEREREpMUYhGiJqVOnIiIiAuHh4XB3d8e8efNQoUIFLFy4UG3+3377Df3794eHhwdq166NX375BQUFBUhISFDKZ2hoCDs7O+ljZWUlx+oQERERkRZjEKIF8vLycPjwYQQEBEhpOjo6CAgIQFJSkkZlPHr0CE+fPkXF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obLGPiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiFERERERCQrBiHlxN3dHffu3ZP+7t+/PzIyMqS/09PTUaFChfKoGhERERFRmWIQUk7Onj2LZ8+eSX8vX74c2dnZ0t9CCDx58qQ8qkZEREREVKYYhLwlhBAqaQqFohxqQkRERERUthiEEBERERGRrBiElBOFQqHypINPPoiIiIjoXaBX3hV4Vwkh0LJlS+jpPW+Cx48fo23btjAwMAAApf4iRERERETahEFIOYmOjlb6u3379ip5OnXqJFd1iIiIiIhkwyCknLwchBARERERvSsYhLxldu3ahZycHPj4+MDKyqq8q0NEREREVOoYhJSTCRMm4OHDhxg3bhyA531EWrduja1btwIAKleujISEBNStW7c8q0lEREREVOo4OlY5iYuLQ7169aS/V69ejd27d2PPnj3IyMiAl5cXxowZU441JCIiIiIqGwxCysmVK1fQoEED6e9Nmzbh008/RdOmTVGxYkV8//33SEpKKscaEhERERGVDQYh5eTZs2cwNDSU/k5KSoKvr6/0t4ODAzIyMsqjakREREREZYpBSDlxdXXF7t27AQApKSk4f/48PvjgA2n6jRs3UKlSpfKqHhERERFRmWHH9HIyYMAADBw4EHv27MH+/fvh4+MDd3d3afqOHTvQqFGjcqwhEREREVHZYBBSTiIiIqCrq4sNGzbggw8+UPndkFu3bqFnz57lVDsiIiIiorKjEEKI8q4Eaa/s7GxYWFggKysL5ubmpVq284iNpVoeae7q+DblXQUiIipDZXn9JgLYJ4SIiIiIiGTG17HKia6urkb58vPzy7gmRERERETy4pOQciKEQLVq1TBq1CisXbu2yE9JzJ49G87OzjAyMoK3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QFdXF8ePH0e7du1Qs2ZN9OrVC56entizZw8MDQ3LZR2JiOjdVBZP/Hv06IHjx48jOTlZ+jg4OGDo0KHYsmWLVEZmZiYOHz4slbFjxw4UFBTA29u7yPoWFBTg6dOnKCgoeO11JtJ2fBKiRQYOHIiBAweqnaauM3nnzp3RuXNntfmNjY2lkzAREVF5K+0n/pUqVUKlSpWUlqGvrw87OzvUqlULAFCnTh20atUKERERmDdvHp4+fYqBAweiW7du0nC+haNq1a9fH4aGhjh06BBGjhyJrl27qoy2RUT/wyCEiIiI3npdu3bFnTt3EBUVhdTUVHh4eKg88dfR+d8LHoVP/L///nv83//9H2rUqKH0xF9Tv/32GwYOHIiWLVtCR0cHnTp1wowZM6Tpenp6mDBhAs6fPw8hBJycnDBw4EB88803pbPiRFpKIYQQ5V0J0l7Z2dmwsLBAVlZWqY+U5TxiY6mWR5q7Or5NmZbPti0/Zdm2bNfyU9bHLGmfsrx+EwHsE0JERERERDJjEEJERERERLJinxAiIiJ6I3zVrvzwVTv6r+KTECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDECIiIiIikhWDEC0ye/ZsODs7w8jICN7e3jh48GCx+VetWoXatWvDyMgI9evXx6ZNm5SmCyEQFRUFe3t7GBsbIyAgABcuXCjLVSAiIiKidwCDEC0RFxeHyMhIREdH48iRI2jYsCGC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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Evaluate the model on the test dataset\n", "dataPath = \"/data/datasets/SelfRefine/\" # Replace with the path to your dataset files\n", "testDS = ChEstDataset( os.path.join(dataPath,\"Test.npy\") ) # Load the test dataset\n", "\n", "numCBs = len(testDS.numPilots)\n", "sumMAEs = np.zeros(numCBs, dtype=np.float64)\n", "sumMSEs = np.zeros(numCBs, dtype=np.float64)\n", "sumNMSEs = np.zeros(numCBs, dtype=np.float64)\n", "counts = np.zeros(numCBs, dtype=np.int32)\n", "\n", "model.eval() # Set the model to evaluation mode\n", "with torch.no_grad():\n", " for batchSamples, batchLabels in testDS.batches(device):\n", " samples = toComplex(batchSamples.cpu().numpy())[:,:-1,:,:] \n", " actuals = toComplex(batchLabels.cpu().numpy())\n", " preds = toComplex( model( batchSamples ).cpu().numpy() )\n", " for sample, actual, pred in zip(samples, actuals, preds):\n", " pilotIdx = np.where(sample.real!=0)\n", " assert len(pilotIdx[0]) in testDS.numPilots, \"%d - %d\\n\"%(len(pilotIdx[0]), sum(counts))\n", " numGoodCBs = testDS.numPilots.index(len(pilotIdx[0]))\n", "\n", " absoluteErrors = np.abs(pred-actual)\n", " sumMAEs[numGoodCBs] += absoluteErrors.mean()\n", " sumMSEs[numGoodCBs] += np.square(absoluteErrors).mean()\n", " sumNMSEs[numGoodCBs]+= np.square(absoluteErrors).sum()/np.square(np.abs(actual-actual.mean())).sum()\n", " counts[numGoodCBs] += 1\n", "\n", "mses, maes, nmses= sumMSEs/counts, sumMAEs/counts, sumNMSEs/counts\n", "print(f\"numGood: 0 1 2 3\" )\n", "print(f\"MSE: {mses[0]:.6f} {mses[1]:.6f} {mses[2]:.6f} {mses[3]:.6f}\" )\n", "print(f\"MAE: {maes[0]:.6f} {maes[1]:.6f} {maes[2]:.6f} {maes[3]:.6f}\" )\n", "print(f\"NMSE: {nmses[0]:.6f} {nmses[1]:.6f} {nmses[2]:.6f} {nmses[3]:.6f}\\n\" )\n", "\n", "rects = plt.bar(['DMRS Only', 'DMRS + \\n1 code-block', 'DMRS + \\n2 code-block', 'DMRS + \\n3 code-block'], nmses)\n", "plt.bar_label(rects, padding=1, fmt='%6.4f', fontsize=10)\n", "plt.title(\"Channel estimation accuracy when different number of code blocks are used as pseudo-pilots\");\n", "plt.ylabel(\"NMSE\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "f3cff234-7af2-4ca1-bd2c-ae9a90b6586a", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "1fedbd61-8615-45f4-9635-1ca846ee7f65", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.10" } }, "nbformat": 4, "nbformat_minor": 5 }