def train_cct_low_entropy(model, ema_ground, trainloader, testloader, epochs=50,
                          lr=0.001, device='cuda',
                          entropy_target=0.1,          # much lower than 0.27
                          beta_init=0.5,               # weight for direct entropy term
                          beta_max=2.0,
                          beta_gain=1.05,
                          use_adaptive_beta=True):
    """
    Actively minimizes entropy by adding β * entropy to the loss.
    """
    model.to(device)
    optimizer = optim.Adam(model.parameters(), lr=lr)
    criterion_ce = nn.CrossEntropyLoss()
    
    beta = beta_init
    entropy_history = []
    beta_history = []
    test_acc_history = []
    
    for epoch in range(epochs):
        model.train()
        running_loss_ce = 0.0
        running_entropy = 0.0
        batch_count = 0
        
        for inputs, labels in trainloader:
            inputs, labels = inputs.to(device), labels.to(device)
            
            outputs = model(inputs)
            loss_ce = criterion_ce(outputs, labels)
            
            # Compute entropy (divergence from EMA ground)
            with torch.no_grad():
                ground_outputs = ema_ground.get_ground()(inputs)
                entropy = F.mse_loss(outputs, ground_outputs).item()
            
            # Total loss = cross‑entropy + β * entropy (direct minimization)
            loss = loss_ce + beta * entropy
            
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            running_loss_ce += loss_ce.item()
            running_entropy += entropy
            batch_count += 1
        
        avg_entropy = running_entropy / batch_count
        entropy_history.append(avg_entropy)
        
        # Update EMA ground model
        ema_ground.update(model)
        
        # Adaptive β: increase if entropy > target, decrease if entropy < target/2
        if use_adaptive_beta:
            if avg_entropy > entropy_target:
                beta = min(beta * beta_gain, beta_max)
            elif avg_entropy < entropy_target * 0.5:
                beta = max(beta_init, beta * 0.99)
        
        beta_history.append(beta)
        
        # Test accuracy
        model.eval()
        correct = 0
        total = 0
        with torch.no_grad():
            for inputs, labels in testloader:
                inputs, labels = inputs.to(device), labels.to(device)
                outputs = model(inputs)
                _, predicted = torch.max(outputs, 1)
                total += labels.size(0)
                correct += (predicted == labels).sum().item()
        acc = 100 * correct / total
        test_acc_history.append(acc)
        
        print(f"Epoch {epoch+1:3d} | CE Loss: {running_loss_ce/len(trainloader):.4f} | "
              f"Entropy: {avg_entropy:.4f} | β: {beta:.3f} | Test Acc: {acc:.2f}%")
    
    return model, entropy_history, beta_history, test_acc_history