import streamlit as st import torch import torch.nn as nn import numpy as np from PIL import Image import time import pandas as pd import plotly.express as px import os # Streamlit Config st.set_page_config( page_title="Knowledge Distillation - Model Comparison - Weather Phenomena Prediction", page_icon="./static/aivn_favicon.png", layout="wide", initial_sidebar_state="expanded" ) # Add logo st.image("./static/aivn_logo.png", width=300) # Set seed SEED = 42 torch.manual_seed(SEED) # Image Transformation def transform(img, img_size=(224, 224)): img = img.resize(img_size) img = np.array(img)[..., :3] img = torch.tensor(img).permute(2, 0, 1).float() normalized_img = img / 255.0 return normalized_img.unsqueeze(0) # Classes classes = {0: 'dew', 1: 'fogsmog', 2: 'frost', 3: 'glaze', 4: 'hail', 5: 'lightning', 6: 'rain', 7: 'rainbow', 8: 'rime', 9: 'sandstorm', 10: 'snow'} class ResidualBlock(nn.Module): def __init__(self, in_channels, out_channels, stride=1): super(ResidualBlock, self).__init__() self.conv1 = nn.Conv2d( in_channels, out_channels, kernel_size=3, stride=stride, padding=1 ) self.batch_norm1 = nn.BatchNorm2d(out_channels) self.conv2 = nn.Conv2d( out_channels, out_channels, kernel_size=3, stride=1, padding=1 ) self.batch_norm2 = nn.BatchNorm2d(out_channels) self.downsample = nn.Sequential() if stride != 1 or in_channels != out_channels: self.downsample = nn.Sequential( nn.Conv2d( in_channels, out_channels, kernel_size=1, stride=stride ), nn.BatchNorm2d(out_channels) ) self.relu = nn.ReLU() def forward(self, x): shortcut = x.clone() x = self.conv1(x) x = self.batch_norm1(x) x = self.relu(x) x = self.conv2(x) x = self.batch_norm2(x) x += self.downsample(shortcut) x = self.relu(x) return x class ResNet(nn.Module): def __init__(self, residual_block, n_blocks_lst, n_classes): super(ResNet, self).__init__() self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3) self.batch_norm1 = nn.BatchNorm2d(64) self.relu = nn.ReLU() self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) self.conv2 = self.create_layer( residual_block, 64, 64, n_blocks_lst[0], 1) self.conv3 = self.create_layer( residual_block, 64, 128, n_blocks_lst[1], 2) self.conv4 = self.create_layer( residual_block, 128, 256, n_blocks_lst[2], 2) self.conv5 = self.create_layer( residual_block, 256, 512, n_blocks_lst[3], 2) self.avgpool = nn.AdaptiveAvgPool2d(1) self.flatten = nn.Flatten() self.fc1 = nn.Linear(512, n_classes) def create_layer(self, residual_block, in_channels, out_channels, n_blocks, stride): blocks = [] first_block = residual_block(in_channels, out_channels, stride) blocks.append(first_block) for idx in range(1, n_blocks): block = residual_block(out_channels, out_channels, stride=1) blocks.append(block) block_sequential = nn.Sequential(*blocks) return block_sequential def forward(self, x): x = self.conv1(x) x = self.batch_norm1(x) x = self.maxpool(x) x = self.relu(x) x = self.conv2(x) x = self.conv3(x) x = self.conv4(x) x = self.conv5(x) x = self.avgpool(x) x = self.flatten(x) x = self.fc1(x) return x # Load Model n_classes = len(classes) device = 'cuda' if torch.cuda.is_available() else 'cpu' # KD Student model_1 = ResNet( residual_block=ResidualBlock, n_blocks_lst=[2, 2, 2, 2], n_classes=n_classes ).to(device) model_1.load_state_dict(torch.load( "./model/kdsamedata_wt.pt", map_location=device)) model_1.eval() # Teacher model_2 = ResNet( residual_block=ResidualBlock, n_blocks_lst=[3, 4, 6, 3], n_classes=n_classes ).to(device) model_2.load_state_dict(torch.load( "./model/teacher_wt.pt", map_location=device)) model_2.eval() # Streamlit App Logic st.title("Weather Phenomena Prediction - Model Comparison") # Predefined image sets image_sets = { "Set 5 images": "./static/set5", "Set 10 images": "./static/set10", "Set 15 images": "./static/set15" } st.markdown("