Instructions to use Liiesl/text-styling-classificationv1 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- timm
How to use Liiesl/text-styling-classificationv1 with timm:
import timm model = timm.create_model("hf_hub:Liiesl/text-styling-classificationv1", pretrained=True) - Notebooks
- Google Colab
- Kaggle
Text Styling Multi-Task Model (EdgeNeXt-Small)
This model performs fine-grained text attribute and styling extraction from cropped text line images. Built upon a lightweight edgenext_small backbone, the model processes an input image of fixed dimensions ($64 \times 160$) and simultaneously predicts typography styles, background modalities, and color attributes across 8 dedicated heads.
π Model Summary
- Backbone:
edgenext_small(pretrained viatimm) - Spatial Pooling: Adaptive Average Pooling to $(2 \times 5)$ ($304 \times 2 \times 5 = 3040\text{d}$)
- Bottleneck:
Linear(3040, 256) -> BatchNorm1d -> Hardswish -> Dropout(0.2) - Input Resolution: $64 \times 160$ (Height $\times$ Width), 3 RGB Channels
- Export Format: PyTorch Checkpoints (
.pth.tar) & ONNX (opset 18, dynamic batch size)
π― Prediction Heads & Output Specification
The model outputs 8 multi-task tensors:
| Output Name | Shape | Range / Activation | Description |
|---|---|---|---|
flags |
[B, 5] |
Raw Logits $\to \sigma(x) \in [0, 1]$ | Binary flags: [is_bold, is_italic, has_stroke, has_shadow, has_glow] |
bg_type |
[B, 3] |
Raw Logits $\to \text{Softmax}$ | Classification: 0: Solid, 1: Gradient, 2: Artwork/Image |
text_color |
[B, 3] |
Clamped $[0.0, 1.0]$ | Primary text fill color (RGB) |
effect_color |
[B, 3] |
Clamped $[0.0, 1.0]$ | Outer effect color (Stroke / Shadow / Glow RGB) (Valid if effect flags $> 0.5$) |
bg_color |
[B, 3] |
Clamped $[0.0, 1.0]$ | Solid background color (RGB) (Valid if bg_type == 0) |
bg_color_a |
[B, 3] |
Clamped $[0.0, 1.0]$ | Gradient start color (RGB) (Valid if bg_type == 1) |
bg_color_b |
[B, 3] |
Clamped $[0.0, 1.0]$ | Gradient end color (RGB) (Valid if bg_type == 1) |
bg_direction |
[B, 2] |
Unit Vector $[\sin \theta, \cos \theta]$ | Gradient angle direction (Valid if bg_type == 1) |
π Quickstart Inference
ONNX Runtime (Recommended for Deployment)
import numpy as np
import onnxruntime as ort
from PIL import Image
# Initialize Session
session = ort.InferenceSession("text_styling_model.onnx", providers=["CPUExecutionProvider"])
def preprocess(img_path):
img = Image.open(img_path).convert("RGB").resize((160, 64), Image.BICUBIC)
arr = np.array(img).astype(np.float32) / 255.0
# Normalize with ImageNet mean/std
mean = np.array([0.485, 0.456, 0.406], dtype=np.float32)
std = np.array([0.229, 0.224, 0.225], dtype=np.float32)
arr = (arr - mean) / std
arr = np.transpose(arr, (2, 0, 1)) # HWC to CHW
return np.expand_dims(arr, axis=0) # Add batch dim [1, 3, 64, 160]
# Run Inference
input_tensor = preprocess("sample_text.png")
outputs = session.run(None, {"input": input_tensor})
(pred_flags, pred_bg_type, pred_text_c, pred_effect_c,
pred_bg_c, pred_bg_ca, pred_bg_cb, pred_bg_dir) = outputs
# Post-process Flags
sigmoid = lambda x: 1 / (1 + np.exp(-x))
flag_probs = sigmoid(pred_flags[0])
flag_names = ["Bold", "Italic", "Stroke", "Shadow", "Glow"]
detected_flags = {name: bool(prob > 0.5) for name, prob in zip(flag_names, flag_probs)}
# Post-process Background Type
bg_types = ["Solid", "Gradient", "Artwork"]
bg_type_idx = int(np.argmax(pred_bg_type[0]))
# Post-process Gradient Angle (if gradient)
sin_val, cos_val = pred_bg_dir[0]
angle_rad = np.arctan2(sin_val, cos_val)
angle_deg = (np.degrees(angle_rad) + 360) % 360
print(f"Flags: {detected_flags}")
print(f"Background Type: {bg_types[bg_type_idx]}")
print(f"Text Color (RGB [0-255]): {(pred_text_c[0] * 255).astype(int).tolist()}")
if any([detected_flags["Stroke"], detected_flags["Shadow"], detected_flags["Glow"]]):
print(f"Effect Color (RGB [0-255]): {(pred_effect_c[0] * 255).astype(int).tolist()}")
if bg_type_idx == 0:
print(f"Solid BG Color (RGB): {(pred_bg_c[0] * 255).astype(int).tolist()}")
elif bg_type_idx == 1:
print(f"Gradient Start Color (RGB): {(pred_bg_ca[0] * 255).astype(int).tolist()}")
print(f"Gradient End Color (RGB): {(pred_bg_cb[0] * 255).astype(int).tolist()}")
print(f"Gradient Angle: {angle_deg:.1f}Β°")
π οΈ Training Details
- Loss Function: Multi-Task Loss combining:
- Binary Cross Entropy with Logits for typography flags.
- Cross Entropy for background category.
- Smooth L1 (Huber Loss, $\beta=0.1$) with sample masking for RGB continuous targets.
- Cosine Distance $(1 - \cos \theta)$ for periodic gradient angle direction.
- Optimizer:
AdamW($\text{lr}=10^{-3}$, weight decay $= 10^{-4}$) with gradient clipping (max_norm=1.0). - Scheduler: Cosine Annealing with 1 warmup epoch.
- Weight Averaging: Step-count normalized Exponential Moving Average (
ModelEmaV2). - Mixed Precision: Distributed FP16 training with HuggingFace Accelerate across $2\times\text{NVIDIA T4}$.
β οΈ Intended Limitations & Edge Cases
- Aspect Ratio & Resolution: Optimized for horizontal text strip crops rendered or resized to $64 \times 160$. Vertical text arrangements or extreme aspect ratios may degrade spatial boundary perception.
- Masked Heads Dependency:
effect_colorpredictions should only be evaluated when one or more of[Stroke, Shadow, Glow]flags are positive.bg_coloris only valid whenbg_type == Solid (0).bg_color_a,bg_color_b, andbg_directionare only valid whenbg_type == Gradient (1).- For
bg_type == Artwork (2), no background color regression is guaranteed.
- Downloads last month
- -
Inference Providers NEW
This model isn't deployed by any Inference Provider. π Ask for provider support
Model tree for Liiesl/text-styling-classificationv1
Base model
timm/edgenext_small.usi_in1k