from datetime import datetime from zoneinfo import ZoneInfo from app.models import db class Model(db.Model): """ 模型类,表示数据库中的 'model' 表。 该类存储不同训练模型的基本信息和性能评估指标。 包括模型名称、存储路径、训练数据增强方法、计算量、目标检测精度与召回率、分割掩膜性能等。 模型还包含与用户、检测分割记录的关系,支持对不同模型进行评估和管理。 Attributes: model_id (int): 模型的唯一标识符(主键)。 model_name (str): 模型名称,必须唯一,不能为空。 model_path (str): 模型存储路径,必须唯一,不能为空。 disease_category (str): 模型所处理的病害类别。 augmentation (str): 使用的数据增强方式。 layers (int): 模型的层数。 parameters (int): 模型的参数量。 GFLOPs (float): 模型的计算量(Giga Floating-Point Operations)。 box_p (float): 目标检测框的精度。 box_r (float): 目标检测框的召回率。 box_mAP50 (float): 目标检测框在 IoU=0.5 时的 mAP(mean Average Precision)。 box_mAP50_95 (float): 目标检测框在 IoU 从 0.5 到 0.95 的 mAP。 mask_p (float): 分割掩膜的精度。 mask_r (float): 分割掩膜的召回率。 mask_mAP50 (float): 分割掩膜在 IoU=0.5 时的 mAP。 mask_mAP50_95 (float): 分割掩膜在 IoU 从 0.5 到 0.95 的 mAP。 f1_score (float): 模型的 F1 分数,综合精度和召回率的性能指标。 fitness_score (float): 模型的适应度分数,用于评估模型的整体性能。 created_at (datetime): 模型记录的创建时间,自动生成。 updated_at (datetime): 模型记录的最后更新时间,自动更新。 owner_id (int): 所属用户的 ID(外键)。 Relationships: owner (User): 一个模型只属于一个用户,表示该模型的所有者。 detections (Detection): 一个模型可以有多个检测分割记录(反向关系,表示该模型应用于的检测任务)。 """ __tablename__ = 'model' # 表名 model_id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 模型 ID model_name = db.Column(db.String(255), unique=True, nullable=False) # 模型名称 model_path = db.Column(db.String(255), unique=True, nullable=False) # 存储路径 disease_category = db.Column(db.String(100), nullable=False) # 病害类别 augmentation = db.Column(db.String(255), default='原图') # 数据增强方式 layers = db.Column(db.Integer, nullable=False, default=0) # 层数 parameters = db.Column(db.Integer, nullable=False, default=0) # 参数量 GFLOPs = db.Column(db.Float, nullable=False, default=lambda: round(0.0, 1)) # 计算量 box_p = db.Column(db.Float, default=lambda: round(0.0, 3)) # 目标检测框的精度 box_r = db.Column(db.Float, default=lambda: round(0.0, 3)) # 目标检测框的召回率 box_mAP50 = db.Column(db.Float, default=lambda: round(0.0, 3)) # 目标检测框在 IoU=0.5 时的 mAP box_mAP50_95 = db.Column(db.Float, default=lambda: round(0.0, 3)) # 目标检测框在 IoU 从 0.5 到 0.95 的 mAP mask_p = db.Column(db.Float, default=lambda: round(0.0, 3)) # 分割掩膜的精度 mask_r = db.Column(db.Float, default=lambda: round(0.0, 3)) # 分割掩膜的召回率 mask_mAP50 = db.Column(db.Float, default=lambda: round(0.0, 3)) # 分割掩膜在 IoU=0.5 时的 mAP mask_mAP50_95 = db.Column(db.Float, default=lambda: round(0.0, 3)) # 分割掩膜在 IoU 从 0.5 到 0.95 的 mAP f1_score = db.Column(db.Float, default=lambda: round(0.0, 5), nullable=False) # F1 分数 fitness_score = db.Column(db.Float, default=lambda: round(0.0, 5), nullable=False) # 适应度分数 created_at = db.Column(db.DateTime, default=lambda: datetime.now(ZoneInfo("Asia/Shanghai"))) # 创建时间 updated_at = db.Column(db.DateTime, default=lambda: datetime.now(ZoneInfo("Asia/Shanghai")), onupdate=lambda: datetime.now(ZoneInfo("Asia/Shanghai"))) # 最后更新时间 owner_id = db.Column(db.Integer, db.ForeignKey('user.user_id'), nullable=False) # 所属用户 ID(外键) # 设置与 User 表的关系:一个模型只属于一个用户 owner = db.relationship('User', backref=db.backref('models', lazy=True)) def __repr__(self): return (f"Model(model_id={self.model_id}, " f"model_name={self.model_name}, " f"model_path={self.model_path}, " f"disease_category={self.disease_category}, " f"augmentation={self.augmentation}, " f"layers={self.layers}, " f"parameters={self.parameters}, " f"GFLOPs={self.GFLOPs}, " f"box_p={self.box_p}, " f"box_r={self.box_r}, " f"box_mAP50={self.box_mAP50}, " f"box_mAP50_95={self.box_mAP50_95}, " f"mask_p={self.mask_p}, " f"mask_r={self.mask_r}, " f"mask_mAP50={self.mask_mAP50}, " f"mask_mAP50_95={self.mask_mAP50_95}, " f"f1_score={self.f1_score}, " f"fitness_score={self.fitness_score}, " f"created_at={self.created_at}, " f"updated_at={self.updated_at}, " f"owner_id={self.owner_id})") def to_dict(self): """ 将 Model 实例转化为字典。 """ return { 'model_id': self.model_id, 'model_name': self.model_name, 'model_path': self.model_path, 'disease_category': self.disease_category, 'augmentation': self.augmentation, 'layers': self.layers, 'parameters': self.parameters, 'GFLOPs': self.GFLOPs, 'box_p': self.box_p, 'box_r': self.box_r, 'box_mAP50': self.box_mAP50, 'box_mAP50_95': self.box_mAP50_95, 'mask_p': self.mask_p, 'mask_r': self.mask_r, 'mask_mAP50': self.mask_mAP50, 'mask_mAP50_95': self.mask_mAP50_95, 'f1_score': self.f1_score, 'fitness_score': self.fitness_score, 'created_at': self.created_at, 'updated_at': self.updated_at, 'owner_id': self.owner_id }