import torch.nn as nn import torch.nn.functional as F class Net(nn.Module): def __init__(self): super().__init__() self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1) self.conv2 = nn.Conv2d(16, 8, kernel_size=3, padding=1) self.fc1 = nn.Linear(8 * 64 * 64, 32) # for 256x256 input self.fc2 = nn.Linear(32, 4) # 4 classes def forward(self, x): out = F.max_pool2d(torch.tanh(self.conv1(x)), 2) # 256 -> 128 out = F.max_pool2d(torch.tanh(self.conv2(out)), 2) # 128 -> 64 out = out.view(-1, 8 * 64 * 64) out = torch.tanh(self.fc1(out)) out = self.fc2(out) return out # Why moving from v0 to v0.1? # 🔹 1. More convolution layers with increasing channels (16 → 32 → 64) # Why more layers? # Convolutions extract features in a hierarchy: # Early layers → detect edges, corners, basic color patterns. # Middle layers → detect textures, shapes (e.g., “forest canopy patterns”, “rooftop grids”). # Deeper layers → detect high-level structures (urban blocks vs farmland). # Your original network had just 2 layers (16, 8 channels) → too shallow to capture rich structures. # Why increasing channels? # Each channel is like a “detector” for a specific feature. # With 16 channels, you only learn 16 low-level filters → very limited. # Expanding 16 → 32 → 64 gives the network more capacity to encode complex patterns without exploding the number of parameters. # Standard practice in CNNs: double channels as you go deeper because spatial resolution shrinks (e.g., 256 → 128 → 64 → 32 pixels). # 📌 Effect: Model can distinguish “forest vs field” based not just on green color, but also on texture differences (dense tree canopy vs plowed farmland). # 🔹 2. Replace tanh with ReLU # tanh: outputs values between -1 and 1. # Problem: saturates easily → gradients vanish when activations go to extremes. # Slower learning, harder to train deeper nets. # ReLU (Rectified Linear Unit): outputs 0 for negatives, identity for positives. # Keeps gradients alive → avoids vanishing gradient problem. # Sparse activations → only some neurons fire, which acts as implicit regularization. # Faster and easier optimization, now the standard in almost all CNNs. # 📌 Effect: Your network trains faster, learns stronger nonlinear features, and avoids being “stuck” in flat gradient regions. # 🔹 3. Insert Batch Normalization (BatchNorm) # BatchNorm normalizes activations (zero mean, unit variance) inside the network. # Benefits: # Stabilizes training → network is less sensitive to weight initialization. # Allows higher learning rates → speeds up convergence. # Acts as a regularizer, reducing overfitting. # Makes the network more robust to distribution shifts (helpful since Google Earth tiles differ from IGN tiles). # 📌 Effect: Your model generalizes better to “out-of-distribution” inputs, since it isn’t too sensitive to raw intensity/color shifts. # 🔹 4. Add Dropout before fully connected head # Dropout randomly “drops” (sets to zero) some neurons during training. # Forces the network not to rely on a single pathway → encourages redundancy in feature representation. # Prevents co-adaptation of neurons (where certain features only work if others are present). # Especially important in the fully connected head, which has many parameters relative to convolutional layers. # 📌 Effect: Reduces overfitting to IGN imagery and makes the network more robust when faced with slightly different textures/colors from Google Earth. # 🔹 5. Keep output layer at 4 classes # Since your problem is 4-way classification (sea, forest, urban, field), final layer must output 4 logits. # Logits go into nn.CrossEntropyLoss, which applies softmax internally. # 📌 Effect: Keeps task-specific output while allowing the backbone (convs + FCs) to be stronger. # ✅ Summary of why this matters for you # Your old net was too shallow, used tanh (harder training), no normalization (unstable activations), and no dropout (overfits to IGN style). With these fixes, you’ll: # Learn richer features (textures, structures). # Train faster & more stable (ReLU + BatchNorm). # Generalize better (Dropout + normalization). # Stay lightweight and trainable from scratch.