Skip to content
This repository was archived by the owner on Feb 25, 2026. It is now read-only.

Commit 6229ff8

Browse files
Add files via upload
1 parent d38ee39 commit 6229ff8

6 files changed

Lines changed: 344 additions & 0 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import torch
2+
import torch.nn as nn
3+
import torch.nn.functional as F
4+
5+
# Define the 3D CNN model
6+
class CNN3D(nn.Module):
7+
def __init__(self):
8+
super(CNN3D, self).__init__()
9+
10+
# Define three 3D convolutional layers with different kernel sizes
11+
self.conv3x3x3 = nn.Conv3d(1, 2, kernel_size=3, padding=(0,1,1)) # 3x3x3 kernel (3D)
12+
self.conv3x5x5 = nn.Conv3d(1, 2, kernel_size=(3,5,5), padding=(0,2,2)) # 3x5x5 kernel
13+
self.conv3x7x7 = nn.Conv3d(1, 2, kernel_size=(3,7,7), padding=(0,3,3)) # 3x7x7 kernel
14+
15+
# Encoder part (2D convolution, batch normalization, and ReLU layers)
16+
self.encoder = nn.Sequential(
17+
nn.Conv2d(12, 32, kernel_size=5, padding=2), # First 2D convolution (input 12 channels)
18+
nn.BatchNorm2d(32), # Batch normalization for stable training
19+
nn.ReLU(inplace=True), # ReLU activation
20+
21+
nn.Conv2d(32, 64, kernel_size=5, padding=2), # Second 2D convolution
22+
nn.BatchNorm2d(64), # Batch normalization
23+
nn.ReLU(inplace=True) # ReLU activation
24+
)
25+
26+
# Decoder part (two 2D convolutional layers to reconstruct output)
27+
self.decoder = nn.Sequential(
28+
nn.Conv2d(64, 16, kernel_size=5, padding=2), # First decoder layer
29+
nn.Conv2d(16, 1, kernel_size=5, padding=2), # Second decoder layer (output is 1 channel)
30+
nn.Sigmoid() # Sigmoid activation to normalize output
31+
)
32+
33+
def forward(self, x): # Input x has shape (batch_size, 4, 56, 56) [channels: emcal, hcal, trkn, trkp]
34+
x = x.unsqueeze(1) # Add an extra dimension to x (batch_size, 1, 4, 56, 56) for 3D convolutions
35+
36+
# Select subsets of the input data for 3D convolutions
37+
x_e_h_n = x[:, :, :3, :, :] # Select channels: emcal, hcal, trkn (first 3 channels)
38+
x_e_h_p = x[:, :, [0, 1, 3], :, :] # Select channels: emcal, hcal, trkp (channels 0, 1, 3)
39+
40+
# Apply 3D convolutions on these subsets
41+
x2 = self.conv3x3x3(x_e_h_n) # Apply 3x3x3 convolution on emcal, hcal, trkn
42+
x3 = self.conv3x5x5(x_e_h_n) # Apply 3x5x5 convolution on emcal, hcal, trkn
43+
x4 = self.conv3x7x7(x_e_h_n) # Apply 3x7x7 convolution on emcal, hcal, trkn
44+
45+
x5 = self.conv3x3x3(x_e_h_p) # Apply 3x3x3 convolution on emcal, hcal, trkp
46+
x6 = self.conv3x5x5(x_e_h_p) # Apply 3x5x5 convolution on emcal, hcal, trkp
47+
x7 = self.conv3x7x7(x_e_h_p) # Apply 3x7x7 convolution on emcal, hcal, trkp
48+
49+
# Concatenate all the resulting feature maps (12 channels) along the channel dimension
50+
x = torch.cat((x2, x3, x4, x5, x6, x7), dim=1).view(-1, 12, 56, 56)
51+
52+
# Pass through the encoder
53+
x = self.encoder(x)
54+
55+
# Pass through the decoder to reconstruct the output
56+
x = self.decoder(x)
57+
58+
return x # Output shape: (batch_size, 1, 56, 56)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import torch
2+
import torch.nn as nn
3+
import torch.nn.functional as F
4+
5+
# Define the Self-Attention layer
6+
class SelfAttention(nn.Module):
7+
def __init__(self, in_channels):
8+
super(SelfAttention, self).__init__()
9+
# Convolutional layers for generating query, key, and value matrices from the input feature maps
10+
self.query = nn.Conv2d(in_channels, in_channels, kernel_size=1) # For the query matrix (Q)
11+
self.key = nn.Conv2d(in_channels, in_channels, kernel_size=1) # For the key matrix (K)
12+
self.value = nn.Conv2d(in_channels, in_channels, kernel_size=1) # For the value matrix (V)
13+
# Softmax layer to normalize the attention scores
14+
self.softmax = nn.Softmax(dim=-1)
15+
16+
def forward(self, x):
17+
batch_size, C, H, W = x.size() # Get the dimensions of the input tensor
18+
19+
# Generate query, key, and value matrices by applying respective convolutions
20+
queries = self.query(x).view(batch_size, C, -1) # Reshape to (B, C, H*W)
21+
keys = self.key(x).view(batch_size, C, -1) # Reshape to (B, C, H*W)
22+
values = self.value(x).view(batch_size, C, -1) # Reshape to (B, C, H*W)
23+
24+
# Compute the attention scores using matrix multiplication between queries and keys
25+
attention_scores = torch.bmm(queries.permute(0, 2, 1), keys) # Output: (B, H*W, H*W)
26+
attention_scores = self.softmax(attention_scores) # Apply softmax to get the attention weights
27+
28+
# Multiply values with attention scores and reshape back to the original size
29+
out = torch.bmm(values, attention_scores.permute(0, 2, 1)) # Output: (B, C, H*W)
30+
return out.view(batch_size, C, H, W) # Reshape to (B, C, H, W) without changing the original shape
31+
32+
# Define the CNN with Self-Attention model
33+
class CNNattention(nn.Module):
34+
def __init__(self, in_channels, out_channels=1): # Default output channels set to 1
35+
super(CNNattention, self).__init__()
36+
# Encoder part (downsampling with convolutional layers)
37+
self.enc1 = nn.Conv2d(in_channels, 64, kernel_size=3, padding=1) # First encoding layer, input has 4 channels
38+
self.enc2 = nn.Conv2d(64, 128, kernel_size=3, padding=1) # Second encoding layer
39+
self.enc3 = nn.Conv2d(128, 256, kernel_size=3, padding=1) # Third encoding layer
40+
41+
# Self-Attention layer applied after the encoder
42+
self.attention = SelfAttention(256) # Self-Attention applied to 256 channels
43+
44+
# Decoder part (upsampling with convolutional layers)
45+
self.dec1 = nn.Conv2d(256, 128, kernel_size=3, padding=1) # First decoding layer
46+
self.dec2 = nn.Conv2d(128, 64, kernel_size=3, padding=1) # Second decoding layer
47+
self.dec3 = nn.Conv2d(64, out_channels, kernel_size=3, padding=1) # Final layer, output has 1 channel
48+
nn.Sigmoid() # Sigmoid activation (not used in forward)
49+
50+
def forward(self, x):
51+
# Encoder: apply convolutional layers and relu activation
52+
enc1 = F.relu(self.enc1(x)) # (4, 56, 56) -> (64, 56, 56)
53+
enc2 = F.relu(self.enc2(F.max_pool2d(enc1, 2))) # Downsampling: (64, 28, 28) -> (128, 28, 28)
54+
enc3 = F.relu(self.enc3(F.max_pool2d(enc2, 2))) # Downsampling: (128, 14, 14) -> (256, 14, 14)
55+
56+
# Self-Attention layer to refine feature maps
57+
attn_out = self.attention(enc3) # Attention output: (256, 14, 14)
58+
59+
# Decoder: upsample and apply convolutional layers
60+
dec1 = F.relu(self.dec1(F.upsample(attn_out, scale_factor=2, mode='bilinear', align_corners=False))) # Upsample: (128, 28, 28)
61+
dec2 = F.relu(self.dec2(F.upsample(dec1, scale_factor=2, mode='bilinear', align_corners=False))) # Upsample: (64, 56, 56)
62+
out = self.dec3(dec2) # Final output: (64, 56, 56) -> (1, 56, 56)
63+
64+
return out # Return the final output

