Compare commits

..
25 Commits
Author SHA1 Message Date
Brian Bjarke Jensen 493da70ba4 updated to do prediction and print result 2024-07-28 23:22:40 +02:00
Brian Bjarke Jensen b415137e25 added method to instantiate from prediction dict 2024-07-28 23:19:51 +02:00
Brian Bjarke Jensen cead3d24c8 added from_tensor method 2024-07-28 23:13:15 +02:00
Brian Bjarke Jensen 0bfbb1920c fixed conversion of classes 2024-07-28 23:12:06 +02:00
Brian Bjarke Jensen 164102557e removed unused import 2024-07-28 23:10:15 +02:00
Brian Bjarke Jensen cf923a228d updated model name reference 2024-07-28 21:37:28 +02:00
Brian Bjarke Jensen 9f4a09a18c fixed definition of layers 2024-07-28 21:36:21 +02:00
Brian Bjarke Jensen 849b59e575 removed double connection to minio 2024-07-28 21:34:56 +02:00
Brian Bjarke Jensen 4a7e33b527 updated referenced model name 2024-07-28 21:32:16 +02:00
Brian Bjarke Jensen e5fad6d765 added function to generate and save new model 2024-07-28 21:31:48 +02:00
Brian Bjarke Jensen be6833ac6a added option to download weights 2024-07-28 21:25:24 +02:00
Brian Bjarke Jensen 6541a47668 added option to download resnet18 weights 2024-07-28 21:19:47 +02:00
Brian Bjarke Jensen 96ccdb5c90 moved file for clarity 2024-07-28 21:16:32 +02:00
Brian Bjarke Jensen 6e9c0a2626 fixed number of inputs 2024-07-28 21:13:51 +02:00
Brian Bjarke Jensen 396bf29f32 updated function name 2024-07-28 21:08:51 +02:00
Brian Bjarke Jensen 05774364fc renamed function for clarity 2024-07-28 21:08:27 +02:00
Brian Bjarke Jensen 74a9538feb renamed function for clarity 2024-07-28 21:05:15 +02:00
Brian Bjarke Jensen 9423c3378a fixed dockerfile syntax 2024-07-28 21:02:59 +02:00
Brian Bjarke Jensen e6fdbfe0b0 changed to not download pretrained weights for ResNet18 2024-07-28 21:01:19 +02:00
Brian Bjarke Jensen 6c354b23bd test run prediction on image 2024-07-27 21:41:29 +02:00
Brian Bjarke Jensen 3ad6c161b1 added new modules 2024-07-27 21:40:38 +02:00
Brian Bjarke Jensen a1ff6a6f33 moved for clarity 2024-07-27 21:40:17 +02:00
Brian Bjarke Jensen cf4f67d7a5 installed tqdm 2024-07-27 21:38:18 +02:00
Brian Bjarke Jensen 7c968db8ac renamed file for clarity 2024-07-27 21:18:39 +02:00
Brian Bjarke Jensen e656cd4e12 remove unneeded code for running in docker container 2024-07-27 21:08:47 +02:00
30 changed files with 217 additions and 190 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
# build stage # build stage
FROM python:3.12-slim-bookworm as BUILDER FROM python:3.12-slim-bookworm AS builder
# set environment variables # set environment variables
ENV PYTHONUNBUFFERED=1 \ ENV PYTHONUNBUFFERED=1 \
+1 -1
View File
@@ -1,5 +1,5 @@
# build stage # build stage
FROM python:3.12-slim-bookworm as BUILDER FROM python:3.12-slim-bookworm AS builder
# set environment variables # set environment variables
ENV PYTHONUNBUFFERED=1 \ ENV PYTHONUNBUFFERED=1 \
+35 -12
View File
@@ -1,25 +1,48 @@
"""Main script to be run by service.""" """Main script to be run by service."""
from pathlib import Path import json
import logging
from traceback import print_exc
from dotenv import load_dotenv import torch
from models import VisualCommunicationModel from models import VisualCommunicationModel
from torchinfo import summary from tqdm import tqdm
from utils import load_model from utils import DEVICE, VCDADataset, load_model
from shared.data_store import connect from shared.data_store import connect_minio
from shared.dto import ModelData
from shared.utils import setup_logging from shared.utils import setup_logging
if __name__ == '__main__': if __name__ == '__main__':
# load in env file
env_path = Path(__file__).parent.parent.parent / 'server.env'
load_dotenv(env_path)
# setup logging # setup logging
setup_logging() setup_logging()
# connect to minio # connect to minio
minio_client = connect() minio_client = connect_minio()
# instantiate model # instantiate model
model: VisualCommunicationModel = load_model(client=minio_client) model: VisualCommunicationModel = load_model(client=minio_client)
# show model weights model.eval()
summary(model) # setup dataset
print('loaded model') dataset = VCDADataset(
minio_client=minio_client,
data_name_list=[
'02dbaf48d713e4e6d3a6b98fd2dc866e',
],
do_augment=False,
)
# make prediction
with torch.no_grad():
for i in tqdm(range(len(dataset))):
try:
# get image
image = dataset[i]
image = torch.unsqueeze(image, 0) # add artificial batch dimension
image = image.to(DEVICE)
# make prediction
pred: ModelData = model(image)
except Exception:
print_exc()
continue
else:
print(json.dumps(pred.model_dump(), indent=4))
logging.debug('finished')
+1 -1
View File
@@ -1 +1 @@
fb75db772ba8b280bdaf1774d5f73f58 2bbe2be17a663f4299657378ac5e993e
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
+8 -10
View File
@@ -1,26 +1,24 @@
from __future__ import annotations from torch import nn
import torch.nn as nn
class FullyConnectedModel(nn.Module): class FullyConnectedModel(nn.Module):
"""Fully connected layers model template for intrepreting feature space-
output from ResNet18 head."""
def __init__(self, num_out_features: int): def __init__(self, num_out_features: int):
super().__init__() super().__init__()
# define layers # define layers
self.fc1 = nn.Linear(in_features=16*16*512, out_features=512) self.fc1 = nn.Linear(in_features=512, out_features=128)
self.af1 = nn.ReLU() self.af1 = nn.ReLU()
self.fc2 = nn.Linear(in_features=512, out_features=128) self.fc2 = nn.Linear(in_features=128, out_features=32)
self.af2 = nn.ReLU() self.af2 = nn.ReLU()
self.fc3 = nn.Linear(in_features=128, out_features=32) self.fc3 = nn.Linear(in_features=32, out_features=num_out_features)
self.af3 = nn.ReLU()
self.fc4 = nn.Linear(in_features=32, out_features=num_out_features)
def forward(self, x): def forward(self, x):
"""Pass input through model."""
x = self.fc1(x) x = self.fc1(x)
x = self.af1(x) x = self.af1(x)
x = self.fc2(x) x = self.fc2(x)
x = self.af2(x) x = self.af2(x)
x = self.fc3(x) x = self.fc3(x)
x = self.af3(x)
x = self.fc4(x)
return x return x
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
+7 -3
View File
@@ -5,11 +5,15 @@ import torchvision
class ResNet18Head(nn.Module): class ResNet18Head(nn.Module):
def __init__(self): def __init__(self, download_resnet_weights: bool = False):
super().__init__() super().__init__()
# copy out parts from ResNet18 with weights # copy out parts from ResNet18 with weights
if download_resnet_weights:
weights = torchvision.models.ResNet18_Weights.IMAGENET1K_V1
else:
weights = None
resnet18 = torchvision.models.resnet18( resnet18 = torchvision.models.resnet18(
weights=torchvision.models.ResNet18_Weights.IMAGENET1K_V1, weights=weights,
) )
# save relevant layers # save relevant layers
self.conv1 = resnet18.conv1 self.conv1 = resnet18.conv1
@@ -21,7 +25,7 @@ class ResNet18Head(nn.Module):
self.layer3 = resnet18.layer3 self.layer3 = resnet18.layer3
self.layer4 = resnet18.layer4 self.layer4 = resnet18.layer4
self.avgpool = resnet18.avgpool self.avgpool = resnet18.avgpool
self.flat = nn.Flatten() # size 512 self.flat = nn.Flatten() # size 512
def forward(self, x): def forward(self, x):
x = self.conv1(x) x = self.conv1(x)
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
+22 -86
View File
@@ -4,19 +4,7 @@ from __future__ import annotations
from torch import nn from torch import nn
from shared.dto import ( from shared.dto import ModelData
AngleData,
ContactData,
DistanceData,
FramingData,
InformationValueData,
ModalityColorData,
ModalityDepthData,
ModalityLightingData,
PointOfViewData,
SalienceData,
VisualSyntaxData,
)
from .angle import AngleTail from .angle import AngleTail
from .contact import ContactTail from .contact import ContactTail
@@ -35,10 +23,10 @@ from .visual_syntax import VisualSyntaxTail
class VisualCommunicationModel(nn.Module): class VisualCommunicationModel(nn.Module):
"""Visual communication model.""" """Visual communication model."""
def __init__(self): def __init__(self, download_resnet_weights: bool = False):
super().__init__() super().__init__()
# store other models # store other models
self.resnet_head = ResNet18Head() self.resnet_head = ResNet18Head(download_resnet_weights)
self.visual_syntax_tail = VisualSyntaxTail() self.visual_syntax_tail = VisualSyntaxTail()
self.contact_tail = ContactTail() self.contact_tail = ContactTail()
self.angle_tail = AngleTail() self.angle_tail = AngleTail()
@@ -51,76 +39,24 @@ class VisualCommunicationModel(nn.Module):
self.framing_tail = FramingTail() self.framing_tail = FramingTail()
self.salience_tail = SalienceTail() self.salience_tail = SalienceTail()
def forward(self, x): def forward(self, x) -> ModelData:
"""Calculate model output on data.""" """Calculate model output on data."""
# generate visual representation # generate visual representation
vis_rep = self.resnet_head(x) features = self.resnet_head(x)
# prepare result map # make predictions
results = {} prediction_dict = {
# predict visual syntax 'visual_syntax': self.visual_syntax_tail(features),
results['visual_syntax'] = VisualSyntaxData.from_list( 'contact': self.contact_tail(features),
self.visual_syntax_tail( 'angle': self.angle_tail(features),
vis_rep, 'point_of_view': self.point_of_view_tail(features),
).cpu(), 'distance': self.distance_tail(features),
) 'modality_lighting': self.modality_lighting_tail(features),
# predict contact 'modality_color': self.modality_color_tail(features),
results['contact'] = ContactData.from_list( 'modality_depth': self.modality_depth_tail(features),
self.contact_tail( 'information_value': self.information_value_tail(features),
vis_rep, 'framing': self.framing_tail(features),
).cpu(), 'salience': self.salience_tail(features),
) }
# predict angle # convert to respective classes
results['angle'] = AngleData.from_list( data = ModelData.from_prediction_dict(prediction_dict)
self.angle_tail( return data
vis_rep,
).cpu(),
)
# predict point of view
results['point_of_view'] = PointOfViewData.from_list(
self.point_of_view_tail(
vis_rep,
).cpu(),
)
# predict distance
results['distance'] = DistanceData.from_list(
self.distance_tail(
vis_rep,
).cpu(),
)
# predict modality lighting
results['modality_lighting'] = ModalityLightingData.from_list(
self.modality_lighting_tail(
vis_rep,
).cpu(),
)
# predict modality color
results['modality_color'] = ModalityColorData.from_list(
self.modality_color_tail(
vis_rep,
).cpu(),
)
# predict modality depth
results['modality_depth'] = ModalityDepthData.from_list(
self.modality_depth_tail(
vis_rep,
).cpu(),
)
# predict information value
results['information_value'] = InformationValueData.from_list(
self.information_value_tail(
vis_rep,
).cpu(),
)
# predict framing
results['framing'] = FramingData.from_list(
self.framing_tail(
vis_rep,
).cpu(),
)
# predict salience
results['salience'] = SalienceData.from_list(
self.salience_tail(
vis_rep,
).cpu(),
)
return results
-2
View File
@@ -1,5 +1,3 @@
from __future__ import annotations
from .fully_connected import FullyConnectedModel from .fully_connected import FullyConnectedModel
+2 -1
View File
@@ -1 +1,2 @@
from .load_model import load_model from .load_model import DEVICE, load_model
from .vcda_dataset import VCDADataset
@@ -6,7 +6,7 @@ import torch
import torch.nn as nn import torch.nn as nn
from dataloader import VCDADataset # noqa: F401 from dataloader import VCDADataset # noqa: F401
from .models import VisualCommunicationModel from ..models import VisualCommunicationModel
PRE_WARMUP_LR = 1e-10 PRE_WARMUP_LR = 1e-10
POST_WARMUP_LR = 1e-5 POST_WARMUP_LR = 1e-5
@@ -2,6 +2,7 @@
import random import random
from minio import Minio
from PIL import Image from PIL import Image
from torch import Tensor from torch import Tensor
from torch.utils.data import Dataset from torch.utils.data import Dataset
@@ -15,7 +16,7 @@ from torchvision.transforms.functional import (
to_tensor, to_tensor,
) )
from shared.data_store import connect, get_image from shared.data_store import get_image
# resnet18 original normalization values # resnet18 original normalization values
RESNET_NORMALIZE_MEAN = [0.485, 0.456, 0.406] RESNET_NORMALIZE_MEAN = [0.485, 0.456, 0.406]
@@ -27,11 +28,13 @@ class VCDADataset(Dataset):
def __init__( def __init__(
self, self,
minio_client: Minio,
data_name_list: list[str], data_name_list: list[str],
do_augment: bool = False, do_augment: bool = False,
random_annotations: bool = False, random_annotations: bool = False,
): ):
super().__init__() super().__init__()
self.minio_client = minio_client
self.data_name_list = data_name_list self.data_name_list = data_name_list
self.do_augment = do_augment self.do_augment = do_augment
self.random_annotations = random_annotations self.random_annotations = random_annotations
@@ -47,9 +50,6 @@ class VCDADataset(Dataset):
contrast=8e-2, contrast=8e-2,
saturation=8e-2, saturation=8e-2,
) )
# connect to minio
minio_client = connect()
self.minio_client = minio_client
def __len__(self): def __len__(self):
return len(self.data_name_list) return len(self.data_name_list)
Generated
+26 -1
View File
@@ -2228,6 +2228,31 @@ type = "legacy"
url = "http://192.168.1.2:5001/index" url = "http://192.168.1.2:5001/index"
reference = "threadripper" reference = "threadripper"
[[package]]
name = "tqdm"
version = "4.66.4"
description = "Fast, Extensible Progress Meter"
optional = false
python-versions = ">=3.7"
files = [
{file = "tqdm-4.66.4-py3-none-any.whl", hash = "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644"},
{file = "tqdm-4.66.4.tar.gz", hash = "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[package.extras]
dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"]
notebook = ["ipywidgets (>=6)"]
slack = ["slack-sdk"]
telegram = ["requests"]
[package.source]
type = "legacy"
url = "http://192.168.1.2:5001/index"
reference = "threadripper"
[[package]] [[package]]
name = "trio" name = "trio"
version = "0.25.1" version = "0.25.1"
@@ -2481,4 +2506,4 @@ reference = "threadripper"
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.12" python-versions = "^3.12"
content-hash = "adcc6b2cdc33ee2aa56b419d6123e3d1553b08641cd81c22b187ecd0096812b1" content-hash = "8caa4d24aec4c8cd5b1e726f2e00bc0cf8d865350aa5dc4282fc88d53d1b944c"
+1
View File
@@ -34,6 +34,7 @@ torch = "^2.2.1"
torchvision = "^0.17.1" torchvision = "^0.17.1"
torchinfo = "^1.8.0" torchinfo = "^1.8.0"
minio = "^7.2.7" minio = "^7.2.7"
tqdm = "^4.66.4"
[tool.poetry.group.shared.dependencies] [tool.poetry.group.shared.dependencies]
+1 -1
View File
@@ -1,4 +1,4 @@
from .connect import connect from .connect_minio import connect_minio
from .delete import delete from .delete import delete
from .get import get from .get import get
from .get_image import get_image from .get_image import get_image
@@ -6,7 +6,7 @@ import os
from minio import Minio from minio import Minio
def connect() -> Minio: def connect_minio() -> Minio:
"""Connect to MinIO server.""" """Connect to MinIO server."""
# ensure necessary env vars available # ensure necessary env vars available
env_var_list = [ env_var_list = [
+1 -2
View File
@@ -1,4 +1,3 @@
"""Database utils module content.""" """Database utils module content."""
from __future__ import annotations
from .connect import connect from .connect_mongodb import connect_mongodb
@@ -1,8 +1,5 @@
""" """Definition of function to connect to database using environment
Definition of function to connect to database variables."""
using environment variables.
"""
from __future__ import annotations
import logging import logging
import os import os
@@ -11,7 +8,7 @@ from dotenv import load_dotenv
from pymongo import MongoClient from pymongo import MongoClient
def connect(): def connect_mongodb():
"""Connect to MongoDB using env vars.""" """Connect to MongoDB using env vars."""
# load env vars # load env vars
load_dotenv() load_dotenv()
+13 -13
View File
@@ -1,10 +1,9 @@
"""Definition of DataModel base class.""" """Definition of DataModel base class."""
from __future__ import annotations
import random import random
from pydantic import BaseModel from pydantic import BaseModel, ValidationError
from pydantic import ValidationError from torch import Tensor
class DataModel(BaseModel): class DataModel(BaseModel):
@@ -33,26 +32,27 @@ class DataModel(BaseModel):
raise ValidationError() raise ValidationError()
assert isinstance(option, str), 'option is not a string' assert isinstance(option, str), 'option is not a string'
allowed_options_list = cls.list_fields() allowed_options_list = cls.list_fields()
assert option in allowed_options_list, \ assert (
f"{option} is not among allowed fields {allowed_options_list}" option in allowed_options_list
), f"{option} is not among allowed fields {allowed_options_list}"
kwargs = {field: 0 for field in cls.list_fields()} kwargs = {field: 0 for field in cls.list_fields()}
kwargs[option] = 1 kwargs[option] = 1
return cls(**kwargs) return cls(**kwargs)
@classmethod @classmethod
def from_list(cls, data_list: list[float]): def from_tensor(cls, tensor: Tensor):
"""Instantiate from list of values.""" """Instantiate from list of values."""
kwargs = {key: val for key, val in zip(cls.list_fields(), data_list)} assert tensor.size(dim=0) == 1, f'tensor batch larger than 1: {tensor}'
data_list = [float(t.item()) for t in tensor[0]]
kwargs = dict(zip(cls.list_fields(), data_list))
return cls(**kwargs) return cls(**kwargs)
def __repr__(self) -> str: def __repr__(self) -> str:
model_dict = self.model_dump() model_dict = self.model_dump()
model_repr_str = f"{self.classname()}(" model_repr_str = f'{self.classname()}('
model_repr_str += ', '.join([ model_repr_str += ', '.join(
f"{field}={value:.3f}" [f'{field}={value:.3f}' for field, value in model_dict.items()],
for field, value )
in model_dict.items()
])
model_repr_str += ')' model_repr_str += ')'
return model_repr_str return model_repr_str
+57 -24
View File
@@ -1,4 +1,5 @@
"""Definition of ModelData data model.""" """Definition of ModelData data model."""
from __future__ import annotations from __future__ import annotations
from .angle import AngleData from .angle import AngleData
@@ -17,6 +18,7 @@ from .visual_syntax import VisualSyntaxData
class ModelData(DataModel): class ModelData(DataModel):
"""ModelData model for data IO with combined ML model.""" """ModelData model for data IO with combined ML model."""
visual_syntax: VisualSyntaxData visual_syntax: VisualSyntaxData
contact: ContactData contact: ContactData
angle: AngleData angle: AngleData
@@ -34,8 +36,50 @@ class ModelData(DataModel):
"""Instantiate with random numbers.""" """Instantiate with random numbers."""
kwargs = { kwargs = {
field: field_info.annotation.from_random() # type: ignore field: field_info.annotation.from_random() # type: ignore
for field, field_info for field, field_info in cls.model_fields.items()
in cls.model_fields.items() }
return cls(**kwargs)
@classmethod
def from_prediction_dict(
cls,
prediction_dict: dict,
) -> ModelData:
"""Instantiate from prediction dictionary."""
kwargs = {
'visual_syntax': VisualSyntaxData.from_tensor(
prediction_dict['visual_syntax'],
),
'contact': ContactData.from_tensor(
prediction_dict['contact'],
),
'angle': AngleData.from_tensor(
prediction_dict['angle'],
),
'point_of_view': PointOfViewData.from_tensor(
prediction_dict['point_of_view'],
),
'distance': DistanceData.from_tensor(
prediction_dict['distance'],
),
'modality_lighting': ModalityLightingData.from_tensor(
prediction_dict['modality_lighting'],
),
'modality_color': ModalityColorData.from_tensor(
prediction_dict['modality_color'],
),
'modality_depth': ModalityDepthData.from_tensor(
prediction_dict['modality_depth'],
),
'information_value': InformationValueData.from_tensor(
prediction_dict['information_value'],
),
'framing': FramingData.from_tensor(
prediction_dict['framing'],
),
'salience': SalienceData.from_tensor(
prediction_dict['salience'],
),
} }
return cls(**kwargs) return cls(**kwargs)
@@ -56,27 +100,16 @@ class ModelData(DataModel):
) -> ModelData: ) -> ModelData:
"""Instantiate from annotation.""" """Instantiate from annotation."""
kwargs = { kwargs = {
'visual_syntax': VisualSyntaxData 'visual_syntax': VisualSyntaxData.from_choice(visual_syntax),
.from_choice(visual_syntax), 'contact': ContactData.from_choice(contact),
'contact': ContactData 'angle': AngleData.from_choice(angle),
.from_choice(contact), 'point_of_view': PointOfViewData.from_choice(point_of_view),
'angle': AngleData 'distance': DistanceData.from_choice(distance),
.from_choice(angle), 'modality_lighting': ModalityLightingData.from_choice(modality_lighting),
'point_of_view': PointOfViewData 'modality_color': ModalityColorData.from_choice(modality_color),
.from_choice(point_of_view), 'modality_depth': ModalityDepthData.from_choice(modality_depth),
'distance': DistanceData 'information_value': InformationValueData.from_choice(information_value),
.from_choice(distance), 'framing': FramingData.from_choice(framing),
'modality_lighting': ModalityLightingData 'salience': SalienceData.from_choice(salience),
.from_choice(modality_lighting),
'modality_color': ModalityColorData
.from_choice(modality_color),
'modality_depth': ModalityDepthData
.from_choice(modality_depth),
'information_value': InformationValueData
.from_choice(information_value),
'framing': FramingData
.from_choice(framing),
'salience': SalienceData
.from_choice(salience),
} }
return cls(**kwargs) return cls(**kwargs)
+32
View File
@@ -0,0 +1,32 @@
"""Definition of function to generate a new randomly initialized model and save
it in Minio datastore."""
from pathlib import Path
from dotenv import load_dotenv
from torchinfo import summary
from model.src.models import VisualCommunicationModel
from shared.data_store import connect_minio, put_model
from shared.utils import setup_logging
if __name__ == '__main__':
# load in env file
env_path = Path(__file__).parent.parent / 'server.env'
assert env_path.exists()
load_dotenv(env_path)
# setup logging
setup_logging()
# connect to minio
client = connect_minio()
# instantiate model
model = VisualCommunicationModel(download_resnet_weights=True)
# show model weights
summary(model)
# put buffer in minio bucket
hash_str = put_model(
client=client,
model=model,
)
print(f"hash string: {hash_str}")
print('saved to Minio')