{ "cells": [ { "cell_type": "markdown", "id": "2924c91c", "metadata": {}, "source": [ "# Predict with CNN Model (PyTorch) for Land Use Classification\n", "Dự đoán sử dụng đất bằng mô hình CNN đã huấn luyện" ] }, { "cell_type": "code", "execution_count": null, "id": "70281ab3", "metadata": {}, "outputs": [], "source": [ "%%time\n", "%matplotlib inline\n", "\n", "import importlib\n", "import new_import_ODC \n", "\n", "importlib.reload(new_import_ODC)\n", "\n", "from new_import_ODC import *" ] }, { "cell_type": "code", "execution_count": null, "id": "22176418", "metadata": {}, "outputs": [], "source": [ "# Kiểm tra GPU availability\n", "print(f\"PyTorch version: {torch.__version__}\")\n", "print(f\"CUDA available: {torch.cuda.is_available()}\")\n", "if torch.cuda.is_available():\n", " print(f\"CUDA device: {torch.cuda.get_device_name(0)}\")\n", " device = 'cuda'\n", "else:\n", " print(\"Using CPU for inference\")\n", " device = 'cpu'\n", "\n", "print(f\"\\nDevice sẽ dùng: {device}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "e3df417f", "metadata": {}, "outputs": [], "source": [ "%%time\n", "# Cấu hình Daskgateway\n", "cluster, client = notebook_utils.initialize_dask(use_gateway=True, workers=(1, 10))\n", "# Khai báo 1 Datacube là dc\n", "dc = datacube.Datacube()\n", "\n", "# Cấu hình truy cập dịch vụ S3\n", "configure_s3_access(aws_unsigned=False, requester_pays=True, client=client)\n", "\n", "client" ] }, { "cell_type": "code", "execution_count": null, "id": "89949cac", "metadata": {}, "outputs": [], "source": [ "## cấu hình thời gian lấy ảnh và tọa độ\n", "date_range = (\"2022-09-01\", \"2023-10-01\")\n", "longtitude_range = (105.5, 106.4)\n", "latitude_range = (9.2, 10.0)\n", "\n", "coordinates = (longtitude_range, latitude_range)" ] }, { "cell_type": "code", "execution_count": null, "id": "6ce973de", "metadata": {}, "outputs": [], "source": [ "## truy vấn ảnh vệ tinh sen2\n", "data = load_data(dc, date_range, longtitude_range, latitude_range)\n", "notebook_utils.heading(notebook_utils.xarray_object_size(data))\n", "display(data)" ] }, { "cell_type": "code", "execution_count": null, "id": "26e449ba", "metadata": {}, "outputs": [], "source": [ "%%time\n", "# Tiến hành loại bỏ các vị trí bị mây ảnh hưởng\n", "result = mask_clean(data)\n", "progress(result)" ] }, { "cell_type": "code", "execution_count": null, "id": "ab88b2ba", "metadata": {}, "outputs": [], "source": [ "# Tiến hành tính toán NDVI\n", "ds1 = calculate_indices(result, index=\"NDVI\", satellite_mission=\"s2\")\n", "ndvi = ds1[\"NDVI\"]\n", "display(ndvi)" ] }, { "cell_type": "code", "execution_count": null, "id": "bc3f5e11", "metadata": {}, "outputs": [], "source": [ "# Thiết lập giá trị trung bình mùa vụ để xử lý các điểm ảnh bị mây dựa vào sự thay đổi theo mùa\n", "time_split = [\n", " slice(\"2022-09-01\", \"2023-01-01\"),\n", " slice(\"2023-01-01\", \"2023-05-01\"),\n", " slice(\"2023-05-01\", \"2023-07-01\"),\n", " slice(\"2023-07-01\", \"2023-10-01\"),\n", "]\n", "\n", "# Điền mây ở các vị trí mang giá trị nan (fill nan)\n", "fill_nan_ndvi = fill_nan(ndvi, time_split)" ] }, { "cell_type": "code", "execution_count": null, "id": "5287a3f5", "metadata": {}, "outputs": [], "source": [ "%%time\n", "## tính ndvi theo tháng\n", "average_ndvi = fill_nan_ndvi.resample(time=\"1M\").mean().persist()\n", "progress(average_ndvi)\n", "\n", "# compute average_ndvi\n", "average_ndvi = average_ndvi.compute()" ] }, { "cell_type": "code", "execution_count": null, "id": "a53659c8", "metadata": {}, "outputs": [], "source": [ "#Load dữ liệu ảnh Sentinel 1\n", "dsvh, dsvv = load_data_sen1(dc, date_range, coordinates)\n", "average_vv = calculate_average(dsvv, time_pattern='1M')\n", "average_vh = calculate_average(dsvh, time_pattern='1M')" ] }, { "cell_type": "markdown", "id": "d5747aa2", "metadata": {}, "source": [ "## Tải model đã huấn luyện" ] }, { "cell_type": "code", "execution_count": null, "id": "c7a31255", "metadata": {}, "outputs": [], "source": [ "# Tải model CNN PyTorch\n", "model, scaler = load_pytorch_model(model_name=\"model_cnn_pytorch.pth\", device=device)\n", "model.eval()\n", "print(f\"\\n✅ Model đã được tải thành công\")" ] }, { "cell_type": "markdown", "id": "410d37ad", "metadata": {}, "source": [ "## Dự đoán cho toàn bộ khu vực" ] }, { "cell_type": "code", "execution_count": null, "id": "11ed8e1f", "metadata": {}, "outputs": [], "source": [ "%%time\n", "# Chuẩn bị dữ liệu dự đoán\n", "print(\"🔷 Chuẩn bị dữ liệu dự đoán...\")\n", "\n", "# Lấy kích thước của ảnh\n", "num_y = average_ndvi.shape[1]\n", "num_x = average_ndvi.shape[2]\n", "\n", "print(f\"Kích thước ảnh: {num_y} x {num_x}\")\n", "\n", "# Chuẩn bị dữ liệu dự đoán\n", "predictions = []\n", "\n", "print(f\"\\n🔍 Dự đoán từng pixel...\")\n", "batch_size = 128\n", "\n", "with torch.no_grad():\n", " for y_idx in range(num_y):\n", " y_predictions = []\n", " \n", " # Lấy dữ liệu cho từng hàng (row)\n", " ndvi_row = average_ndvi.isel(y=y_idx).values # shape: (time, x)\n", " vh_row = average_vh.sel(y=average_ndvi.y.values[y_idx], method='nearest').values # shape: (time, x)\n", " vv_row = average_vv.sel(y=average_ndvi.y.values[y_idx], method='nearest').values # shape: (time, x)\n", " \n", " # Xử lý theo batch\n", " for x_idx in range(0, num_x, batch_size):\n", " x_end = min(x_idx + batch_size, num_x)\n", " batch_size_actual = x_end - x_idx\n", " \n", " # Tạo batch data\n", " batch_data = np.zeros((batch_size_actual, ndvi_row.shape[0] * 3))\n", " \n", " for idx, x_i in enumerate(range(x_idx, x_end)):\n", " ndvi_data = ndvi_row[:, x_i]\n", " vh_data = vh_row[:, x_i]\n", " vv_data = vv_row[:, x_i]\n", " batch_data[idx, :] = np.concatenate((ndvi_data, vh_data, vv_data))\n", " \n", " # Normalize dữ liệu\n", " batch_data_scaled = scaler.transform(batch_data)\n", " batch_data_reshaped = batch_data_scaled.reshape(batch_size_actual, 1, -1)\n", " \n", " # Convert to tensor\n", " batch_tensor = torch.FloatTensor(batch_data_reshaped).to(device)\n", " \n", " # Dự đoán\n", " outputs = model(batch_tensor)\n", " _, predicted = torch.max(outputs.data, 1)\n", " \n", " y_predictions.extend(predicted.cpu().numpy().tolist())\n", " \n", " predictions.extend(y_predictions)\n", " \n", " if (y_idx + 1) % 100 == 0:\n", " print(f\" Đã xử lý {y_idx + 1}/{num_y} hàng...\")\n", "\n", "# Reshape predictions\n", "predictions = np.array(predictions).reshape(num_y, num_x)\n", "print(f\"\\n✅ Hoàn thành dự đoán!\")\n", "print(f\" Shape: {predictions.shape}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "48b49f89", "metadata": {}, "outputs": [], "source": [ "# Tạo xarray DataArray từ predictions\n", "final_label = predictions\n", "final_xarray_save = xr.DataArray(final_label, dims=(\"y\", \"x\"))\n", "final_xarray_save = final_xarray_save.rio.write_crs(average_ndvi.rio.crs)\n", "\n", "x_values = average_ndvi.x.values\n", "y_values = average_ndvi.y.values\n", "\n", "data_array = xr.DataArray(final_xarray_save,\n", " coords={'x': x_values, 'y': y_values},\n", " dims=['y', 'x'])\n", "data_array = data_array.rio.write_crs(average_ndvi.rio.crs)\n", "\n", "print(f\"✅ DataArray tạo thành công\")\n", "print(f\" Shape: {data_array.shape}\")\n", "print(f\" CRS: {data_array.rio.crs}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "9fe5062c", "metadata": {}, "outputs": [], "source": [ "# Hiển thị kết quả dự đoán\n", "fig, ax = plt.subplots(figsize=(12, 10))\n", "\n", "# Cấu hình colormap\n", "cmap = plt.cm.get_cmap('tab10')\n", "im = ax.imshow(data_array.values, cmap=cmap, interpolation='nearest')\n", "\n", "# Tạo colorbar\n", "cbar = plt.colorbar(im, ax=ax, label='Land Use Class')\n", "cbar.set_ticks([0, 1, 2, 3, 4, 5, 6, 7])\n", "cbar.set_ticklabels(['Lua tom', 'Lua', 'CHN', 'CLN', 'TS', 'Song', 'Dat xay dung', 'Rung'])\n", "\n", "ax.set_title('Land Use Classification Map (CNN PyTorch)', fontsize=14, fontweight='bold')\n", "ax.set_xlabel('X coordinate')\n", "ax.set_ylabel('Y coordinate')\n", "\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "32d9f9f6", "metadata": {}, "outputs": [], "source": [ "# Lưu kết quả dự đoán\n", "output_path = \"prediction_results/classification_map_cnn_pytorch.tif\"\n", "os.makedirs(\"prediction_results\", exist_ok=True)\n", "\n", "data_array.rio.to_raster(output_path)\n", "print(f\"✅ Kết quả đã lưu tại: {output_path}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "7a2abb2b", "metadata": {}, "outputs": [], "source": [ "# đóng client, cluster\n", "client.close()\n", "cluster.close()" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }