raj5517's picture
Upload model.py with huggingface_hub
aa63775 verified
import tensorflow as tf
from tensorflow.keras import layers, Model
ACTIVITIES = [
'WALKING', 'WALKING_UPSTAIRS', 'WALKING_DOWNSTAIRS',
'SITTING', 'STANDING', 'LAYING'
]
N_CLASSES = len(ACTIVITIES)
INPUT_SHAPE = (128, 9) # 128 timesteps, 9 channels
def build_imu_model(input_shape=INPUT_SHAPE, n_classes=N_CLASSES):
"""
Compact 1D-CNN for IMU activity classification.
Designed from scratch for pruning + INT8 quantization.
Architecture rationale:
- Conv1D blocks β†’ extract local motion patterns per axis
- BatchNorm β†’ stable training, works well post-quantization
- MaxPooling β†’ downsample before deeper layers
- GlobalAvgPool β†’ replaces Flatten, much fewer params, less overfit
- Dense head β†’ final classifier
Total params: ~85K (intentionally small for edge deployment)
"""
inputs = tf.keras.Input(shape=input_shape, name='imu_input')
# ── Block 1 ──────────────────────────────
x = layers.Conv1D(32, kernel_size=5, padding='same',
activation='relu', name='conv1')(inputs)
x = layers.BatchNormalization(name='bn1')(x)
x = layers.MaxPooling1D(pool_size=2, name='pool1')(x) # 128 β†’ 64
x = layers.Dropout(0.1, name='drop1')(x)
# ── Block 2 ──────────────────────────────
x = layers.Conv1D(64, kernel_size=3, padding='same',
activation='relu', name='conv2')(x)
x = layers.BatchNormalization(name='bn2')(x)
x = layers.MaxPooling1D(pool_size=2, name='pool2')(x) # 64 β†’ 32
x = layers.Dropout(0.1, name='drop2')(x)
# ── Block 3 ──────────────────────────────
x = layers.Conv1D(128, kernel_size=3, padding='same',
activation='relu', name='conv3')(x)
x = layers.BatchNormalization(name='bn3')(x)
x = layers.MaxPooling1D(pool_size=2, name='pool3')(x) # 32 β†’ 16
x = layers.Dropout(0.1, name='drop4')(x)
# ── Block 4 (deeper feature extraction) ──
x = layers.Conv1D(128, kernel_size=3, padding='same',
activation='relu', name='conv4')(x)
x = layers.BatchNormalization(name='bn4')(x)
# ── Pooling + Head ────────────────────────
x = layers.GlobalAveragePooling1D(name='gap')(x) # [N, 128]
x = layers.Dense(64, activation='relu', name='dense1')(x)
x = layers.Dropout(0.3, name='drop5')(x)
outputs = layers.Dense(
n_classes, activation='softmax', name='activity'
)(x)
model = Model(inputs, outputs, name='IMU_Classifier')
return model
# ─────────────────────────────────────────────
# Quick sanity check when run directly
# ─────────────────────────────────────────────
if __name__ == '__main__':
model = build_imu_model()
model.summary()
total = model.count_params()
size_kb = total * 4 / 1024 # FP32 = 4 bytes per param
print(f"\n── Model Info ──────────────────────────")
print(f"Total parameters : {total:,}")
print(f"FP32 size estimate: {size_kb:.1f} KB")
print(f"Input shape : {INPUT_SHAPE}")
print(f"Output classes : {N_CLASSES} β†’ {ACTIVITIES}")
print(f"\nβœ… Model built successfully.")