|
# Custom ResNet-18 for 7-Class Classification |
|
|
|
This is a fine-tuned **`ResNet-18`** model designed for a 7-class classification task. The model replaces all **ReLU** activation functions with **PReLU**, introduces **Dropout2D** layers for better generalization, and was trained on a custom dataset with various augmentations. |
|
|
|
--- |
|
|
|
## 📜 Model Details |
|
|
|
- **Base Model:** ResNet-18 (pre-trained on ImageNet). |
|
- **Activations:** ReLU layers replaced with PReLU. |
|
- **Dropout:** Dropout2D applied to enhance generalization. |
|
- **Classes:** 7 output classes. |
|
- **Input Size:** Images with customizable dimensions (default: `[100, 100]`). |
|
- **Normalization:** Input images are normalized using the following statistics: |
|
- Mean: `[0.485, 0.456, 0.406]` |
|
- Std: `[0.229, 0.224, 0.225]` |
|
|
|
--- |
|
|
|
## 📈 Evaluation Metrics on Test Data |
|
![Confusion Matrix](Test Accuracy 80.31%.png) |
|
|
|
|
|
## 🧑💻 How to Use |
|
|
|
You can load the model weights and architecture for inference or fine-tuning with the provided files: |
|
|
|
### **Using PyTorch** |
|
``` |
|
|
|
def get_out_channels(module): |
|
"""تابعی برای یافتن تعداد کانالهای خروجی از لایههای کانولوشن و BatchNorm""" |
|
if isinstance(module, nn.Conv2d): |
|
return module.out_channels |
|
elif isinstance(module, nn.BatchNorm2d): |
|
return module.num_features |
|
elif isinstance(module, nn.Linear): |
|
return module.out_features |
|
return None |
|
|
|
def replace_relu_with_prelu_and_dropout(module, inplace=True): |
|
for name, child in module.named_children(): |
|
replace_relu_with_prelu_and_dropout(child, inplace) |
|
|
|
if isinstance(child, nn.ReLU): |
|
out_channels = None |
|
for prev_name, prev_child in module.named_children(): |
|
if prev_name == name: |
|
break |
|
out_channels = get_out_channels(prev_child) or out_channels |
|
|
|
if out_channels is None: |
|
raise ValueError(f"Cannot determine `out_channels` for {child}. Please check the model structure.") |
|
|
|
prelu = PReLU(device=device, num_parameters=out_channels) |
|
dropout = nn.Dropout2d(p=0.2) |
|
setattr(module, name, nn.Sequential(prelu, dropout).to(device)) |
|
model = models.resnet18(weights = models.ResNet18_Weights.IMAGENET1K_V1).train(True).to(device) |
|
replace_relu_with_prelu_and_dropout(model) |
|
# print(model.fc.in_features) |
|
|
|
|
|
number = model.fc.in_features |
|
module = [] |
|
|
|
module.append(LazyLinear(7)) |
|
model.fc = Sequential(*module).to(device) |
|
|
|
state_dict = load_file("model.safetensors") |
|
model.load_state_dict(state_dict) |
|
model.eval() |
|
``` |
|
|
|
## ⚠️ Limitations and Considerations |
|
Input Dimensions: Make sure your input images are resized to the expected dimensions (100x100) before inference. |
|
Number of Classes: The trained model supports exactly 7 classes as defined in the training dataset. |
|
|
|
|
|
|
|
|