train CNN thành công

This commit is contained in:
Victor Phan
2026-04-04 02:16:36 +00:00
parent 93c7ae2ef3
commit 646b9300e1
34 changed files with 22636 additions and 0 deletions
+337
View File
@@ -0,0 +1,337 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "ac069784-fbb6-48c8-a547-11b96cade97b",
"metadata": {
"collapsed": true,
"jupyter": {
"outputs_hidden": true,
"source_hidden": true
},
"scrolled": true
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/ipykernel_218/1243805045.py:22: UserWarning: pandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy.\n",
" df = pd.read_sql(sql, conn)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" product_name total_images\n",
"0 s2_l2a 2074896\n",
"1 sentinel_2_c1_l2a 1137446\n",
"2 landsat7_c2l2_sr 169065\n",
"3 landsat7_c2l2_st 168410\n",
"4 landsat8_c2l2_sr 122846\n",
"5 landsat8_c2l2_st 120778\n",
"6 landsat5_c2l2_sr 118583\n",
"7 landsat5_c2l2_st 118406\n",
"8 landsat8_c2l1 111513\n",
"9 nasa_aqua_l2_oc 37232\n",
"10 landsat9_c2l2_sr 30214\n",
"11 landsat9_c2l2_st 29709\n",
"12 landsat9_c2l1 18875\n",
"13 nasa_aqua_l2_sst 12070\n",
"14 ga_ls_mangrove_cover_cyear_3 5580\n",
"15 sentinel1_grd_gamma0_10m_unsmooth 5488\n",
"16 sentinel1_grd_gamma0_20m 4260\n",
"17 copernicus_dem_30 1334\n",
"18 global_mangrove_soc_2020_30m 784\n",
"19 global_mangrove_soc_2000_30m 781\n",
"20 global_mangrove_canopy_height_2015_12m 761\n",
"21 sentinel1_grd_gamma0_10m 291\n",
"22 lpdaac_nasadem 264\n",
"23 cci_biomass_annual_v51 248\n",
"24 esa_worldcover_2020 184\n",
"25 esa_worldcover_2021 184\n",
"26 global_tidal_marsh_soc_30m 41\n",
"27 global_tidal_marsh_distribution_2020_10m 35\n",
"28 copernicus_dem_fiji 26\n",
"29 lpdaac_mod11a1v061_lste 2\n",
"30 global_mangrove_soc_2000_100m 1\n"
]
}
],
"source": [
"import psycopg2\n",
"import os\n",
"import pandas as pd\n",
"\n",
"# Kết nối (như cũ)\n",
"conn = psycopg2.connect(\n",
" host=os.environ.get('DB_HOSTNAME'),\n",
" user=os.environ.get('DB_USERNAME'),\n",
" password=os.environ.get('DB_PASSWORD'),\n",
" dbname=os.environ.get('DB_DATABASE')\n",
")\n",
"\n",
"# Đếm số lượng ảnh theo từng loại sản phẩm\n",
"sql = \"\"\"\n",
"SELECT t.name as product_name, count(*) as total_images\n",
"FROM agdc.dataset d\n",
"JOIN agdc.dataset_type t ON d.dataset_type_ref = t.id\n",
"GROUP BY t.name\n",
"ORDER BY total_images DESC;\n",
"\"\"\"\n",
"\n",
"df = pd.read_sql(sql, conn)\n",
"print(df)\n",
"conn.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a0ae4051-3bfd-49fd-83fe-4c31c74338e2",
"metadata": {},
"outputs": [],
"source": [
"import psycopg2\n",
"import os\n",
"\n",
"# 1. Lấy thông tin kết nối\n",
"db_host = os.environ.get('DB_HOSTNAME')\n",
"db_user = os.environ.get('DB_USERNAME')\n",
"db_pass = os.environ.get('DB_PASSWORD')\n",
"db_name = os.environ.get('DB_DATABASE')\n",
"\n",
"# 2. Danh sách các bảng cần lấy\n",
"tables = [\n",
" 'agdc.metadata_type',\n",
" 'agdc.dataset_type',\n",
" 'agdc.dataset_location',\n",
" 'agdc.dataset'\n",
"]\n",
"\n",
"print(\"Đang kết nối trực tiếp tới PostgreSQL...\")\n",
"\n",
"try:\n",
" # Kết nối trực tiếp (Bỏ qua Pandas/SQLAlchemy)\n",
" conn = psycopg2.connect(\n",
" host=db_host,\n",
" user=db_user,\n",
" password=db_pass,\n",
" dbname=db_name\n",
" )\n",
" cur = conn.cursor()\n",
" print(\"Kết nối thành công!\\n\")\n",
"\n",
" for table_name in tables:\n",
" print(f\"--> Đang xuất bảng: {table_name}\")\n",
" \n",
" # Tên file CSV đầu ra\n",
" file_name = table_name.split('.')[1] + \".csv\"\n",
" \n",
" # Sử dụng lệnh COPY chuyên dụng của Postgres (Cực nhanh và chuẩn)\n",
" # SQL: COPY (SELECT * FROM table) TO STDOUT WITH CSV HEADER\n",
" sql = f\"COPY (SELECT * FROM {table_name}) TO STDOUT WITH CSV HEADER\"\n",
" \n",
" with open(file_name, 'w') as f:\n",
" cur.copy_expert(sql, f)\n",
" \n",
" print(f\" Đã lưu xong: {file_name}\")\n",
"\n",
" cur.close()\n",
" conn.close()\n",
" print(\"\\nHOÀN TẤT! Bạn hãy tải 4 file CSV về máy.\")\n",
"\n",
"except Exception as e:\n",
" print(f\"\\nCÓ LỖI XẢY RA: {e}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d139879e-c350-4986-a2e6-0d59099eb770",
"metadata": {
"collapsed": true,
"jupyter": {
"outputs_hidden": true,
"source_hidden": true
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Đang kết nối...\n",
"Kết nối thành công! Đang ước lượng nhanh...\n",
"\n",
"--- BẢNG DỰ TÍNH DUNG LƯỢNG (ƯỚC LƯỢNG) ---\n",
"NĂM | SỐ ẢNH (ƯỚC TÍNH) | SIZE (CSV) \n",
"------------------------------------------------------------\n",
"2020 | ~ 21,448 | ~ 83.78 MB\n",
"2021 | ~ 21,448 | ~ 83.78 MB\n",
"2022 | ~ 21,448 | ~ 83.78 MB\n",
"2023 | ~ 21,448 | ~ 83.78 MB\n",
"2024 | ~ 21,448 | ~ 83.78 MB\n",
"------------------------------------------------------------\n",
"TỔNG CỘNG : ~ 107,240 ảnh (Khoảng 418.91 MB)\n",
"------------------------------------------------------------\n",
"(Lưu ý: Số liệu này là ước tính của Database, độ chính xác khoảng 80-90%)\n"
]
},
{
"name": "stdin",
"output_type": "stream",
"text": [
"\n",
"Bạn có muốn bắt đầu tải không? (y/n): y\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
">>> Đang tải bảng định nghĩa...\n",
"\n",
">>> Đang tải dữ liệu chính...\n",
"--> Năm 2020...\n"
]
}
],
"source": [
"import psycopg2\n",
"import os\n",
"import re # Thư viện xử lý chuỗi để lấy số liệu\n",
"\n",
"# --- CẤU HÌNH ---\n",
"YEARS = [2020, 2021, 2022, 2023, 2024]\n",
"AVG_ROW_SIZE_KB = 4 \n",
"\n",
"db_host = os.environ.get('DB_HOSTNAME')\n",
"db_user = os.environ.get('DB_USERNAME')\n",
"db_pass = os.environ.get('DB_PASSWORD')\n",
"db_name = os.environ.get('DB_DATABASE')\n",
"\n",
"print(\"Đang kết nối...\")\n",
"\n",
"try:\n",
" conn = psycopg2.connect(\n",
" host=db_host, user=db_user, password=db_pass, dbname=db_name\n",
" )\n",
" cur = conn.cursor()\n",
" print(\"Kết nối thành công! Đang ước lượng nhanh...\\n\")\n",
"\n",
" # ==========================================\n",
" # BƯỚC 1: ƯỚC LƯỢNG SIÊU TỐC (INSTANT ESTIMATE)\n",
" # ==========================================\n",
" print(\"--- BẢNG DỰ TÍNH DUNG LƯỢNG (ƯỚC LƯỢNG) ---\")\n",
" print(f\"{'NĂM':<10} | {'SỐ ẢNH (ƯỚC TÍNH)':<20} | {'SIZE (CSV)':<20}\")\n",
" print(\"-\" * 60)\n",
"\n",
" total_est_rows = 0\n",
"\n",
" for year in YEARS:\n",
" # Mẹo: Dùng EXPLAIN để lấy số liệu ước tính từ Query Planner\n",
" # Nó sẽ trả về chuỗi kiểu: \"Seq Scan on dataset ... (rows=12345 ...)\"\n",
" sql_estimate = f\"\"\"\n",
" EXPLAIN SELECT 1 FROM agdc.dataset\n",
" WHERE (metadata->'properties'->>'datetime')::timestamp >= '{year}-01-01'\n",
" AND (metadata->'properties'->>'datetime')::timestamp <= '{year}-12-31 23:59:59'\n",
" \"\"\"\n",
" cur.execute(sql_estimate)\n",
" explain_result = cur.fetchone()[0] # Lấy dòng đầu tiên của kết quả EXPLAIN\n",
" \n",
" # Dùng Regex để bắt lấy con số sau chữ \"rows=\"\n",
" match = re.search(r\"rows=(\\d+)\", explain_result)\n",
" if match:\n",
" count = int(match.group(1))\n",
" else:\n",
" count = 0 # Không bắt được số\n",
" \n",
" total_est_rows += count\n",
" est_size_mb = (count * AVG_ROW_SIZE_KB) / 1024\n",
" \n",
" print(f\"{year:<10} | ~ {count:<18,} | ~ {est_size_mb:.2f} MB\")\n",
"\n",
" print(\"-\" * 60)\n",
" print(f\"TỔNG CỘNG : ~ {total_est_rows:,} ảnh (Khoảng {(total_est_rows * AVG_ROW_SIZE_KB)/1024:.2f} MB)\")\n",
" print(\"-\" * 60)\n",
" print(\"(Lưu ý: Số liệu này là ước tính của Database, độ chính xác khoảng 80-90%)\")\n",
"\n",
" # ==========================================\n",
" # QUYẾT ĐỊNH TẢI\n",
" # ==========================================\n",
" check = input(\"\\nBạn có muốn bắt đầu tải không? (y/n): \")\n",
" if check.lower() != 'y':\n",
" print(\"Đã hủy.\")\n",
" exit()\n",
"\n",
" # ==========================================\n",
" # BƯỚC 2 & 3: TẢI DỮ LIỆU (Giữ nguyên logic cũ)\n",
" # ==========================================\n",
" # ... (Phần code tải small_tables và tải dữ liệu chính giữ nguyên như cũ) ...\n",
" # Để code gọn, mình viết tiếp phần tải ở dưới đây:\n",
" \n",
" # 2. Tải bảng nhỏ\n",
" print(\"\\n>>> Đang tải bảng định nghĩa...\")\n",
" for tb in ['agdc.metadata_type', 'agdc.dataset_type']:\n",
" f_name = tb.split('.')[1] + \".csv\"\n",
" with open(f_name, 'w') as f:\n",
" cur.copy_expert(f\"COPY (SELECT * FROM {tb}) TO STDOUT WITH CSV HEADER\", f)\n",
" \n",
" # 3. Tải dữ liệu chính\n",
" print(\"\\n>>> Đang tải dữ liệu chính...\")\n",
" for year in YEARS:\n",
" print(f\"--> Năm {year}...\")\n",
" \n",
" # Dataset\n",
" f_ds = f\"dataset_{year}.csv\"\n",
" sql_ds = f\"\"\"\n",
" COPY (SELECT * FROM agdc.dataset \n",
" WHERE (metadata->'properties'->>'datetime')::timestamp >= '{year}-01-01' \n",
" AND (metadata->'properties'->>'datetime')::timestamp <= '{year}-12-31 23:59:59'\n",
" ) TO STDOUT WITH CSV HEADER\"\"\"\n",
" with open(f_ds, 'w') as f: cur.copy_expert(sql_ds, f)\n",
" \n",
" # Location\n",
" f_loc = f\"dataset_location_{year}.csv\"\n",
" sql_loc = f\"\"\"\n",
" COPY (SELECT l.* FROM agdc.dataset_location l JOIN agdc.dataset d ON l.dataset_ref = d.id\n",
" WHERE (d.metadata->'properties'->>'datetime')::timestamp >= '{year}-01-01' \n",
" AND (d.metadata->'properties'->>'datetime')::timestamp <= '{year}-12-31 23:59:59'\n",
" ) TO STDOUT WITH CSV HEADER\"\"\"\n",
" with open(f_loc, 'w') as f: cur.copy_expert(sql_loc, f)\n",
" \n",
" print(\"\\nHOÀN TẤT TOÀN BỘ!\")\n",
" cur.close()\n",
" conn.close()\n",
"\n",
"except Exception as e:\n",
" print(f\"\\nCÓ LỖI: {e}\")"
]
}
],
"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.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}