AI-powered water contamination detection and monitoring
This repository implements and reproduces the methods described in the paper "AI-Powered Approaches for Enhancing Water Contamination Remote Sensing Detection in Ecological", including the AquaDynNet and FlowSentinel frameworks for high-accuracy detection and real-time monitoring.
Water contamination poses a significant threat to public health and ecosystems. Traditional water quality monitoring methods, such as manual sampling and basic chemical analysis, suffer from delays and insufficient spatial coverage.
This research proposes an AI-powered approach that combines sensor networks, machine learning algorithms, and real-time predictive models to:
Experimental results show that the proposed method significantly outperforms traditional approaches in terms of detection accuracy and response speed, offering practical decision support for policymakers and environmental agencies.
The project leverages four complementary datasets:
template.pdf
— Research paper templaterequirements.txt
— Python dependenciesdata/
— Dataset files
raw/
— Raw data (read-only)processed/
— Processed dataREADME.md
— Data descriptionsrc/
— Source code
model/
— Model architecture and training scriptspreprocessing/
— Data preprocessing scriptsevaluation/
— Model evaluation scriptsnotebooks/
— Jupyter notebooks
EDA.ipynb
— Exploratory Data AnalysisModelTraining.ipynb
— Model trainingEvaluation.ipynb
— Model evaluationresults/
— Experiment results and visualizations
figures/
— Plots and figuresmetrics.csv
— Performance metricsreport.pdf
— Project reportdocs/
— Documentation and references
methodology.md
— Methodology details (AquaDynNet / FlowSentinel)references.bib
— Reference bibliographydiagrams/
— Model and workflow diagramsgit clone https://github.com/<your-username>/<repository-name>.git
cd <repository-name>
"""
Minimal AquaDynNet: multi-branch CNN for spatial, temporal and spatiotemporal features.
This is a lightweight, trainable baseline you can extend.
"""
from dataclasses import dataclass
import torch
import torch.nn as nn
@dataclass
class AquaDynNetCfg:
in_channels: int = 8
classes: int = 2
spatial_size: int = 32
seq_len: int = 128
hidden: int = 64
class ConvBlock(nn.Module):
def __init__(self, c_in, c_out, k=3, p=1):
super().__init__()
self.net = nn.Sequential(
nn.Conv2d(c_in, c_out, k, padding=p),
nn.BatchNorm2d(c_out),
nn.ReLU(inplace=True),
nn.Conv2d(c_out, c_out, k, padding=p),
nn.BatchNorm2d(c_out),
nn.ReLU(inplace=True),
)
def forward(self, x): # (B,C,H,W)
return self.net(x)
class TemporalConv(nn.Module):
def __init__(self, c_in, c_out, k=5):
super().__init__()
self.net = nn.Sequential(
nn.Conv1d(c_in, c_out, k, padding=k//2),
nn.BatchNorm1d(c_out),
nn.ReLU(inplace=True),
nn.Conv1d(c_out, c_out, k, padding=k//2),
nn.BatchNorm1d(c_out),
nn.ReLU(inplace=True),
)
def forward(self, x): # (B,C,T)
return self.net(x)
class AquaDynNet(nn.Module):
def __init__(self, cfg: AquaDynNetCfg):
super().__init__()
self.cfg = cfg
h = cfg.hidden
# Spatial branch: expects (B, C, H, W)
self.spatial = nn.Sequential(
ConvBlock(cfg.in_channels, h),
nn.AdaptiveAvgPool2d(1)
)
# Temporal branch: expects (B, C, T)
self.temporal = nn.Sequential(
TemporalConv(cfg.in_channels, h),
nn.AdaptiveAvgPool1d(1)
)
# Spatio-temporal fusion (simple MLP head)
self.head = nn.Sequential(
nn.Linear(2*h, h),
nn.ReLU(inplace=True),
nn.Dropout(0.2),
nn.Linear(h, cfg.classes)
)
def forward(self, x_spatial: torch.Tensor, x_temporal: torch.Tensor):
# x_spatial: (B,C,H,W)
# x_temporal: (B,C,T)
s = self.spatial(x_spatial).flatten(1) # (B,h)
t = self.temporal(x_temporal).flatten(1) # (B,h)
z = torch.cat([s, t], dim=1) # (B,2h)
return self.head(z)
if __name__ == "__main__":
# Smoke test
cfg = AquaDynNetCfg()
model = AquaDynNet(cfg)
xs = torch.randn(4, cfg.in_channels, cfg.spatial_size, cfg.spatial_size)
xt = torch.randn(4, cfg.in_channels, cfg.seq_len)
logits = model(xs, xt)
print("logits:", logits.shape)