mirror of
https://git.victorphan.net/basketballcantho/CSIROBoeingPhase5-Vietnam.git
synced 2026-08-05 13:43:11 +07:00
358 lines
10 KiB
Plaintext
358 lines
10 KiB
Plaintext
{
|
|
"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
|
|
}
|