Model Implementation/CNN.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import torch.nn as nn
2+
import torch.nn.functional as F
3+
import torch
4+
5+
# Define the CNN model
6+
class CNN(nn.Module):
7+
def __init__(self):
8+
super(CNN, self).__init__()
9+
10+
# Three convolutional layers with different kernel sizes (3x3, 5x5, 7x7)
11+
self.cov3x3 = nn.Conv2d(4, 2, kernel_size=3, padding=1) # 3x3 kernel with padding for same size output
12+
self.cov5x5 = nn.Conv2d(4, 2, kernel_size=5, padding=2) # 5x5 kernel with padding for same size output
13+
self.cov7x7 = nn.Conv2d(4, 2, kernel_size=7, padding=3) # 7x7 kernel with padding for same size output
14+
15+
# Encoder part (a sequence of convolutional, batch normalization, and ReLU layers)
16+
self.encoder = nn.Sequential(
17+
nn.Conv2d(6, 32, kernel_size=5, padding=2), # First layer after concatenation of cov layers
18+
nn.BatchNorm2d(32), # Batch normalization for stable training
19+
nn.ReLU(inplace=True), # ReLU activation function
20+
21+
nn.Conv2d(32, 64, kernel_size=5, padding=2), # Second convolutional layer
22+
nn.BatchNorm2d(64), # Batch normalization
23+
nn.ReLU(inplace=True) # ReLU activation
24+
)
25+
26+
# Decoder part (two convolutional layers for reconstruction)
27+
self.decoder = nn.Sequential(
28+
nn.Conv2d(64, 16, kernel_size=5, padding=2), # First layer of decoder
29+
nn.Conv2d(16, 1, kernel_size=5, padding=2), # Second layer, outputting one channel
30+
nn.Sigmoid() # Sigmoid activation for the output (for normalization)
31+
)
32+
33+
def forward(self, x): # Input x is a 4-channel image, i.e., concatenated (emcal, hcal, trkn, trkp)
34+
# Apply three convolutional layers with different kernel sizes
35+
x1 = self.cov3x3(x) # Apply 3x3 convolution
36+
x2 = self.cov5x5(x) # Apply 5x5 convolution
37+
x3 = self.cov7x7(x) # Apply 7x7 convolution
38+
39+
# Concatenate the outputs of the three convolutional layers along the channel dimension
40+
x = torch.cat((x1, x2, x3), dim=1) # (2+2+2 = 6 channels)
41+
42+
# Pass the concatenated output through the encoder
43+
x = self.encoder(x)
44+
45+
# Pass the encoded features through the decoder to reconstruct the output
46+
x = self.decoder(x)
47+
48+
return x # Final output (1 channel, 56x56)

