syahh-coder commited on
Commit
db6750c
·
1 Parent(s): edd23bc

load model

Browse files
Files changed (3) hide show
  1. Dockerfile +11 -0
  2. app.py +58 -0
  3. requirements.txt +8 -0
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /code
4
+
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ COPY . .
9
+
10
+ EXPOSE 7860
11
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File
2
+ import torch
3
+ from safetensors.torch import load_file
4
+ from torchvision import transforms
5
+ from PIL import Image
6
+ import io
7
+ from torchvision import models
8
+ app = FastAPI()
9
+
10
+ # =============== LOAD MODEL SAFETENSORS ==================
11
+ class Dense121(nn.Module):
12
+ def __init__(self, num_classes, pretrained=True):
13
+ super(Dense121, self).__init__()
14
+ if pretrained:
15
+ try:
16
+ weights = models.DenseNet121_Weights.IMAGENET1K_V1
17
+ self.dense121 = models.densenet121(weights=weights)
18
+ except:
19
+ self.dense121 = models.densenet121(pretrained=True)
20
+ else:
21
+ self.dense121 = models.densenet121(pretrained=False)
22
+
23
+ # classifier DenseNet bukan list, jadi langsung akses in_features
24
+ in_features = self.dense121.classifier.in_features
25
+ self.dense121.classifier = nn.Linear(in_features, num_classes)
26
+
27
+ def forward(self, x):
28
+ return self.dense121(x)
29
+
30
+
31
+ model = Dense121()
32
+ state_dict = load_file("model_stunting.safetensors")
33
+ model.load_state_dict(state_dict)
34
+ model.eval()
35
+
36
+ # =============== IMAGE PREPROCESS ==================
37
+ preprocess = transforms.Compose([
38
+ transforms.Resize((224, 224)),
39
+ transforms.ToTensor(), # [0..1]
40
+ ])
41
+
42
+ # =============== API ENDPOINT ==================
43
+ @app.post("/predict-image")
44
+ async def predict(file: UploadFile = File(...)):
45
+
46
+ img_bytes = await file.read()
47
+ img = Image.open(io.BytesIO(img_bytes)).convert("RGB")
48
+ tensor = preprocess(img).unsqueeze(0) # shape: (1, 3, 224, 224)
49
+
50
+ with torch.no_grad():
51
+ output = model(tensor)
52
+ probs = torch.softmax(output, dim=1).numpy().tolist()[0]
53
+
54
+ return {
55
+ "prediction": probs,
56
+ "label": "stunting" if probs[1] > 0.5 else "normal",
57
+ "confidence": max(probs),
58
+ }
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ python-multipart
4
+ torch
5
+ torchvision
6
+ safetensors
7
+ pillow
8
+ numpy