MAE_ATMO/torch_GAN_1d_baseline.ipynb

1011 lines
93 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"id": "8252a3af-edbb-4dcf-967c-fe206e98ceab",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import torch\n",
"import torch.nn as nn\n",
"import torch.optim as optim\n",
"from torch.utils.data import DataLoader, Dataset\n",
"from PIL import Image\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n",
"os.environ[\"CUDA_VISIBLE_DEVICE\"] = \"0\" "
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "8f8c3fd5-f70f-45d0-886a-c572895ffcee",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using device: cuda\n"
]
}
],
"source": [
"# 设置CUDA设备\n",
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
"print(f\"Using device: {device}\")"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "d15a7732-b516-4054-905f-0e7d57e4a38e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Maximum pixel value in the dataset: 107.49169921875\n"
]
}
],
"source": [
"# 定义函数来找到最大值\n",
"def find_max_pixel_value(image_dir):\n",
" max_pixel_value = 0.0\n",
" for filename in os.listdir(image_dir):\n",
" if filename.endswith('.npy'):\n",
" image_path = os.path.join(image_dir, filename)\n",
" image = np.load(image_path).astype(np.float32)\n",
" max_pixel_value = max(max_pixel_value, image[:, :, 0].max())\n",
" return max_pixel_value\n",
"\n",
"# 计算图像数据中的最大像素值\n",
"image_dir = './out_mat/96/train/' \n",
"max_pixel_value = 107.49169921875\n",
"\n",
"print(f\"Maximum pixel value in the dataset: {max_pixel_value}\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "bc01ab26-2bd1-4adb-9d6d-5080e32ac1b5",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<torch._C.Generator at 0x7f7a40059f90>"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.seed(42)\n",
"torch.random.manual_seed(42)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "69ac2ad4-0e7c-42b8-b4cf-1149b447c3e4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"checkpoint before Generator is OK\n"
]
}
],
"source": [
"class NO2Dataset(Dataset):\n",
" \n",
" def __init__(self, image_dir, mask_dir):\n",
" \n",
" self.image_dir = image_dir\n",
" self.mask_dir = mask_dir\n",
" self.image_filenames = [f for f in os.listdir(image_dir) if f.endswith('.npy')] # 仅加载 .npy 文件\n",
" self.mask_filenames = [f for f in os.listdir(mask_dir) if f.endswith('.jpg')] # 仅加载 .jpg 文件\n",
" \n",
" def __len__(self):\n",
" \n",
" return len(self.image_filenames)\n",
" \n",
" def __getitem__(self, idx):\n",
" \n",
" image_path = os.path.join(self.image_dir, self.image_filenames[idx])\n",
" mask_idx = np.random.choice(self.mask_filenames)\n",
" mask_path = os.path.join(self.mask_dir, mask_idx)\n",
"\n",
" # 加载图像数据 (.npy 文件)\n",
" image = np.load(image_path).astype(np.float32)[:,:,:1] / max_pixel_value # 形状为 (96, 96, 8)\n",
"\n",
" # 加载掩码数据 (.jpg 文件)\n",
" mask = np.array(Image.open(mask_path).convert('L')).astype(np.float32)\n",
"\n",
" # 将掩码数据中非0值设为10值保持不变\n",
" mask = np.where(mask != 0, 1.0, 0.0)\n",
"\n",
" # 保持掩码数据形状为 (96, 96, 1)\n",
" mask = mask[:, :, np.newaxis] # 将形状调整为 (96, 96, 1)\n",
"\n",
" # 应用掩码\n",
" masked_image = image.copy()\n",
" masked_image[:, :, 0] = image[:, :, 0] * mask.squeeze() # 遮盖NO2数据\n",
"\n",
" # cGAN的输入和目标\n",
" X = np.concatenate([masked_image[:, :, :1], image[:, :, 1:]], axis=-1) # 形状为 (96, 96, 8)\n",
" y = image[:, :, 0:1] # 目标输出为NO2数据形状为 (96, 96, 1)\n",
"\n",
" # 转换形状为 (channels, height, width)\n",
" X = np.transpose(X, (2, 0, 1)) # 转换为 (8, 96, 96)\n",
" y = np.transpose(y, (2, 0, 1)) # 转换为 (1, 96, 96)\n",
" mask = np.transpose(mask, (2, 0, 1)) # 转换为 (1, 96, 96)\n",
"\n",
" return torch.tensor(X, dtype=torch.float32), torch.tensor(y, dtype=torch.float32), torch.tensor(mask, dtype=torch.float32)\n",
"\n",
"# 实例化数据集和数据加载器\n",
"image_dir = './out_mat/96/train/'\n",
"mask_dir = './out_mat/96/mask/20/'\n",
"\n",
"print(f\"checkpoint before Generator is OK\")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "305f2522-bcb0-46b1-8cb1-ebb5a821db7b",
"metadata": {},
"outputs": [],
"source": [
"dataset = NO2Dataset(image_dir, mask_dir)\n",
"dataloader = DataLoader(dataset, batch_size=64, shuffle=True, num_workers=8)\n",
"\n",
"# 生成器模型\n",
"class Generator(nn.Module):\n",
" \n",
" def __init__(self):\n",
" super(Generator, self).__init__()\n",
" self.encoder = nn.Sequential(\n",
" nn.Conv2d(1, 64, kernel_size=4, stride=2, padding=1),\n",
" nn.LeakyReLU(0.2, inplace=True),\n",
" nn.BatchNorm2d(64),\n",
" nn.Conv2d(64, 128, kernel_size=4, stride=2, padding=1),\n",
" nn.LeakyReLU(0.2, inplace=True),\n",
" nn.BatchNorm2d(128),\n",
" )\n",
" self.decoder = nn.Sequential(\n",
" nn.ConvTranspose2d(128, 64, kernel_size=4, stride=2, padding=1),\n",
" nn.ReLU(inplace=True),\n",
" nn.BatchNorm2d(64),\n",
" nn.ConvTranspose2d(64, 1, kernel_size=4, stride=2, padding=1),\n",
" nn.Tanh(),\n",
" )\n",
"\n",
" def forward(self, x, mask):\n",
" x_encoded = self.encoder(x)\n",
" x_decoded = self.decoder(x_encoded)\n",
"\n",
" x_decoded = (x_decoded + 1) / 2\n",
"\n",
" x_output = (1 - mask) * x_decoded + mask * x[:, :1, :, :]\n",
" return x_output\n",
"\n",
"# 判别器模型\n",
"class Discriminator(nn.Module):\n",
" \n",
" def __init__(self):\n",
" super(Discriminator, self).__init__()\n",
" self.model = nn.Sequential(\n",
" nn.Conv2d(2, 64, kernel_size=4, stride=2, padding=1),\n",
" nn.LeakyReLU(0.2, inplace=True),\n",
" nn.BatchNorm2d(64),\n",
" nn.Conv2d(64, 128, kernel_size=4, stride=2, padding=1),\n",
" nn.LeakyReLU(0.2, inplace=True),\n",
" nn.BatchNorm2d(128),\n",
" nn.Conv2d(128, 1, kernel_size=4, stride=2, padding=1),\n",
" nn.Sigmoid(),\n",
" )\n",
"\n",
" def forward(self, x):\n",
" return self.model(x)\n",
"\n",
"# 将模型加载到GPU\n",
"generator = Generator().to(device)\n",
"discriminator = Discriminator().to(device)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "881b9b78-4e03-406c-8af3-d9a749350508",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generator is on: cuda:0\n",
"Discriminator is on: cuda:0\n"
]
}
],
"source": [
"# 定义优化器和损失函数\n",
"optimizer_G = optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))\n",
"optimizer_D = optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))\n",
"adversarial_loss = nn.BCELoss().to(device)\n",
"pixelwise_loss = nn.MSELoss().to(device)\n",
"\n",
"# 确认模型是否在GPU上\n",
"print(f\"Generator is on: {next(generator.parameters()).device}\")\n",
"print(f\"Discriminator is on: {next(discriminator.parameters()).device}\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "b85fcbe7-ed61-40a7-8259-19f2fa71b056",
"metadata": {},
"outputs": [],
"source": [
"gen = torch.load('./models/GAN/generator.pth', map_location='cpu')\n",
"generator.load_state_dict(gen)\n",
"generator = generator.to('cpu')"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "55a55f48-77ff-4ef7-9b79-9e98798d7c4d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<All keys matched successfully>"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dis = torch.load('./models/GAN/discriminator.pth', map_location='cpu')\n",
"discriminator.load_state_dict(dis)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "d15f91ca-1bb1-464c-a937-8bdd13c6a1ee",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/root/miniconda3/envs/python38/lib/python3.8/site-packages/torch/nn/modules/conv.py:456: UserWarning: Applied workaround for CuDNN issue, install nvrtc.so (Triggered internally at /opt/conda/conda-bld/pytorch_1711403590347/work/aten/src/ATen/native/cudnn/Conv_v8.cpp:80.)\n",
" return F.conv2d(input, weight, bias, self.stride,\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch [0/300] [D loss: 0.5392551422119141] [G loss: 0.9313964247703552]\n",
"Epoch [1/300] [D loss: 0.45492202043533325] [G loss: 1.5053317546844482]\n",
"Epoch [2/300] [D loss: 0.3420121669769287] [G loss: 1.4923288822174072]\n",
"Epoch [3/300] [D loss: 0.2960708737373352] [G loss: 1.955796480178833]\n",
"Epoch [4/300] [D loss: 0.40790891647338867] [G loss: 2.071624279022217]\n",
"Epoch [5/300] [D loss: 0.2747359275817871] [G loss: 1.917580485343933]\n",
"Epoch [6/300] [D loss: 0.47008591890335083] [G loss: 1.5003858804702759]\n",
"Epoch [7/300] [D loss: 0.19478999078273773] [G loss: 3.949864149093628]\n",
"Epoch [8/300] [D loss: 0.5340784192085266] [G loss: 0.8913870453834534]\n",
"Epoch [9/300] [D loss: 0.3194230794906616] [G loss: 1.861933946609497]\n",
"Epoch [10/300] [D loss: 0.22022968530654907] [G loss: 1.6654534339904785]\n",
"Epoch [11/300] [D loss: 0.3743482828140259] [G loss: 1.626413106918335]\n",
"Epoch [12/300] [D loss: 0.13774043321609497] [G loss: 3.187469482421875]\n",
"Epoch [13/300] [D loss: 0.4275822043418884] [G loss: 2.2269718647003174]\n",
"Epoch [14/300] [D loss: 0.22367843985557556] [G loss: 2.707667827606201]\n",
"Epoch [15/300] [D loss: 0.25350409746170044] [G loss: 1.6780041456222534]\n",
"Epoch [16/300] [D loss: 0.23647311329841614] [G loss: 1.6349072456359863]\n",
"Epoch [17/300] [D loss: 0.5604373812675476] [G loss: 2.025310754776001]\n",
"Epoch [18/300] [D loss: 0.4707084596157074] [G loss: 2.938746452331543]\n",
"Epoch [19/300] [D loss: 0.2135343998670578] [G loss: 1.438072919845581]\n",
"Epoch [20/300] [D loss: 0.08090662956237793] [G loss: 2.77827787399292]\n",
"Epoch [21/300] [D loss: 0.2995302677154541] [G loss: 2.239123821258545]\n",
"Epoch [22/300] [D loss: 0.45718979835510254] [G loss: 3.404195547103882]\n",
"Epoch [23/300] [D loss: 0.13950982689857483] [G loss: 2.7335846424102783]\n",
"Epoch [24/300] [D loss: 0.1814766675233841] [G loss: 2.7603776454925537]\n",
"Epoch [25/300] [D loss: 0.0551619790494442] [G loss: 4.066004276275635]\n",
"Epoch [26/300] [D loss: 0.1498052179813385] [G loss: 2.733922243118286]\n",
"Epoch [27/300] [D loss: 0.11236032098531723] [G loss: 3.215831756591797]\n",
"Epoch [28/300] [D loss: 0.4945942461490631] [G loss: 1.9661915302276611]\n",
"Epoch [29/300] [D loss: 0.0760776624083519] [G loss: 2.7212204933166504]\n",
"Epoch [30/300] [D loss: 0.19911707937717438] [G loss: 1.5356297492980957]\n",
"Epoch [31/300] [D loss: 0.0900304988026619] [G loss: 2.84740948677063]\n",
"Epoch [32/300] [D loss: 0.05910511314868927] [G loss: 4.071162223815918]\n",
"Epoch [33/300] [D loss: 0.0711229220032692] [G loss: 2.716848373413086]\n",
"Epoch [34/300] [D loss: 0.39897823333740234] [G loss: 1.5674937963485718]\n",
"Epoch [35/300] [D loss: 0.05552360787987709] [G loss: 3.754516124725342]\n",
"Epoch [36/300] [D loss: 0.5413599014282227] [G loss: 4.129798889160156]\n",
"Epoch [37/300] [D loss: 0.17664434015750885] [G loss: 4.226540565490723]\n",
"Epoch [38/300] [D loss: 0.15215317904949188] [G loss: 2.6023881435394287]\n",
"Epoch [39/300] [D loss: 0.07798739522695541] [G loss: 4.075980186462402]\n",
"Epoch [40/300] [D loss: 0.03936776518821716] [G loss: 4.37988805770874]\n",
"Epoch [41/300] [D loss: 0.2012120634317398] [G loss: 2.1987271308898926]\n",
"Epoch [42/300] [D loss: 0.05274203419685364] [G loss: 3.8458642959594727]\n",
"Epoch [43/300] [D loss: 0.13967157900333405] [G loss: 3.438344955444336]\n",
"Epoch [44/300] [D loss: 0.05800560116767883] [G loss: 2.941135883331299]\n",
"Epoch [45/300] [D loss: 0.14671097695827484] [G loss: 3.388277292251587]\n",
"Epoch [46/300] [D loss: 0.06439051032066345] [G loss: 2.9789438247680664]\n",
"Epoch [47/300] [D loss: 0.11101078987121582] [G loss: 2.6266937255859375]\n",
"Epoch [48/300] [D loss: 0.028554894030094147] [G loss: 4.042592525482178]\n",
"Epoch [49/300] [D loss: 0.3364626169204712] [G loss: 3.419842004776001]\n",
"Epoch [50/300] [D loss: 0.2501979470252991] [G loss: 3.319307804107666]\n",
"Epoch [51/300] [D loss: 0.2962917387485504] [G loss: 5.088353157043457]\n",
"Epoch [52/300] [D loss: 0.07700179517269135] [G loss: 3.231515884399414]\n",
"Epoch [53/300] [D loss: 0.4093267321586609] [G loss: 1.918235182762146]\n",
"Epoch [54/300] [D loss: 0.12105419486761093] [G loss: 2.3409922122955322]\n",
"Epoch [55/300] [D loss: 0.057456158101558685] [G loss: 4.047771453857422]\n",
"Epoch [56/300] [D loss: 0.250449538230896] [G loss: 1.9442336559295654]\n",
"Epoch [57/300] [D loss: 0.08125491440296173] [G loss: 2.7323458194732666]\n",
"Epoch [58/300] [D loss: 0.06671395897865295] [G loss: 3.081458330154419]\n",
"Epoch [59/300] [D loss: 0.06982511281967163] [G loss: 3.95278000831604]\n",
"Epoch [60/300] [D loss: 0.08973922580480576] [G loss: 3.9550158977508545]\n",
"Epoch [61/300] [D loss: 0.29226893186569214] [G loss: 2.2824535369873047]\n",
"Epoch [62/300] [D loss: 0.06800767779350281] [G loss: 4.67025089263916]\n",
"Epoch [63/300] [D loss: 0.017987174913287163] [G loss: 4.119121551513672]\n",
"Epoch [64/300] [D loss: 0.1278763711452484] [G loss: 4.481695652008057]\n",
"Epoch [65/300] [D loss: 0.12277506291866302] [G loss: 2.0188961029052734]\n",
"Epoch [66/300] [D loss: 0.10042040050029755] [G loss: 4.019499778747559]\n",
"Epoch [67/300] [D loss: 0.15092261135578156] [G loss: 3.0588033199310303]\n",
"Epoch [68/300] [D loss: 0.157196044921875] [G loss: 4.579256534576416]\n",
"Epoch [69/300] [D loss: 0.0256386436522007] [G loss: 4.309335708618164]\n",
"Epoch [70/300] [D loss: 0.011956267058849335] [G loss: 4.763312816619873]\n",
"Epoch [71/300] [D loss: 0.08460590243339539] [G loss: 5.456184387207031]\n",
"Epoch [72/300] [D loss: 0.07495025545358658] [G loss: 3.5078511238098145]\n",
"Epoch [73/300] [D loss: 0.13037167489528656] [G loss: 3.164292812347412]\n",
"Epoch [74/300] [D loss: 0.0830327719449997] [G loss: 5.159647464752197]\n",
"Epoch [75/300] [D loss: 0.4353921115398407] [G loss: 5.0652875900268555]\n",
"Epoch [76/300] [D loss: 0.02432486228644848] [G loss: 3.7066524028778076]\n",
"Epoch [77/300] [D loss: 0.2809848189353943] [G loss: 1.1604290008544922]\n",
"Epoch [78/300] [D loss: 0.7653636932373047] [G loss: 2.5745716094970703]\n",
"Epoch [79/300] [D loss: 0.041840165853500366] [G loss: 4.082228660583496]\n",
"Epoch [80/300] [D loss: 0.03992146998643875] [G loss: 4.9236321449279785]\n",
"Epoch [81/300] [D loss: 0.1003192886710167] [G loss: 2.683060646057129]\n",
"Epoch [82/300] [D loss: 0.1460535228252411] [G loss: 4.597597122192383]\n",
"Epoch [83/300] [D loss: 0.1408858597278595] [G loss: 1.8829160928726196]\n",
"Epoch [84/300] [D loss: 0.048089221119880676] [G loss: 3.1438090801239014]\n",
"Epoch [85/300] [D loss: 0.041934601962566376] [G loss: 3.298645257949829]\n",
"Epoch [86/300] [D loss: 0.1363355964422226] [G loss: 2.6124517917633057]\n",
"Epoch [87/300] [D loss: 0.03299988433718681] [G loss: 3.3402161598205566]\n",
"Epoch [88/300] [D loss: 0.22786922752857208] [G loss: 3.9778051376342773]\n",
"Epoch [89/300] [D loss: 0.021804900839924812] [G loss: 4.595890045166016]\n",
"Epoch [90/300] [D loss: 0.022495444864034653] [G loss: 4.2465901374816895]\n",
"Epoch [91/300] [D loss: 0.02908019907772541] [G loss: 6.379057884216309]\n",
"Epoch [92/300] [D loss: 0.6523040533065796] [G loss: 0.6009750962257385]\n",
"Epoch [93/300] [D loss: 0.007557982578873634] [G loss: 5.837783336639404]\n",
"Epoch [94/300] [D loss: 0.020063551142811775] [G loss: 4.044745445251465]\n",
"Epoch [95/300] [D loss: 0.003706925082951784] [G loss: 8.243224143981934]\n",
"Epoch [96/300] [D loss: 0.021942533552646637] [G loss: 4.662309169769287]\n",
"Epoch [97/300] [D loss: 0.005410192534327507] [G loss: 5.5743536949157715]\n",
"Epoch [98/300] [D loss: 0.07137680053710938] [G loss: 3.261455535888672]\n",
"Epoch [99/300] [D loss: 0.11327817291021347] [G loss: 3.817570686340332]\n",
"Epoch [100/300] [D loss: 0.04488084092736244] [G loss: 4.458094596862793]\n",
"Epoch [101/300] [D loss: 0.05757671222090721] [G loss: 3.695896625518799]\n",
"Epoch [102/300] [D loss: 0.04083157703280449] [G loss: 3.704172134399414]\n",
"Epoch [103/300] [D loss: 0.02816752716898918] [G loss: 4.322700023651123]\n",
"Epoch [104/300] [D loss: 0.026689285412430763] [G loss: 4.115890979766846]\n",
"Epoch [105/300] [D loss: 0.03571446239948273] [G loss: 4.080765724182129]\n",
"Epoch [106/300] [D loss: 0.020453810691833496] [G loss: 5.457651615142822]\n",
"Epoch [107/300] [D loss: 0.03774755448102951] [G loss: 5.34019136428833]\n",
"Epoch [108/300] [D loss: 0.0933525487780571] [G loss: 5.5797905921936035]\n",
"Epoch [109/300] [D loss: 0.024301748722791672] [G loss: 4.042290210723877]\n",
"Epoch [110/300] [D loss: 0.9034162759780884] [G loss: 5.52556848526001]\n",
"Epoch [111/300] [D loss: 0.0911281406879425] [G loss: 6.487083911895752]\n",
"Epoch [112/300] [D loss: 0.13892149925231934] [G loss: 3.0797510147094727]\n",
"Epoch [113/300] [D loss: 0.09627098590135574] [G loss: 3.104957103729248]\n",
"Epoch [114/300] [D loss: 0.007696065586060286] [G loss: 6.618851184844971]\n",
"Epoch [115/300] [D loss: 0.06528083980083466] [G loss: 3.4506514072418213]\n",
"Epoch [116/300] [D loss: 0.03879600390791893] [G loss: 3.3708789348602295]\n",
"Epoch [117/300] [D loss: 0.03395622968673706] [G loss: 6.2684736251831055]\n",
"Epoch [118/300] [D loss: 0.010569067671895027] [G loss: 5.944631099700928]\n",
"Epoch [119/300] [D loss: 0.024817001074552536] [G loss: 6.614266872406006]\n",
"Epoch [120/300] [D loss: 0.013173197396099567] [G loss: 6.226423263549805]\n",
"Epoch [121/300] [D loss: 0.06546411663293839] [G loss: 3.0585291385650635]\n",
"Epoch [122/300] [D loss: 0.01085597462952137] [G loss: 6.437295913696289]\n",
"Epoch [123/300] [D loss: 0.03522876650094986] [G loss: 4.0734052658081055]\n",
"Epoch [124/300] [D loss: 0.06875205039978027] [G loss: 4.0921711921691895]\n",
"Epoch [125/300] [D loss: 0.006707158405333757] [G loss: 5.244316577911377]\n",
"Epoch [126/300] [D loss: 0.03866109997034073] [G loss: 3.368199110031128]\n",
"Epoch [127/300] [D loss: 0.041117191314697266] [G loss: 4.484440326690674]\n",
"Epoch [128/300] [D loss: 0.0829429179430008] [G loss: 4.554262638092041]\n",
"Epoch [129/300] [D loss: 0.03219084441661835] [G loss: 5.4280924797058105]\n",
"Epoch [130/300] [D loss: 0.11037464439868927] [G loss: 5.89276647567749]\n",
"Epoch [131/300] [D loss: 0.029911085963249207] [G loss: 4.116299629211426]\n",
"Epoch [132/300] [D loss: 0.14276768267154694] [G loss: 2.059661626815796]\n",
"Epoch [133/300] [D loss: 0.06751281768083572] [G loss: 4.1591362953186035]\n",
"Epoch [134/300] [D loss: 0.06710615009069443] [G loss: 3.1725471019744873]\n",
"Epoch [135/300] [D loss: 0.015449777245521545] [G loss: 5.900448799133301]\n",
"Epoch [136/300] [D loss: 0.0017297605518251657] [G loss: 6.8876633644104]\n",
"Epoch [137/300] [D loss: 0.10661254078149796] [G loss: 3.035740613937378]\n",
"Epoch [138/300] [D loss: 0.04841696843504906] [G loss: 3.2598555088043213]\n",
"Epoch [139/300] [D loss: 0.13029193878173828] [G loss: 3.732114791870117]\n",
"Epoch [140/300] [D loss: 0.01422959566116333] [G loss: 4.98042106628418]\n",
"Epoch [141/300] [D loss: 0.15487617254257202] [G loss: 5.367415428161621]\n",
"Epoch [142/300] [D loss: 0.07540086656808853] [G loss: 4.3357768058776855]\n",
"Epoch [143/300] [D loss: 0.014456328004598618] [G loss: 4.569247245788574]\n",
"Epoch [144/300] [D loss: 0.012367785908281803] [G loss: 5.9672956466674805]\n",
"Epoch [145/300] [D loss: 0.05262265354394913] [G loss: 5.160377502441406]\n",
"Epoch [146/300] [D loss: 0.08042960613965988] [G loss: 3.7927441596984863]\n",
"Epoch [147/300] [D loss: 0.19245359301567078] [G loss: 3.8005473613739014]\n",
"Epoch [148/300] [D loss: 0.052174512296915054] [G loss: 5.132132053375244]\n",
"Epoch [149/300] [D loss: 0.4083835482597351] [G loss: 3.095195770263672]\n",
"Epoch [150/300] [D loss: 0.007787104230374098] [G loss: 7.455079078674316]\n",
"Epoch [151/300] [D loss: 0.011952079832553864] [G loss: 5.102141857147217]\n",
"Epoch [152/300] [D loss: 0.1612093597650528] [G loss: 3.7608675956726074]\n",
"Epoch [153/300] [D loss: 0.03018610179424286] [G loss: 3.8288230895996094]\n",
"Epoch [154/300] [D loss: 0.06719933450222015] [G loss: 4.006799697875977]\n",
"Epoch [155/300] [D loss: 0.0286514051258564] [G loss: 4.619848728179932]\n",
"Epoch [156/300] [D loss: 0.024552451446652412] [G loss: 4.437436580657959]\n",
"Epoch [157/300] [D loss: 0.011825334280729294] [G loss: 4.815029144287109]\n",
"Epoch [158/300] [D loss: 0.061660464853048325] [G loss: 7.883100509643555]\n",
"Epoch [159/300] [D loss: 0.041454415768384933] [G loss: 6.650402545928955]\n",
"Epoch [160/300] [D loss: 0.39040958881378174] [G loss: 8.09695053100586]\n",
"Epoch [161/300] [D loss: 0.0026854330208152533] [G loss: 8.107271194458008]\n",
"Epoch [162/300] [D loss: 0.16259369254112244] [G loss: 5.87791109085083]\n",
"Epoch [163/300] [D loss: 0.03663758188486099] [G loss: 4.121287822723389]\n",
"Epoch [164/300] [D loss: 0.009695476852357388] [G loss: 8.566814422607422]\n",
"Epoch [165/300] [D loss: 0.010842864401638508] [G loss: 7.692420959472656]\n",
"Epoch [166/300] [D loss: 0.010091769509017467] [G loss: 5.9158101081848145]\n",
"Epoch [167/300] [D loss: 0.005709683522582054] [G loss: 5.492888450622559]\n",
"Epoch [168/300] [D loss: 0.16688843071460724] [G loss: 3.3484747409820557]\n",
"Epoch [169/300] [D loss: 0.007227647118270397] [G loss: 6.33713960647583]\n",
"Epoch [170/300] [D loss: 0.007962928153574467] [G loss: 7.612416744232178]\n",
"Epoch [171/300] [D loss: 0.012646579183638096] [G loss: 4.420655250549316]\n",
"Epoch [172/300] [D loss: 0.01767764426767826] [G loss: 4.4174957275390625]\n",
"Epoch [173/300] [D loss: 0.006378074176609516] [G loss: 7.643772125244141]\n",
"Epoch [174/300] [D loss: 0.009910110384225845] [G loss: 5.333507061004639]\n",
"Epoch [175/300] [D loss: 0.004518002271652222] [G loss: 6.36816930770874]\n",
"Epoch [176/300] [D loss: 0.08845338225364685] [G loss: 4.761691570281982]\n",
"Epoch [177/300] [D loss: 0.038503680378198624] [G loss: 3.653679370880127]\n",
"Epoch [178/300] [D loss: 0.0021649880800396204] [G loss: 6.513932704925537]\n",
"Epoch [179/300] [D loss: 0.0054839057847857475] [G loss: 5.804437637329102]\n",
"Epoch [180/300] [D loss: 0.005088070873171091] [G loss: 5.903375148773193]\n",
"Epoch [181/300] [D loss: 0.024380924180150032] [G loss: 6.934257984161377]\n",
"Epoch [182/300] [D loss: 0.003647219855338335] [G loss: 9.193355560302734]\n",
"Epoch [183/300] [D loss: 0.8360736966133118] [G loss: 8.123100280761719]\n",
"Epoch [184/300] [D loss: 0.014819988049566746] [G loss: 4.3469648361206055]\n",
"Epoch [185/300] [D loss: 0.009622478857636452] [G loss: 5.201544761657715]\n",
"Epoch [186/300] [D loss: 0.023895107209682465] [G loss: 3.903581380844116]\n",
"Epoch [187/300] [D loss: 0.013679596595466137] [G loss: 8.605210304260254]\n",
"Epoch [188/300] [D loss: 0.0036324947141110897] [G loss: 6.411885738372803]\n",
"Epoch [189/300] [D loss: 0.006745172664523125] [G loss: 5.29392147064209]\n",
"Epoch [190/300] [D loss: 0.0007813140982761979] [G loss: 8.193427085876465]\n",
"Epoch [191/300] [D loss: 0.021813858300447464] [G loss: 4.648034572601318]\n",
"Epoch [192/300] [D loss: 0.025777161121368408] [G loss: 4.67152738571167]\n",
"Epoch [193/300] [D loss: 0.06395631283521652] [G loss: 7.985042095184326]\n",
"Epoch [194/300] [D loss: 0.034654516726732254] [G loss: 3.360792398452759]\n",
"Epoch [195/300] [D loss: 0.26737672090530396] [G loss: 6.765297889709473]\n",
"Epoch [196/300] [D loss: 0.010468905791640282] [G loss: 5.34564208984375]\n",
"Epoch [197/300] [D loss: 0.014369252137839794] [G loss: 5.097072124481201]\n",
"Epoch [198/300] [D loss: 0.003273996990174055] [G loss: 6.472024440765381]\n",
"Epoch [199/300] [D loss: 0.005874062888324261] [G loss: 8.4591646194458]\n",
"Epoch [200/300] [D loss: 0.005507076624780893] [G loss: 5.7223286628723145]\n",
"Epoch [201/300] [D loss: 0.16853176057338715] [G loss: 1.9387050867080688]\n",
"Epoch [202/300] [D loss: 0.0023364669177681208] [G loss: 8.370942115783691]\n",
"Epoch [203/300] [D loss: 0.003936069551855326] [G loss: 7.522141933441162]\n",
"Epoch [204/300] [D loss: 0.01826675795018673] [G loss: 4.6409101486206055]\n",
"Epoch [205/300] [D loss: 0.018070252612233162] [G loss: 6.2785234451293945]\n",
"Epoch [206/300] [D loss: 0.06540463864803314] [G loss: 4.250749111175537]\n",
"Epoch [207/300] [D loss: 0.005754987709224224] [G loss: 5.474653720855713]\n",
"Epoch [208/300] [D loss: 0.0024513285607099533] [G loss: 6.821662425994873]\n",
"Epoch [209/300] [D loss: 0.005051593761891127] [G loss: 8.622801780700684]\n",
"Epoch [210/300] [D loss: 0.2648685872554779] [G loss: 1.4338374137878418]\n",
"Epoch [211/300] [D loss: 0.06582126766443253] [G loss: 4.042891502380371]\n",
"Epoch [212/300] [D loss: 0.033716216683387756] [G loss: 3.6866607666015625]\n",
"Epoch [213/300] [D loss: 0.008300993591547012] [G loss: 5.592546463012695]\n",
"Epoch [214/300] [D loss: 0.10640338063240051] [G loss: 3.440943479537964]\n",
"Epoch [215/300] [D loss: 0.018705546855926514] [G loss: 8.040839195251465]\n",
"Epoch [216/300] [D loss: 0.32254651188850403] [G loss: 1.023318886756897]\n",
"Epoch [217/300] [D loss: 0.006875279359519482] [G loss: 5.205789566040039]\n",
"Epoch [218/300] [D loss: 0.01632297970354557] [G loss: 6.327811241149902]\n",
"Epoch [219/300] [D loss: 0.020900549367070198] [G loss: 6.634525299072266]\n",
"Epoch [220/300] [D loss: 0.011139878071844578] [G loss: 7.300896644592285]\n",
"Epoch [221/300] [D loss: 0.01837160252034664] [G loss: 5.964895248413086]\n",
"Epoch [222/300] [D loss: 0.016974858939647675] [G loss: 4.413552284240723]\n",
"Epoch [223/300] [D loss: 0.3439306914806366] [G loss: 5.5219573974609375]\n",
"Epoch [224/300] [D loss: 0.047548823058605194] [G loss: 6.586645603179932]\n",
"Epoch [225/300] [D loss: 0.03183538839221001] [G loss: 4.398618221282959]\n",
"Epoch [226/300] [D loss: 0.0033374489285051823] [G loss: 7.412342071533203]\n",
"Epoch [227/300] [D loss: 0.018537862226366997] [G loss: 5.484577655792236]\n",
"Epoch [228/300] [D loss: 0.03582551330327988] [G loss: 3.6857614517211914]\n",
"Epoch [229/300] [D loss: 0.11226078867912292] [G loss: 2.819861888885498]\n",
"Epoch [230/300] [D loss: 0.002012553857639432] [G loss: 7.154722690582275]\n",
"Epoch [231/300] [D loss: 0.00868014432489872] [G loss: 8.001018524169922]\n",
"Epoch [232/300] [D loss: 0.0419110469520092] [G loss: 6.980061054229736]\n",
"Epoch [233/300] [D loss: 0.006477241404354572] [G loss: 5.782578945159912]\n",
"Epoch [234/300] [D loss: 0.0016205032588914037] [G loss: 10.428010940551758]\n",
"Epoch [235/300] [D loss: 0.02312217839062214] [G loss: 4.159178733825684]\n",
"Epoch [236/300] [D loss: 0.36001917719841003] [G loss: 2.4811325073242188]\n",
"Epoch [237/300] [D loss: 0.005733223166316748] [G loss: 5.611016750335693]\n",
"Epoch [238/300] [D loss: 0.008837449364364147] [G loss: 8.30731201171875]\n",
"Epoch [239/300] [D loss: 0.011222743429243565] [G loss: 4.619396209716797]\n",
"Epoch [240/300] [D loss: 0.0060098664835095406] [G loss: 6.022060394287109]\n",
"Epoch [241/300] [D loss: 0.0011382169323042035] [G loss: 7.404472351074219]\n",
"Epoch [242/300] [D loss: 0.3661719560623169] [G loss: 7.876453399658203]\n",
"Epoch [243/300] [D loss: 0.0019019388128072023] [G loss: 7.3895263671875]\n",
"Epoch [244/300] [D loss: 0.006632590666413307] [G loss: 5.541728973388672]\n",
"Epoch [245/300] [D loss: 0.008930223993957043] [G loss: 5.2114691734313965]\n",
"Epoch [246/300] [D loss: 0.016119416803121567] [G loss: 7.121890068054199]\n",
"Epoch [247/300] [D loss: 0.001622633310034871] [G loss: 7.303770065307617]\n",
"Epoch [248/300] [D loss: 0.005070182494819164] [G loss: 6.975015640258789]\n",
"Epoch [249/300] [D loss: 0.04641895741224289] [G loss: 7.218448638916016]\n",
"Epoch [250/300] [D loss: 0.01194002851843834] [G loss: 4.6930975914001465]\n",
"Epoch [251/300] [D loss: 0.012792033143341541] [G loss: 4.67077112197876]\n",
"Epoch [252/300] [D loss: 0.008810436353087425] [G loss: 5.938291072845459]\n",
"Epoch [253/300] [D loss: 0.010516034439206123] [G loss: 4.816621780395508]\n",
"Epoch [254/300] [D loss: 0.017264991998672485] [G loss: 8.856822967529297]\n",
"Epoch [255/300] [D loss: 0.011463891714811325] [G loss: 6.232043743133545]\n",
"Epoch [256/300] [D loss: 0.08137447386980057] [G loss: 2.598818778991699]\n",
"Epoch [257/300] [D loss: 0.032363615930080414] [G loss: 4.790830135345459]\n",
"Epoch [258/300] [D loss: 0.00863250344991684] [G loss: 7.292766571044922]\n",
"Epoch [259/300] [D loss: 0.027235930785536766] [G loss: 6.844869613647461]\n",
"Epoch [260/300] [D loss: 0.008849331177771091] [G loss: 5.027510643005371]\n",
"Epoch [261/300] [D loss: 0.020822376012802124] [G loss: 4.600456714630127]\n",
"Epoch [262/300] [D loss: 1.7667120695114136] [G loss: 3.4651100635528564]\n",
"Epoch [263/300] [D loss: 0.022669170051813126] [G loss: 5.7553019523620605]\n",
"Epoch [264/300] [D loss: 0.01582598127424717] [G loss: 4.149420261383057]\n",
"Epoch [265/300] [D loss: 0.0035504011902958155] [G loss: 6.116427421569824]\n",
"Epoch [266/300] [D loss: 0.07644154131412506] [G loss: 2.720405101776123]\n",
"Epoch [267/300] [D loss: 0.030415533110499382] [G loss: 4.244810104370117]\n",
"Epoch [268/300] [D loss: 0.020068874582648277] [G loss: 6.474517822265625]\n",
"Epoch [269/300] [D loss: 0.002136750379577279] [G loss: 9.29329776763916]\n",
"Epoch [270/300] [D loss: 0.00978941936045885] [G loss: 5.02622652053833]\n",
"Epoch [271/300] [D loss: 0.08784317970275879] [G loss: 6.733256816864014]\n",
"Epoch [272/300] [D loss: 0.009109925478696823] [G loss: 5.823270797729492]\n",
"Epoch [273/300] [D loss: 0.008865194395184517] [G loss: 5.696066379547119]\n",
"Epoch [274/300] [D loss: 0.029590584337711334] [G loss: 8.216507911682129]\n",
"Epoch [275/300] [D loss: 0.0636298805475235] [G loss: 8.98292064666748]\n",
"Epoch [276/300] [D loss: 0.004769572988152504] [G loss: 6.2220025062561035]\n",
"Epoch [277/300] [D loss: 0.003883387427777052] [G loss: 6.5977911949157715]\n",
"Epoch [278/300] [D loss: 0.04028937965631485] [G loss: 4.9343485832214355]\n",
"Epoch [279/300] [D loss: 0.011857430450618267] [G loss: 6.440511703491211]\n",
"Epoch [280/300] [D loss: 0.007019379176199436] [G loss: 5.2130351066589355]\n",
"Epoch [281/300] [D loss: 0.022525882348418236] [G loss: 3.9527556896209717]\n",
"Epoch [282/300] [D loss: 0.0071130781434476376] [G loss: 6.993907928466797]\n",
"Epoch [283/300] [D loss: 0.003977011889219284] [G loss: 7.2447967529296875]\n",
"Epoch [284/300] [D loss: 0.07062061131000519] [G loss: 5.2334771156311035]\n",
"Epoch [285/300] [D loss: 0.01805986650288105] [G loss: 5.5015082359313965]\n",
"Epoch [286/300] [D loss: 0.05663669481873512] [G loss: 6.766615390777588]\n",
"Epoch [287/300] [D loss: 0.0032901568338274956] [G loss: 6.28628396987915]\n",
"Epoch [288/300] [D loss: 0.3530406653881073] [G loss: 7.906818389892578]\n",
"Epoch [289/300] [D loss: 0.004547123331576586] [G loss: 6.108604431152344]\n",
"Epoch [290/300] [D loss: 0.010472457855939865] [G loss: 6.213746070861816]\n",
"Epoch [291/300] [D loss: 0.016601260751485825] [G loss: 5.763346195220947]\n",
"Epoch [292/300] [D loss: 0.04024907946586609] [G loss: 5.658637523651123]\n",
"Epoch [293/300] [D loss: 0.07437323033809662] [G loss: 5.68184757232666]\n",
"Epoch [294/300] [D loss: 0.08150847256183624] [G loss: 6.040549278259277]\n",
"Epoch [295/300] [D loss: 0.0924491435289383] [G loss: 2.502917766571045]\n",
"Epoch [296/300] [D loss: 0.0035814237780869007] [G loss: 7.250881195068359]\n",
"Epoch [297/300] [D loss: 0.012245922349393368] [G loss: 6.780396461486816]\n",
"Epoch [298/300] [D loss: 0.004009227734059095] [G loss: 5.833404064178467]\n",
"Epoch [299/300] [D loss: 0.14272907376289368] [G loss: 7.528534889221191]\n"
]
}
],
"source": [
"# 开始训练\n",
"epochs = 300\n",
"for epoch in range(epochs):\n",
" for i, (X, y, mask) in enumerate(dataloader):\n",
" # 将数据移到 GPU 上\n",
" X, y, mask = X.to(device), y.to(device), mask.to(device)\n",
" \n",
" valid = torch.ones((X.size(0), 1, 12, 12)).to(device)\n",
" fake = torch.zeros((X.size(0), 1, 12, 12)).to(device)\n",
"\n",
" # 生成器生成图像\n",
" optimizer_G.zero_grad()\n",
" generated_images = generator(X, mask)\n",
" g_loss = adversarial_loss(discriminator(torch.cat((generated_images, X), dim=1)), valid) + 100 * pixelwise_loss(\n",
" generated_images, y)\n",
" g_loss.backward()\n",
" optimizer_G.step()\n",
"\n",
" # 判别器训练\n",
" optimizer_D.zero_grad()\n",
" real_loss = adversarial_loss(discriminator(torch.cat((y, X), dim=1)), valid)\n",
" fake_loss = adversarial_loss(discriminator(torch.cat((generated_images.detach(), X), dim=1)), fake)\n",
" d_loss = 0.5 * (real_loss + fake_loss)\n",
" d_loss.backward()\n",
" optimizer_D.step()\n",
"\n",
" print(f\"Epoch [{epoch}/{epochs}] [D loss: {d_loss.item()}] [G loss: {g_loss.item()}]\")\n",
"\n",
"# 保存训练好的模型\n",
"torch.save(generator.state_dict(), './models/GAN/generator.pth')\n",
"torch.save(discriminator.state_dict(), './models/GAN/discriminator.pth')"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "18482f18-a9cd-49cb-a63a-85725cc4088a",
"metadata": {},
"outputs": [],
"source": [
"# 结果评估与可视化\n",
"def visualize_results():\n",
" \n",
" X, y, mask = next(iter(dataloader))\n",
" X, y, mask = X.to(device), y.to(device), mask.to(device)\n",
" generated_images = generator(X, mask)\n",
"\n",
" mask = mask.squeeze(1)\n",
" generated_images = generated_images.squeeze(1)\n",
" y = y.squeeze(1)\n",
"\n",
" final_output = generated_images\n",
"\n",
" plt.figure(figsize=(15, 5))\n",
" plt.subplot(1, 3, 1)\n",
" plt.title('Masked NO2 Data')\n",
" plt.imshow(X[0, 0].cpu().detach().numpy(), cmap='gray')\n",
" plt.axis('off')\n",
"\n",
" plt.subplot(1, 3, 2)\n",
" plt.title('Generated NO2 Data')\n",
" plt.imshow(final_output[0].cpu().detach().numpy(), cmap='gray')\n",
" plt.axis('off')\n",
"\n",
" plt.subplot(1, 3, 3)\n",
" plt.title('Original NO2 Data')\n",
" plt.imshow(y[0].cpu().detach().numpy(), cmap='gray')\n",
" plt.axis('off')\n",
"\n",
" plt.tight_layout()\n",
" plt.savefig('results_visualizationxxx.png')\n",
" plt.close()\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "a02c7b46-4c53-4fff-b130-a82412f9cf06",
"metadata": {},
"outputs": [],
"source": [
"dataset_test = NO2Dataset('./out_mat/96/test/', './out_mat/96/mask/20/')\n",
"test_loader = DataLoader(dataset_test, batch_size=64, shuffle=False, num_workers=8)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "13e2180c-5615-4610-a041-6da5f5c69a5d",
"metadata": {},
"outputs": [],
"source": [
"from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_percentage_error, mean_absolute_error"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "3a5533e4-f24d-41ae-8de0-0ab2a383d38f",
"metadata": {},
"outputs": [],
"source": [
"def cal_ioa(y_true, y_pred):\n",
" # 计算平均值\n",
" mean_observed = np.mean(y_true)\n",
" mean_predicted = np.mean(y_pred)\n",
"\n",
" # 计算IoA\n",
" numerator = np.sum((y_true - y_pred) ** 2)\n",
" denominator = np.sum((np.abs(y_true - mean_observed) + np.abs(y_pred - mean_predicted)) ** 2)\n",
" IoA = 1 - (numerator / denominator)\n",
"\n",
" return IoA"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "c1dd78b5-c66e-45f4-ab0f-f4b9c6f08cd2",
"metadata": {},
"outputs": [],
"source": [
"device = 'cpu'\n",
"generator = generator.to(device)\n",
"eva_list = list()\n",
"with torch.no_grad():\n",
" for X, y, mask in test_loader:\n",
" X, y, mask = X.to(device), y.to(device), mask.to(device)\n",
" generated_images = generator(X, mask)\n",
" mask = mask.squeeze(1).cpu().detach().numpy()\n",
" rev_mask = (mask==0)* 1\n",
" generated_images = generated_images.squeeze(1)\n",
" real = y.squeeze(1).cpu().detach().numpy() * max_pixel_value\n",
" final_output = generated_images.cpu().detach().numpy()\n",
" final_output *= max_pixel_value\n",
" # y_pred = final_output[rev_mask==1].tolist()\n",
" # y_real = real[rev_mask==1].tolist()\n",
" for i, sample in enumerate(generated_images):\n",
" used_mask = rev_mask[i]\n",
" data_label = real[i] * used_mask\n",
" recon_no2 = final_output[i] * used_mask\n",
" data_label = data_label[used_mask==1]\n",
" recon_no2 = recon_no2[used_mask==1]\n",
" mae = mean_absolute_error(data_label, recon_no2)\n",
" rmse = np.sqrt(mean_squared_error(data_label, recon_no2))\n",
" mape = mean_absolute_percentage_error(data_label, recon_no2)\n",
" r2 = r2_score(data_label, recon_no2)\n",
" ioa = cal_ioa(data_label, recon_no2)\n",
" r = np.corrcoef(data_label, recon_no2)[0, 1]\n",
" eva_list_frame.append([mae, rmse, mape, r2, ioa, r])"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "1ca21b33-753f-49ee-93d8-ede92e100b5a",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "edc3aaa3-c9b3-4094-9dea-e981f582ac09",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>mae</th>\n",
" <th>rmse</th>\n",
" <th>mape</th>\n",
" <th>r2</th>\n",
" <th>ioa</th>\n",
" <th>r</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>4739.000000</td>\n",
" <td>4739.000000</td>\n",
" <td>4739.000000</td>\n",
" <td>4739.000000</td>\n",
" <td>4739.000000</td>\n",
" <td>4739.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>2.512144</td>\n",
" <td>3.430941</td>\n",
" <td>0.360515</td>\n",
" <td>-0.342186</td>\n",
" <td>0.680466</td>\n",
" <td>0.578431</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>1.184403</td>\n",
" <td>1.580097</td>\n",
" <td>0.338929</td>\n",
" <td>1.730534</td>\n",
" <td>0.267197</td>\n",
" <td>0.227716</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>0.895772</td>\n",
" <td>1.189229</td>\n",
" <td>0.126946</td>\n",
" <td>-42.147773</td>\n",
" <td>-2.040257</td>\n",
" <td>-0.542623</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>1.699544</td>\n",
" <td>2.389879</td>\n",
" <td>0.211304</td>\n",
" <td>-0.480435</td>\n",
" <td>0.606881</td>\n",
" <td>0.457522</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>2.259834</td>\n",
" <td>3.125452</td>\n",
" <td>0.263535</td>\n",
" <td>0.094196</td>\n",
" <td>0.749986</td>\n",
" <td>0.620338</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>2.953516</td>\n",
" <td>3.983247</td>\n",
" <td>0.358762</td>\n",
" <td>0.421505</td>\n",
" <td>0.840619</td>\n",
" <td>0.745614</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>10.477497</td>\n",
" <td>14.460713</td>\n",
" <td>4.314635</td>\n",
" <td>0.922679</td>\n",
" <td>0.981525</td>\n",
" <td>0.965753</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" mae rmse mape r2 ioa \\\n",
"count 4739.000000 4739.000000 4739.000000 4739.000000 4739.000000 \n",
"mean 2.512144 3.430941 0.360515 -0.342186 0.680466 \n",
"std 1.184403 1.580097 0.338929 1.730534 0.267197 \n",
"min 0.895772 1.189229 0.126946 -42.147773 -2.040257 \n",
"25% 1.699544 2.389879 0.211304 -0.480435 0.606881 \n",
"50% 2.259834 3.125452 0.263535 0.094196 0.749986 \n",
"75% 2.953516 3.983247 0.358762 0.421505 0.840619 \n",
"max 10.477497 14.460713 4.314635 0.922679 0.981525 \n",
"\n",
" r \n",
"count 4739.000000 \n",
"mean 0.578431 \n",
"std 0.227716 \n",
"min -0.542623 \n",
"25% 0.457522 \n",
"50% 0.620338 \n",
"75% 0.745614 \n",
"max 0.965753 "
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.DataFrame(eva_list_frame, columns=['mae', 'rmse', 'mape', 'r2', 'ioa', 'r']).describe()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "7db4bb93-198e-4163-a926-f3fabebe4510",
"metadata": {},
"outputs": [],
"source": [
"# 保存训练好的模型\n",
"torch.save(generator, './models/GAN/generator.pt')\n",
"torch.save(discriminator, './models/GAN/discriminator.pt')"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "598577c8-7643-41a7-ad1e-ae9c5f2664f2",
"metadata": {},
"outputs": [],
"source": [
"test_imgs = [x for x in os.listdir('./test_img/') if 'img' in x]\n",
"test_imgs.sort()\n",
"test_masks = [x for x in os.listdir('./test_img/') if 'mask' in x]\n",
"test_masks.sort()\n",
"for img_npy, mask_npy in zip(test_imgs, test_masks):\n",
" img = np.load(f'./test_img/{file}')\n",
" img_in = torch.tensor(np.expand_dims(img, 0), dtype=torch.float32)\n",
" mask = np.load(f'./test_img/{file}')\n",
" mask_in = torch.tensor(np.expand_dims(mask, 0), dtype=torch.float32)\n",
" out = generator(img_in, mask_in).detach().cpu().numpy() * max_pixel_value\n",
" break"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "11a7a089-5691-455c-9b70-1c7a306be913",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f793dd49520>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.imshow(out[0][0], cmap='RdYlGn_r')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "44b063cf-d295-4dd8-b21b-1631ddae8ca1",
"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.8.16"
}
},
"nbformat": 4,
"nbformat_minor": 5
}