Model Implementation/RNN.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import torch
2+
import torch.nn as nn
3+
4+
class RNN(nn.Module):
5+
def __init__(self, input_dim, hidden_dim, output_dim, num_layers=2):
6+
super(RNN, self).__init__()
7+
# Initialize the encoder LSTM layer
8+
self.encoder = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True)
9+
# Initialize the decoder LSTM layer
10+
self.decoder = nn.LSTM(hidden_dim, hidden_dim, num_layers, batch_first=True)
11+
# Initialize a fully connected layer to map the hidden states to the output dimension
12+
self.fc = nn.Linear(hidden_dim, output_dim)
13+
14+
def forward(self, x):
15+
# Forward pass through the encoder LSTM
16+
# enc_out: Encoded output sequences
17+
# hidden: Hidden states of the encoder
18+
enc_out, hidden = self.encoder(x)
19+
20+
# Forward pass through the decoder LSTM
21+
# dec_out: Decoded output sequences
22+
# _ : Decoder hidden states (not used here)
23+
dec_out, _ = self.decoder(enc_out, hidden)
24+
25+
# Apply the fully connected layer to map decoder outputs to the desired output dimension
26+
out = self.fc(dec_out)
27+
return out
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import torch
2+
import torch.nn as nn
3+
import torch.nn.functional as F
4+
5+
# Define a Self-Attention layer
6+
class SelfAttention(nn.Module):
7+
def __init__(self, in_channels):
8+
super(SelfAttention, self).__init__()
9+
# Define the layers for query, key, and value
10+
self.query = nn.Conv2d(in_channels, in_channels, kernel_size=1) # 1x1 convolution to generate queries
11+
self.key = nn.Conv2d(in_channels, in_channels, kernel_size=1) # 1x1 convolution to generate keys
12+
self.value = nn.Conv2d(in_channels, in_channels, kernel_size=1) # 1x1 convolution to generate values
13+
self.softmax = nn.Softmax(dim=-1) # Softmax for attention scores
14+
15+
def forward(self, x):
16+
batch_size, C, H, W = x.size()
17+
# Generate queries, keys, and values
18+
queries = self.query(x).view(batch_size, C, -1) # (B, C, H*W)
19+
keys = self.key(x).view(batch_size, C, -1) # (B, C, H*W)
20+
values = self.value(x).view(batch_size, C, -1) # (B, C, H*W)
21+
22+
# Compute attention scores
23+
attention_scores = torch.bmm(queries.permute(0, 2, 1), keys) # (B, H*W, H*W)
24+
attention_scores = self.softmax(attention_scores) # Apply softmax
25+
26+
# Compute the attention output
27+
out = torch.bmm(values, attention_scores.permute(0, 2, 1)) # (B, C, H*W)
28+
return out.view(batch_size, C, H, W) # Reshape to original dimensions
29+
30+
# Define the U-Net with Transformer integration
31+
class UNetTransformer(nn.Module):
32+
def __init__(self, in_channels, out_channels=1): # Output channels set to 1
33+
super(UNetTransformer, self).__init__()
34+
# Encoder part
35+
self.enc1 = nn.Conv2d(in_channels, 64, kernel_size=3, padding=1) # Input has 4 channels
36+
self.enc2 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
37+
self.enc3 = nn.Conv2d(128, 256, kernel_size=3, padding=1)
38+
# Self-attention layer
39+
self.attention = SelfAttention(256) # Input has 256 channels
40+
# Decoder part
41+
self.dec1 = nn.Conv2d(256, 128, kernel_size=3, padding=1)
42+
self.conv1 = nn.Conv2d(256, 128, kernel_size=1) # Adjust number of channels after concatenation
43+
self.dec2 = nn.Conv2d(128, 64, kernel_size=3, padding=1)
44+
self.dec3 = nn.Conv2d(64, out_channels, kernel_size=3, padding=1) # Final output layer
45+
self.conv2 = nn.Conv2d(128, 64, kernel_size=1) # Adjust number of channels after concatenation
46+
47+
def forward(self, x):
48+
# Encoding
49+
enc1 = F.relu(self.enc1(x)) # 4x56x56 -> 64x56x56
50+
enc2 = F.relu(self.enc2(F.max_pool2d(enc1, 2))) # 64x28x28 -> 128x28x28
51+
enc3 = F.relu(self.enc3(F.max_pool2d(enc2, 2))) # 128x14x14 -> 256x14x14
52+
53+
# Self-attention
54+
attn_out = self.attention(enc3) # 256x14x14 -> 256x14x14
55+
56+
# Decoding
57+
dec1 = F.relu(self.dec1(F.upsample(attn_out, scale_factor=2, mode='bilinear', align_corners=False))) # 256x14x14 -> 128x28x28
58+
dec1 = torch.cat([dec1, enc2], dim=1) # Concatenate with corresponding encoder output
59+
dec1 = self.conv1(dec1) # Adjust channels after concatenation
60+
dec2 = F.relu(self.dec2(F.upsample(dec1, scale_factor=2, mode='bilinear', align_corners=False))) # 128x28x28 -> 64x56x56
61+
dec2 = torch.cat([dec2, enc1], dim=1) # Concatenate with corresponding encoder output
62+
dec2 = self.conv2(dec2) # Adjust channels after concatenation
63+
out = self.dec3(dec2) # 64x56x56 -> 1x56x56
64+
65+
return out # Output the final result

Model Implementation/U-Net.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import torch
2+
import torch.nn as nn
3+
import torch.nn.functional as F
4+
5+
# Basic convolutional block with two convolutional layers, batch normalization, dropout, and LeakyReLU activation
6+
class Conv(nn.Module):
7+
def __init__(self, C_in, C_out):
8+
super(Conv, self).__init__()
9+
self.layer = nn.Sequential(
10+
# First 3x3 convolution layer with batch normalization, dropout, and activation
11+
nn.Conv2d(C_in, C_out, kernel_size=3, stride=1, padding=1), # 3x3 convolution, padding=1 keeps size unchanged
12+
nn.BatchNorm2d(C_out),
13+
nn.Dropout(0.3),
14+
nn.LeakyReLU(inplace=True),
15+
# Second 3x3 convolution layer with batch normalization, dropout, and activation
16+
nn.Conv2d(C_out, C_out, kernel_size=3, stride=1, padding=1), # Again, keep size unchanged
17+
nn.BatchNorm2d(C_out),
18+
nn.Dropout(0.4),
19+
nn.LeakyReLU(inplace=True),
20+
)
21+
22+
def forward(self, x):
23+
return self.layer(x)
24+
25+
# Downsampling block to reduce the feature map size by half using a 2x2 convolution with stride 2
26+
class DownSampling(nn.Module):
27+
def __init__(self, C_in, C_out):
28+
super(DownSampling, self).__init__()
29+
self.Down = nn.Sequential(
30+
# 2x2 convolution with stride 2 reduces the spatial dimensions
31+
nn.Conv2d(C_in, C_out, kernel_size=2, stride=2), # 2x2 convolution, stride=2 reduces size by half
32+
nn.LeakyReLU(inplace=True)
33+
)
34+
35+
def forward(self, x):
36+
return self.Down(x)
37+
38+
# Upsampling block to increase the feature map size by a factor of 2 using nearest neighbor interpolation
39+
class UpSampling(nn.Module):
40+
def __init__(self, C_in, C_out):
41+
super(UpSampling, self).__init__()
42+
# 1x1 convolution to adjust the number of channels after upsampling
43+
self.Up = nn.Conv2d(C_in, C_out, kernel_size=1) # 1x1 convolution to change the number of channels
44+
45+
def forward(self, x, r):
46+
# Upsample using nearest neighbor interpolation
47+
up = F.interpolate(x, scale_factor=2, mode='nearest') # Use nearest neighbor interpolation to upsample
48+
x = self.Up(up) # Change the number of output channels
49+
x = torch.cat([x, r], dim=1) # Concatenate the upsampled feature map with the skip connection
50+
return x
51+
52+
# U-Net architecture for image segmentation or similar tasks
53+
class UNet(nn.Module):
54+
def __init__(self):
55+
super(UNet, self).__init__()
56+
# Initial convolution block with 4 input channels (for example, emcal, hcal, trkn, trkp)
57+
self.C1 = Conv(4, 64) # First convolution block, input has 4 channels
58+
# First downsampling layer to reduce spatial size
59+
self.D1 = DownSampling(64, 128) # First downsampling layer
60+
# Second convolution block
61+
self.C2 = Conv(128, 128) # Second convolution block
62+
# Skipping a second downsampling and upsampling for simplicity in this version
63+
# Final upsampling layer to increase the size back and perform concatenation with the previous layer
64+
self.U2 = UpSampling(128, 64) # Second upsampling layer
65+
# Final convolution block after concatenation
66+
self.C5 = Conv(128, 64) # Final convolution block
67+
# Prediction layer that outputs a single channel
68+
self.pred = nn.Conv2d(64, 1, kernel_size=3, padding=1) # Output layer, predicts 1 channel
69+
# Apply sigmoid activation for final output
70+
self.sigmoid = nn.Sigmoid() # Sigmoid activation for final output
71+
72+
def forward(self, x):
73+
# Encoder part: First convolution and downsampling
74+
R1 = self.C1(x) # First convolution block
75+
R2 = self.C2(self.D1(R1)) # Downsampling followed by the second convolution block
76+
77+
# Decoder part: Upsample and concatenate with previous layer (skip connection)
78+
up2 = self.U2(R2, R1) # Second upsampling with skip connection to the first convolution block
79+
80+
# Final convolution and output
81+
c = self.C5(up2) # Final convolution block
82+
return self.sigmoid(self.pred(c)) # Output prediction with sigmoid activation

0 commit comments

Comments
 (0)