javi-forge 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ci-local/ci-local.sh +20 -8
- package/package.json +1 -1
- package/ai-config/.skillignore +0 -15
- package/ai-config/AUTO_INVOKE.md +0 -300
- package/ai-config/agents/_TEMPLATE.md +0 -93
- package/ai-config/agents/business/api-designer.md +0 -1657
- package/ai-config/agents/business/business-analyst.md +0 -1331
- package/ai-config/agents/business/product-strategist.md +0 -206
- package/ai-config/agents/business/project-manager.md +0 -178
- package/ai-config/agents/business/requirements-analyst.md +0 -1277
- package/ai-config/agents/business/technical-writer.md +0 -1679
- package/ai-config/agents/creative/ux-designer.md +0 -205
- package/ai-config/agents/data-ai/ai-engineer.md +0 -487
- package/ai-config/agents/data-ai/analytics-engineer.md +0 -953
- package/ai-config/agents/data-ai/data-engineer.md +0 -173
- package/ai-config/agents/data-ai/data-scientist.md +0 -672
- package/ai-config/agents/data-ai/mlops-engineer.md +0 -814
- package/ai-config/agents/data-ai/prompt-engineer.md +0 -772
- package/ai-config/agents/development/angular-expert.md +0 -620
- package/ai-config/agents/development/backend-architect.md +0 -795
- package/ai-config/agents/development/database-specialist.md +0 -212
- package/ai-config/agents/development/frontend-specialist.md +0 -686
- package/ai-config/agents/development/fullstack-engineer.md +0 -668
- package/ai-config/agents/development/golang-pro.md +0 -338
- package/ai-config/agents/development/java-enterprise.md +0 -400
- package/ai-config/agents/development/javascript-pro.md +0 -422
- package/ai-config/agents/development/nextjs-pro.md +0 -474
- package/ai-config/agents/development/python-pro.md +0 -570
- package/ai-config/agents/development/react-pro.md +0 -487
- package/ai-config/agents/development/rust-pro.md +0 -246
- package/ai-config/agents/development/spring-boot-4-expert.md +0 -326
- package/ai-config/agents/development/typescript-pro.md +0 -336
- package/ai-config/agents/development/vue-specialist.md +0 -605
- package/ai-config/agents/infrastructure/cloud-architect.md +0 -472
- package/ai-config/agents/infrastructure/deployment-manager.md +0 -358
- package/ai-config/agents/infrastructure/devops-engineer.md +0 -455
- package/ai-config/agents/infrastructure/incident-responder.md +0 -519
- package/ai-config/agents/infrastructure/kubernetes-expert.md +0 -705
- package/ai-config/agents/infrastructure/monitoring-specialist.md +0 -674
- package/ai-config/agents/infrastructure/performance-engineer.md +0 -658
- package/ai-config/agents/orchestrator.md +0 -241
- package/ai-config/agents/quality/accessibility-auditor.md +0 -1204
- package/ai-config/agents/quality/code-reviewer-compact.md +0 -123
- package/ai-config/agents/quality/code-reviewer.md +0 -363
- package/ai-config/agents/quality/dependency-manager.md +0 -743
- package/ai-config/agents/quality/e2e-test-specialist.md +0 -1005
- package/ai-config/agents/quality/performance-tester.md +0 -1086
- package/ai-config/agents/quality/security-auditor.md +0 -133
- package/ai-config/agents/quality/test-engineer.md +0 -453
- package/ai-config/agents/specialists/api-designer.md +0 -87
- package/ai-config/agents/specialists/backend-architect.md +0 -73
- package/ai-config/agents/specialists/code-reviewer.md +0 -77
- package/ai-config/agents/specialists/db-optimizer.md +0 -75
- package/ai-config/agents/specialists/devops-engineer.md +0 -83
- package/ai-config/agents/specialists/documentation-writer.md +0 -78
- package/ai-config/agents/specialists/frontend-developer.md +0 -75
- package/ai-config/agents/specialists/performance-analyst.md +0 -82
- package/ai-config/agents/specialists/refactor-specialist.md +0 -74
- package/ai-config/agents/specialists/security-auditor.md +0 -74
- package/ai-config/agents/specialists/test-engineer.md +0 -81
- package/ai-config/agents/specialists/ux-consultant.md +0 -76
- package/ai-config/agents/specialized/agent-generator.md +0 -1190
- package/ai-config/agents/specialized/blockchain-developer.md +0 -149
- package/ai-config/agents/specialized/code-migrator.md +0 -892
- package/ai-config/agents/specialized/context-manager.md +0 -978
- package/ai-config/agents/specialized/documentation-writer.md +0 -1078
- package/ai-config/agents/specialized/ecommerce-expert.md +0 -1756
- package/ai-config/agents/specialized/embedded-engineer.md +0 -1714
- package/ai-config/agents/specialized/error-detective.md +0 -1034
- package/ai-config/agents/specialized/fintech-specialist.md +0 -1659
- package/ai-config/agents/specialized/freelance-project-planner-v2.md +0 -1988
- package/ai-config/agents/specialized/freelance-project-planner-v3.md +0 -2136
- package/ai-config/agents/specialized/freelance-project-planner-v4.md +0 -4503
- package/ai-config/agents/specialized/freelance-project-planner.md +0 -722
- package/ai-config/agents/specialized/game-developer.md +0 -1963
- package/ai-config/agents/specialized/healthcare-dev.md +0 -1620
- package/ai-config/agents/specialized/mobile-developer.md +0 -188
- package/ai-config/agents/specialized/parallel-plan-executor.md +0 -506
- package/ai-config/agents/specialized/plan-executor.md +0 -485
- package/ai-config/agents/specialized/solo-dev-planner-modular/00-INDEX.md +0 -485
- package/ai-config/agents/specialized/solo-dev-planner-modular/01-CORE.md +0 -3493
- package/ai-config/agents/specialized/solo-dev-planner-modular/02-SELF-CORRECTION.md +0 -778
- package/ai-config/agents/specialized/solo-dev-planner-modular/03-PROGRESSIVE-SETUP.md +0 -918
- package/ai-config/agents/specialized/solo-dev-planner-modular/04-DEPLOYMENT.md +0 -1537
- package/ai-config/agents/specialized/solo-dev-planner-modular/05-TESTING.md +0 -2633
- package/ai-config/agents/specialized/solo-dev-planner-modular/06-OPERATIONS.md +0 -5610
- package/ai-config/agents/specialized/solo-dev-planner-modular/INSTALL.md +0 -335
- package/ai-config/agents/specialized/solo-dev-planner-modular/QUICK-REFERENCE.txt +0 -215
- package/ai-config/agents/specialized/solo-dev-planner-modular/README.md +0 -260
- package/ai-config/agents/specialized/solo-dev-planner-modular/START-HERE.md +0 -379
- package/ai-config/agents/specialized/solo-dev-planner-modular/WORKFLOW-DIAGRAM.md +0 -355
- package/ai-config/agents/specialized/solo-dev-planner-modular/solo-dev-planner.md +0 -279
- package/ai-config/agents/specialized/template-writer.md +0 -347
- package/ai-config/agents/specialized/test-runner.md +0 -99
- package/ai-config/agents/specialized/vibekanban-smart-worker.md +0 -244
- package/ai-config/agents/specialized/wave-executor.md +0 -138
- package/ai-config/agents/specialized/workflow-optimizer.md +0 -1114
- package/ai-config/commands/git/changelog.md +0 -32
- package/ai-config/commands/git/ci-local.md +0 -70
- package/ai-config/commands/git/commit.md +0 -35
- package/ai-config/commands/git/fix-issue.md +0 -23
- package/ai-config/commands/git/pr-create.md +0 -42
- package/ai-config/commands/git/pr-review.md +0 -50
- package/ai-config/commands/git/worktree.md +0 -39
- package/ai-config/commands/refactoring/cleanup.md +0 -24
- package/ai-config/commands/refactoring/dead-code.md +0 -40
- package/ai-config/commands/refactoring/extract.md +0 -31
- package/ai-config/commands/testing/e2e.md +0 -30
- package/ai-config/commands/testing/tdd.md +0 -36
- package/ai-config/commands/testing/test-coverage.md +0 -30
- package/ai-config/commands/testing/test-fix.md +0 -24
- package/ai-config/commands/workflow/generate-agents-md.md +0 -85
- package/ai-config/commands/workflow/planning.md +0 -47
- package/ai-config/commands/workflows/compound.md +0 -89
- package/ai-config/commands/workflows/diagnose.md +0 -70
- package/ai-config/commands/workflows/discover.md +0 -86
- package/ai-config/commands/workflows/plan.md +0 -77
- package/ai-config/commands/workflows/review.md +0 -78
- package/ai-config/commands/workflows/work.md +0 -75
- package/ai-config/config.yaml +0 -18
- package/ai-config/hooks/_TEMPLATE.md +0 -96
- package/ai-config/hooks/block-dangerous-commands.md +0 -75
- package/ai-config/hooks/commit-guard.md +0 -90
- package/ai-config/hooks/context-loader.md +0 -73
- package/ai-config/hooks/improve-prompt.md +0 -91
- package/ai-config/hooks/learning-log.md +0 -72
- package/ai-config/hooks/model-router.md +0 -86
- package/ai-config/hooks/secret-scanner.md +0 -64
- package/ai-config/hooks/skill-validator.md +0 -102
- package/ai-config/hooks/task-artifact.md +0 -114
- package/ai-config/hooks/validate-workflow.md +0 -100
- package/ai-config/prompts/base.md +0 -71
- package/ai-config/prompts/modes/debug.md +0 -34
- package/ai-config/prompts/modes/deploy.md +0 -40
- package/ai-config/prompts/modes/research.md +0 -32
- package/ai-config/prompts/modes/review.md +0 -33
- package/ai-config/prompts/review-policy.md +0 -79
- package/ai-config/skills/_TEMPLATE.md +0 -157
- package/ai-config/skills/backend/api-gateway/SKILL.md +0 -254
- package/ai-config/skills/backend/bff-concepts/SKILL.md +0 -239
- package/ai-config/skills/backend/bff-spring/SKILL.md +0 -364
- package/ai-config/skills/backend/chi-router/SKILL.md +0 -396
- package/ai-config/skills/backend/error-handling/SKILL.md +0 -255
- package/ai-config/skills/backend/exceptions-spring/SKILL.md +0 -323
- package/ai-config/skills/backend/fastapi/SKILL.md +0 -302
- package/ai-config/skills/backend/gateway-spring/SKILL.md +0 -390
- package/ai-config/skills/backend/go-backend/SKILL.md +0 -457
- package/ai-config/skills/backend/gradle-multimodule/SKILL.md +0 -274
- package/ai-config/skills/backend/graphql-concepts/SKILL.md +0 -352
- package/ai-config/skills/backend/graphql-spring/SKILL.md +0 -398
- package/ai-config/skills/backend/grpc-concepts/SKILL.md +0 -283
- package/ai-config/skills/backend/grpc-spring/SKILL.md +0 -445
- package/ai-config/skills/backend/jwt-auth/SKILL.md +0 -412
- package/ai-config/skills/backend/notifications-concepts/SKILL.md +0 -259
- package/ai-config/skills/backend/recommendations-concepts/SKILL.md +0 -261
- package/ai-config/skills/backend/search-concepts/SKILL.md +0 -263
- package/ai-config/skills/backend/search-spring/SKILL.md +0 -375
- package/ai-config/skills/backend/spring-boot-4/SKILL.md +0 -172
- package/ai-config/skills/backend/websockets/SKILL.md +0 -532
- package/ai-config/skills/data-ai/ai-ml/SKILL.md +0 -423
- package/ai-config/skills/data-ai/analytics-concepts/SKILL.md +0 -195
- package/ai-config/skills/data-ai/analytics-spring/SKILL.md +0 -340
- package/ai-config/skills/data-ai/duckdb-analytics/SKILL.md +0 -440
- package/ai-config/skills/data-ai/langchain/SKILL.md +0 -238
- package/ai-config/skills/data-ai/mlflow/SKILL.md +0 -302
- package/ai-config/skills/data-ai/onnx-inference/SKILL.md +0 -290
- package/ai-config/skills/data-ai/powerbi/SKILL.md +0 -352
- package/ai-config/skills/data-ai/pytorch/SKILL.md +0 -274
- package/ai-config/skills/data-ai/scikit-learn/SKILL.md +0 -321
- package/ai-config/skills/data-ai/vector-db/SKILL.md +0 -301
- package/ai-config/skills/database/graph-databases/SKILL.md +0 -218
- package/ai-config/skills/database/graph-spring/SKILL.md +0 -361
- package/ai-config/skills/database/pgx-postgres/SKILL.md +0 -512
- package/ai-config/skills/database/redis-cache/SKILL.md +0 -343
- package/ai-config/skills/database/sqlite-embedded/SKILL.md +0 -388
- package/ai-config/skills/database/timescaledb/SKILL.md +0 -320
- package/ai-config/skills/docs/api-documentation/SKILL.md +0 -293
- package/ai-config/skills/docs/docs-spring/SKILL.md +0 -377
- package/ai-config/skills/docs/mustache-templates/SKILL.md +0 -190
- package/ai-config/skills/docs/technical-docs/SKILL.md +0 -447
- package/ai-config/skills/frontend/astro-ssr/SKILL.md +0 -441
- package/ai-config/skills/frontend/frontend-design/SKILL.md +0 -54
- package/ai-config/skills/frontend/frontend-web/SKILL.md +0 -368
- package/ai-config/skills/frontend/mantine-ui/SKILL.md +0 -396
- package/ai-config/skills/frontend/tanstack-query/SKILL.md +0 -439
- package/ai-config/skills/frontend/zod-validation/SKILL.md +0 -417
- package/ai-config/skills/frontend/zustand-state/SKILL.md +0 -350
- package/ai-config/skills/infrastructure/chaos-engineering/SKILL.md +0 -244
- package/ai-config/skills/infrastructure/chaos-spring/SKILL.md +0 -378
- package/ai-config/skills/infrastructure/devops-infra/SKILL.md +0 -435
- package/ai-config/skills/infrastructure/docker-containers/SKILL.md +0 -420
- package/ai-config/skills/infrastructure/kubernetes/SKILL.md +0 -456
- package/ai-config/skills/infrastructure/opentelemetry/SKILL.md +0 -546
- package/ai-config/skills/infrastructure/traefik-proxy/SKILL.md +0 -474
- package/ai-config/skills/infrastructure/woodpecker-ci/SKILL.md +0 -315
- package/ai-config/skills/mobile/ionic-capacitor/SKILL.md +0 -504
- package/ai-config/skills/mobile/mobile-ionic/SKILL.md +0 -448
- package/ai-config/skills/prompt-improver/SKILL.md +0 -125
- package/ai-config/skills/quality/ghagga-review/SKILL.md +0 -216
- package/ai-config/skills/references/hooks-patterns/SKILL.md +0 -238
- package/ai-config/skills/references/mcp-servers/SKILL.md +0 -275
- package/ai-config/skills/references/plugins-reference/SKILL.md +0 -110
- package/ai-config/skills/references/skills-reference/SKILL.md +0 -420
- package/ai-config/skills/references/subagent-templates/SKILL.md +0 -193
- package/ai-config/skills/systems-iot/modbus-protocol/SKILL.md +0 -410
- package/ai-config/skills/systems-iot/mqtt-rumqttc/SKILL.md +0 -408
- package/ai-config/skills/systems-iot/rust-systems/SKILL.md +0 -386
- package/ai-config/skills/systems-iot/tokio-async/SKILL.md +0 -324
- package/ai-config/skills/testing/playwright-e2e/SKILL.md +0 -289
- package/ai-config/skills/testing/testcontainers/SKILL.md +0 -299
- package/ai-config/skills/testing/vitest-testing/SKILL.md +0 -381
- package/ai-config/skills/workflow/ci-local-guide/SKILL.md +0 -118
- package/ai-config/skills/workflow/claude-automation-recommender/SKILL.md +0 -299
- package/ai-config/skills/workflow/claude-md-improver/SKILL.md +0 -158
- package/ai-config/skills/workflow/finishing-a-development-branch/SKILL.md +0 -117
- package/ai-config/skills/workflow/git-github/SKILL.md +0 -334
- package/ai-config/skills/workflow/git-github/references/examples.md +0 -160
- package/ai-config/skills/workflow/git-workflow/SKILL.md +0 -214
- package/ai-config/skills/workflow/ide-plugins/SKILL.md +0 -277
- package/ai-config/skills/workflow/ide-plugins-intellij/SKILL.md +0 -401
- package/ai-config/skills/workflow/obsidian-brain-workflow/SKILL.md +0 -199
- package/ai-config/skills/workflow/using-git-worktrees/SKILL.md +0 -100
- package/ai-config/skills/workflow/verification-before-completion/SKILL.md +0 -73
- package/ai-config/skills/workflow/wave-workflow/SKILL.md +0 -178
- package/schemas/agent.schema.json +0 -34
- package/schemas/ai-config.schema.json +0 -28
- package/schemas/plugin.schema.json +0 -62
- package/schemas/skill.schema.json +0 -44
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: powerbi
|
|
3
|
-
description: >
|
|
4
|
-
Power BI business intelligence with DAX measures, Power Query transformations, and dashboard design patterns.
|
|
5
|
-
Trigger: powerbi, dax, business intelligence, dashboard, analytics, reporting, power query
|
|
6
|
-
tools:
|
|
7
|
-
- Read
|
|
8
|
-
- Write
|
|
9
|
-
- Bash
|
|
10
|
-
metadata:
|
|
11
|
-
author: plataforma-industrial
|
|
12
|
-
version: "2.0"
|
|
13
|
-
tags: [powerbi, dax, analytics, dashboards]
|
|
14
|
-
updated: "2026-02"
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
# Power BI Business Intelligence
|
|
18
|
-
|
|
19
|
-
## Data Architecture
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
SOURCES DATAFLOW REPORTS
|
|
23
|
-
+---------------+ +---------------+ +---------------+
|
|
24
|
-
| PostgreSQL | | ETL | | Executive |
|
|
25
|
-
| API REST | ---> | Dimensional | ---> | Dashboard |
|
|
26
|
-
| Excel/CSV | | Model | | Analysis |
|
|
27
|
-
+---------------+ +---------------+ +---------------+
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Star Schema Model
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
DimSensor
|
|
34
|
-
|
|
|
35
|
-
DimPlant FactReadings DimDate
|
|
36
|
-
| | |
|
|
37
|
-
+------+-------+-------+------+
|
|
38
|
-
| |
|
|
39
|
-
FactAlerts DimTime
|
|
40
|
-
|
|
|
41
|
-
DimAlertType
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Power Query (M)
|
|
45
|
-
|
|
46
|
-
### PostgreSQL Connection
|
|
47
|
-
|
|
48
|
-
```m
|
|
49
|
-
// Query: Sensors
|
|
50
|
-
let
|
|
51
|
-
Source = PostgreSQL.Database("server", "database"),
|
|
52
|
-
sensors = Source{[Schema="public", Item="sensors"]}[Data],
|
|
53
|
-
|
|
54
|
-
// Filter and rename
|
|
55
|
-
FilteredRows = Table.SelectRows(sensors, each [status] = "active"),
|
|
56
|
-
RenamedColumns = Table.RenameColumns(FilteredRows, {
|
|
57
|
-
{"id", "SensorID"},
|
|
58
|
-
{"name", "SensorName"}
|
|
59
|
-
}),
|
|
60
|
-
|
|
61
|
-
// Add key
|
|
62
|
-
AddedKey = Table.AddIndexColumn(RenamedColumns, "SensorKey", 1, 1, Int64.Type)
|
|
63
|
-
in
|
|
64
|
-
AddedKey
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### REST API Connection
|
|
68
|
-
|
|
69
|
-
```m
|
|
70
|
-
// Query: Metrics
|
|
71
|
-
let
|
|
72
|
-
BaseUrl = "https://api.example.com/v1",
|
|
73
|
-
Token = GetSecret("API_TOKEN"),
|
|
74
|
-
|
|
75
|
-
GetPage = (page as number) as table =>
|
|
76
|
-
let
|
|
77
|
-
Response = Web.Contents(
|
|
78
|
-
BaseUrl & "/metrics",
|
|
79
|
-
[
|
|
80
|
-
Headers = [Authorization = "Bearer " & Token],
|
|
81
|
-
Query = [page = Text.From(page), limit = "1000"]
|
|
82
|
-
]
|
|
83
|
-
),
|
|
84
|
-
Json = Json.Document(Response),
|
|
85
|
-
AsTable = Table.FromRecords(Json[data])
|
|
86
|
-
in
|
|
87
|
-
AsTable,
|
|
88
|
-
|
|
89
|
-
// Paginate
|
|
90
|
-
AllPages = List.Generate(
|
|
91
|
-
() => [Page = 1, Data = GetPage(1)],
|
|
92
|
-
each Table.RowCount([Data]) > 0,
|
|
93
|
-
each [Page = [Page] + 1, Data = GetPage([Page] + 1)],
|
|
94
|
-
each [Data]
|
|
95
|
-
),
|
|
96
|
-
|
|
97
|
-
Combined = Table.Combine(AllPages)
|
|
98
|
-
in
|
|
99
|
-
Combined
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Date Dimension
|
|
103
|
-
|
|
104
|
-
```m
|
|
105
|
-
// Query: DimDate
|
|
106
|
-
let
|
|
107
|
-
StartDate = #date(2020, 1, 1),
|
|
108
|
-
EndDate = Date.AddYears(DateTime.Date(DateTime.LocalNow()), 1),
|
|
109
|
-
|
|
110
|
-
DateList = List.Dates(StartDate, Duration.Days(EndDate - StartDate), #duration(1,0,0,0)),
|
|
111
|
-
DateTable = Table.FromList(DateList, Splitter.SplitByNothing(), {"Date"}),
|
|
112
|
-
|
|
113
|
-
AddYear = Table.AddColumn(DateTable, "Year", each Date.Year([Date]), Int64.Type),
|
|
114
|
-
AddMonth = Table.AddColumn(AddYear, "Month", each Date.Month([Date]), Int64.Type),
|
|
115
|
-
AddMonthName = Table.AddColumn(AddMonth, "MonthName", each Date.MonthName([Date])),
|
|
116
|
-
AddWeek = Table.AddColumn(AddMonthName, "Week", each Date.WeekOfYear([Date]), Int64.Type),
|
|
117
|
-
AddIsWeekend = Table.AddColumn(AddWeek, "IsWeekend", each Date.DayOfWeek([Date]) >= 5),
|
|
118
|
-
|
|
119
|
-
AddKey = Table.AddColumn(AddIsWeekend, "DateKey",
|
|
120
|
-
each Date.Year([Date]) * 10000 + Date.Month([Date]) * 100 + Date.Day([Date]),
|
|
121
|
-
Int64.Type
|
|
122
|
-
)
|
|
123
|
-
in
|
|
124
|
-
AddKey
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Time Dimension
|
|
128
|
-
|
|
129
|
-
```m
|
|
130
|
-
// Query: DimTime
|
|
131
|
-
let
|
|
132
|
-
Minutes = List.Generate(() => 0, each _ < 1440, each _ + 1),
|
|
133
|
-
ToTable = Table.FromList(Minutes, Splitter.SplitByNothing(), {"MinuteOfDay"}),
|
|
134
|
-
|
|
135
|
-
AddHour = Table.AddColumn(ToTable, "Hour", each Number.IntegerDivide([MinuteOfDay], 60)),
|
|
136
|
-
AddMinute = Table.AddColumn(AddHour, "Minute", each Number.Mod([MinuteOfDay], 60)),
|
|
137
|
-
|
|
138
|
-
AddShift = Table.AddColumn(AddMinute, "Shift", each
|
|
139
|
-
if [Hour] >= 6 and [Hour] < 14 then "Morning"
|
|
140
|
-
else if [Hour] >= 14 and [Hour] < 22 then "Afternoon"
|
|
141
|
-
else "Night"
|
|
142
|
-
),
|
|
143
|
-
|
|
144
|
-
AddKey = Table.AddColumn(AddShift, "TimeKey", each [Hour] * 100 + [Minute], Int64.Type)
|
|
145
|
-
in
|
|
146
|
-
AddKey
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## DAX Measures
|
|
150
|
-
|
|
151
|
-
### Basic Metrics
|
|
152
|
-
|
|
153
|
-
```dax
|
|
154
|
-
// Average
|
|
155
|
-
Avg Reading = AVERAGE(FactReadings[Value])
|
|
156
|
-
|
|
157
|
-
// Current (latest)
|
|
158
|
-
Current Reading =
|
|
159
|
-
CALCULATE(
|
|
160
|
-
MAX(FactReadings[Value]),
|
|
161
|
-
FILTER(ALL(DimDate), DimDate[DateKey] = MAX(DimDate[DateKey]))
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
// Percentage change
|
|
165
|
-
Reading Change % =
|
|
166
|
-
VAR CurrentValue = [Avg Reading]
|
|
167
|
-
VAR PreviousValue = CALCULATE([Avg Reading], DATEADD(DimDate[Date], -1, DAY))
|
|
168
|
-
RETURN
|
|
169
|
-
IF(ISBLANK(PreviousValue), BLANK(),
|
|
170
|
-
DIVIDE(CurrentValue - PreviousValue, PreviousValue))
|
|
171
|
-
|
|
172
|
-
// In range percentage
|
|
173
|
-
In Range % =
|
|
174
|
-
VAR InRange = CALCULATE(COUNTROWS(FactReadings),
|
|
175
|
-
FactReadings[Value] >= RELATED(DimSensor[MinValue]),
|
|
176
|
-
FactReadings[Value] <= RELATED(DimSensor[MaxValue])
|
|
177
|
-
)
|
|
178
|
-
VAR Total = COUNTROWS(FactReadings)
|
|
179
|
-
RETURN DIVIDE(InRange, Total)
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Alert Metrics
|
|
183
|
-
|
|
184
|
-
```dax
|
|
185
|
-
// Active alerts
|
|
186
|
-
Active Alerts = CALCULATE(COUNTROWS(FactAlerts), FactAlerts[Status] = "active")
|
|
187
|
-
|
|
188
|
-
// Critical alerts
|
|
189
|
-
Critical Alerts = CALCULATE(COUNTROWS(FactAlerts),
|
|
190
|
-
RELATED(DimAlertType[Severity]) = "critical")
|
|
191
|
-
|
|
192
|
-
// MTTR (Mean Time To Resolve)
|
|
193
|
-
MTTR Hours = AVERAGEX(
|
|
194
|
-
FILTER(FactAlerts, FactAlerts[ResolvedAt] <> BLANK()),
|
|
195
|
-
DATEDIFF(FactAlerts[TriggeredAt], FactAlerts[ResolvedAt], HOUR)
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
// Acknowledgement rate
|
|
199
|
-
Ack Rate % =
|
|
200
|
-
VAR Acked = CALCULATE(COUNTROWS(FactAlerts), FactAlerts[AckedAt] <> BLANK())
|
|
201
|
-
VAR Total = COUNTROWS(FactAlerts)
|
|
202
|
-
RETURN DIVIDE(Acked, Total)
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Time Intelligence
|
|
206
|
-
|
|
207
|
-
```dax
|
|
208
|
-
// Year to Date
|
|
209
|
-
Production YTD = CALCULATE([Total Production], DATESYTD(DimDate[Date]))
|
|
210
|
-
|
|
211
|
-
// Month to Date
|
|
212
|
-
Production MTD = CALCULATE([Total Production], DATESMTD(DimDate[Date]))
|
|
213
|
-
|
|
214
|
-
// Same Period Last Year
|
|
215
|
-
Production SPLY = CALCULATE([Total Production], SAMEPERIODLASTYEAR(DimDate[Date]))
|
|
216
|
-
|
|
217
|
-
// Year over Year growth
|
|
218
|
-
YoY Growth % =
|
|
219
|
-
VAR Current = [Total Production]
|
|
220
|
-
VAR LastYear = [Production SPLY]
|
|
221
|
-
RETURN DIVIDE(Current - LastYear, LastYear)
|
|
222
|
-
|
|
223
|
-
// 7-day Moving Average
|
|
224
|
-
Production MA7 =
|
|
225
|
-
CALCULATE(
|
|
226
|
-
[Total Production],
|
|
227
|
-
DATESINPERIOD(DimDate[Date], MAX(DimDate[Date]), -7, DAY)
|
|
228
|
-
) / 7
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### Using Variables
|
|
232
|
-
|
|
233
|
-
```dax
|
|
234
|
-
// Good: Use variables
|
|
235
|
-
Margin % =
|
|
236
|
-
VAR Revenue = SUM(Sales[Amount])
|
|
237
|
-
VAR Cost = SUM(Sales[Cost])
|
|
238
|
-
RETURN DIVIDE(Revenue - Cost, Revenue)
|
|
239
|
-
|
|
240
|
-
// Bad: Calculates twice
|
|
241
|
-
Margin % = DIVIDE(
|
|
242
|
-
SUM(Sales[Amount]) - SUM(Sales[Cost]),
|
|
243
|
-
SUM(Sales[Amount])
|
|
244
|
-
)
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
## Dashboard Layout
|
|
248
|
-
|
|
249
|
-
### Executive Dashboard
|
|
250
|
-
|
|
251
|
-
```
|
|
252
|
-
+----------------------------------------------------------+
|
|
253
|
-
| EXECUTIVE DASHBOARD |
|
|
254
|
-
+----------+----------+----------+----------+---------------+
|
|
255
|
-
| KPI 1 | KPI 2 | KPI 3 | KPI 4 | Trend |
|
|
256
|
-
| Card | Card | Card | Card | Indicator |
|
|
257
|
-
+----------+----------+----------+----------+---------------+
|
|
258
|
-
| |
|
|
259
|
-
| MAIN CHART (Time Series) |
|
|
260
|
-
| |
|
|
261
|
-
+--------------------------+--------------------------------+
|
|
262
|
-
| | |
|
|
263
|
-
| BREAKDOWN | TOP 5 TABLE |
|
|
264
|
-
| (Bar Chart) | (Conditional Formatting) |
|
|
265
|
-
| | |
|
|
266
|
-
+--------------------------+--------------------------------+
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
## Visualizations Guide
|
|
270
|
-
|
|
271
|
-
| Metric Type | Visual | Configuration |
|
|
272
|
-
|-------------|--------|---------------|
|
|
273
|
-
| Single KPI | Card | Value + Trend + Indicator |
|
|
274
|
-
| Progress | Gauge | Color thresholds |
|
|
275
|
-
| Time comparison | Line Chart | With area for ranges |
|
|
276
|
-
| Distribution | Donut Chart | Max 5 categories |
|
|
277
|
-
| Ranking | Bar Chart | Horizontal, sorted |
|
|
278
|
-
| Correlation | Scatter Plot | With trendline |
|
|
279
|
-
| Location | Map | Bubbles by size |
|
|
280
|
-
| Detail | Table/Matrix | Conditional formatting |
|
|
281
|
-
|
|
282
|
-
## Color Standards
|
|
283
|
-
|
|
284
|
-
```
|
|
285
|
-
// Status colors
|
|
286
|
-
Green (OK): #2DD36F
|
|
287
|
-
Yellow (Warn): #FFC409
|
|
288
|
-
Red (Error): #EB445A
|
|
289
|
-
Gray (Offline): #92949C
|
|
290
|
-
|
|
291
|
-
// Trend colors
|
|
292
|
-
Positive: #2DD36F
|
|
293
|
-
Negative: #EB445A
|
|
294
|
-
Neutral: #3DC2FF
|
|
295
|
-
|
|
296
|
-
// Brand
|
|
297
|
-
Primary: #0969FF
|
|
298
|
-
Secondary: #3DC2FF
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
## Row-Level Security
|
|
302
|
-
|
|
303
|
-
### By Tenant
|
|
304
|
-
|
|
305
|
-
```dax
|
|
306
|
-
// Role: TenantAccess
|
|
307
|
-
// Table: DimPlant
|
|
308
|
-
[TenantID] = USERPRINCIPALNAME()
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
### By Plant
|
|
312
|
-
|
|
313
|
-
```dax
|
|
314
|
-
// Role: PlantManager
|
|
315
|
-
// Table: DimPlant
|
|
316
|
-
[PlantID] IN
|
|
317
|
-
SELECTCOLUMNS(
|
|
318
|
-
FILTER(UserPlantAccess,
|
|
319
|
-
UserPlantAccess[UserEmail] = USERPRINCIPALNAME()),
|
|
320
|
-
"PlantID", UserPlantAccess[PlantID]
|
|
321
|
-
)
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
## Refresh Configuration
|
|
325
|
-
|
|
326
|
-
```yaml
|
|
327
|
-
Type: Incremental Refresh
|
|
328
|
-
|
|
329
|
-
Policy:
|
|
330
|
-
- Last 7 days: Full refresh every 1 hour
|
|
331
|
-
- Last 30 days: Daily refresh at 6:00 AM
|
|
332
|
-
- Historical (>30 days): Initial load only
|
|
333
|
-
|
|
334
|
-
Dataflow:
|
|
335
|
-
- Refresh: Every 4 hours
|
|
336
|
-
- Timeout: 2 hours
|
|
337
|
-
- Retry: 3 attempts
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
## Best Practices
|
|
341
|
-
|
|
342
|
-
1. **Star Schema** - Dimensional model with fact and dimension tables
|
|
343
|
-
2. **Measures over Calculated Columns** - For aggregations, use measures
|
|
344
|
-
3. **Avoid unnecessary CALCULATE** - Simple aggregations don't need it
|
|
345
|
-
4. **Use Variables** - More readable and efficient
|
|
346
|
-
5. **Incremental Refresh** - For large datasets
|
|
347
|
-
|
|
348
|
-
## Related Skills
|
|
349
|
-
|
|
350
|
-
- `duckdb-analytics`: Data preprocessing
|
|
351
|
-
- `timescaledb`: Time-series data source
|
|
352
|
-
- `technical-docs`: Report documentation
|
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pytorch
|
|
3
|
-
description: >
|
|
4
|
-
Deep learning with PyTorch and Lightning for anomaly detection and time series forecasting.
|
|
5
|
-
Trigger: pytorch, deep learning, neural network, lightning, anomaly detection, forecasting
|
|
6
|
-
tools:
|
|
7
|
-
- Read
|
|
8
|
-
- Write
|
|
9
|
-
- Bash
|
|
10
|
-
- Grep
|
|
11
|
-
metadata:
|
|
12
|
-
author: plataforma-industrial
|
|
13
|
-
version: "2.0"
|
|
14
|
-
tags: [pytorch, deep-learning, lightning, ml, forecasting]
|
|
15
|
-
updated: "2026-02"
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
# PyTorch Skill
|
|
19
|
-
|
|
20
|
-
Deep learning with PyTorch Lightning for anomaly detection and time series forecasting.
|
|
21
|
-
|
|
22
|
-
## Stack
|
|
23
|
-
|
|
24
|
-
```yaml
|
|
25
|
-
torch: 2.2+
|
|
26
|
-
lightning: 2.2+
|
|
27
|
-
torchmetrics: 1.3+
|
|
28
|
-
einops: 0.7+
|
|
29
|
-
wandb: 0.16+ # logging
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Project Structure
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
src/ml/
|
|
36
|
-
├── models/
|
|
37
|
-
│ ├── autoencoder.py
|
|
38
|
-
│ ├── transformer.py
|
|
39
|
-
│ └── lstm.py
|
|
40
|
-
├── data/
|
|
41
|
-
│ ├── dataset.py
|
|
42
|
-
│ └── preprocessing.py
|
|
43
|
-
├── training/
|
|
44
|
-
│ └── trainer.py
|
|
45
|
-
└── inference/
|
|
46
|
-
└── predictor.py
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Autoencoder for Anomaly Detection
|
|
50
|
-
|
|
51
|
-
```python
|
|
52
|
-
import torch
|
|
53
|
-
import torch.nn as nn
|
|
54
|
-
import lightning as L
|
|
55
|
-
from torchmetrics import F1Score, Precision, Recall
|
|
56
|
-
|
|
57
|
-
class SensorAutoencoder(nn.Module):
|
|
58
|
-
def __init__(self, input_dim: int = 5, hidden_dims: list = [64, 32, 16], latent_dim: int = 8):
|
|
59
|
-
super().__init__()
|
|
60
|
-
# Encoder
|
|
61
|
-
encoder_layers = []
|
|
62
|
-
prev_dim = input_dim
|
|
63
|
-
for dim in hidden_dims:
|
|
64
|
-
encoder_layers.extend([
|
|
65
|
-
nn.Linear(prev_dim, dim), nn.BatchNorm1d(dim), nn.ReLU(), nn.Dropout(0.1)
|
|
66
|
-
])
|
|
67
|
-
prev_dim = dim
|
|
68
|
-
encoder_layers.append(nn.Linear(prev_dim, latent_dim))
|
|
69
|
-
self.encoder = nn.Sequential(*encoder_layers)
|
|
70
|
-
|
|
71
|
-
# Decoder (mirror)
|
|
72
|
-
decoder_layers = []
|
|
73
|
-
prev_dim = latent_dim
|
|
74
|
-
for dim in reversed(hidden_dims):
|
|
75
|
-
decoder_layers.extend([
|
|
76
|
-
nn.Linear(prev_dim, dim), nn.BatchNorm1d(dim), nn.ReLU(), nn.Dropout(0.1)
|
|
77
|
-
])
|
|
78
|
-
prev_dim = dim
|
|
79
|
-
decoder_layers.append(nn.Linear(prev_dim, input_dim))
|
|
80
|
-
self.decoder = nn.Sequential(*decoder_layers)
|
|
81
|
-
|
|
82
|
-
def forward(self, x):
|
|
83
|
-
z = self.encoder(x)
|
|
84
|
-
return self.decoder(z), z
|
|
85
|
-
|
|
86
|
-
class AnomalyDetectorModule(L.LightningModule):
|
|
87
|
-
def __init__(self, input_dim: int = 5, learning_rate: float = 1e-3, threshold_percentile: float = 95):
|
|
88
|
-
super().__init__()
|
|
89
|
-
self.save_hyperparameters()
|
|
90
|
-
self.model = SensorAutoencoder(input_dim=input_dim)
|
|
91
|
-
self.threshold = None
|
|
92
|
-
self.f1 = F1Score(task="binary")
|
|
93
|
-
|
|
94
|
-
def forward(self, x):
|
|
95
|
-
return self.model(x)
|
|
96
|
-
|
|
97
|
-
def training_step(self, batch, batch_idx):
|
|
98
|
-
x, _ = batch
|
|
99
|
-
x_recon, _ = self(x)
|
|
100
|
-
loss = nn.functional.mse_loss(x_recon, x)
|
|
101
|
-
self.log("train_loss", loss, prog_bar=True)
|
|
102
|
-
return loss
|
|
103
|
-
|
|
104
|
-
def validation_step(self, batch, batch_idx):
|
|
105
|
-
x, labels = batch
|
|
106
|
-
x_recon, _ = self(x)
|
|
107
|
-
loss = nn.functional.mse_loss(x_recon, x)
|
|
108
|
-
recon_error = torch.mean((x - x_recon) ** 2, dim=1)
|
|
109
|
-
self.log("val_loss", loss, prog_bar=True)
|
|
110
|
-
return {"recon_error": recon_error, "labels": labels}
|
|
111
|
-
|
|
112
|
-
def configure_optimizers(self):
|
|
113
|
-
optimizer = torch.optim.AdamW(self.parameters(), lr=self.hparams.learning_rate, weight_decay=1e-5)
|
|
114
|
-
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100, eta_min=1e-6)
|
|
115
|
-
return {"optimizer": optimizer, "lr_scheduler": {"scheduler": scheduler, "monitor": "val_loss"}}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Time Series Transformer
|
|
119
|
-
|
|
120
|
-
```python
|
|
121
|
-
import torch.nn as nn
|
|
122
|
-
import math
|
|
123
|
-
from einops import rearrange
|
|
124
|
-
|
|
125
|
-
class PositionalEncoding(nn.Module):
|
|
126
|
-
def __init__(self, d_model: int, max_len: int = 5000):
|
|
127
|
-
super().__init__()
|
|
128
|
-
position = torch.arange(max_len).unsqueeze(1)
|
|
129
|
-
div_term = torch.exp(torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model))
|
|
130
|
-
pe = torch.zeros(max_len, 1, d_model)
|
|
131
|
-
pe[:, 0, 0::2] = torch.sin(position * div_term)
|
|
132
|
-
pe[:, 0, 1::2] = torch.cos(position * div_term)
|
|
133
|
-
self.register_buffer('pe', pe)
|
|
134
|
-
|
|
135
|
-
def forward(self, x):
|
|
136
|
-
return x + self.pe[:x.size(0)]
|
|
137
|
-
|
|
138
|
-
class SensorTransformer(nn.Module):
|
|
139
|
-
def __init__(self, input_dim: int = 5, d_model: int = 64, nhead: int = 4,
|
|
140
|
-
num_layers: int = 3, prediction_horizon: int = 12):
|
|
141
|
-
super().__init__()
|
|
142
|
-
self.prediction_horizon = prediction_horizon
|
|
143
|
-
self.input_projection = nn.Linear(input_dim, d_model)
|
|
144
|
-
self.pos_encoder = PositionalEncoding(d_model)
|
|
145
|
-
encoder_layer = nn.TransformerEncoderLayer(d_model=d_model, nhead=nhead,
|
|
146
|
-
dim_feedforward=256, dropout=0.1, batch_first=False)
|
|
147
|
-
self.transformer_encoder = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
|
|
148
|
-
self.output_projection = nn.Linear(d_model, input_dim * prediction_horizon)
|
|
149
|
-
|
|
150
|
-
def forward(self, src):
|
|
151
|
-
src = rearrange(src, 'b s d -> s b d')
|
|
152
|
-
src = self.pos_encoder(self.input_projection(src))
|
|
153
|
-
output = self.transformer_encoder(src)
|
|
154
|
-
predictions = self.output_projection(output[-1])
|
|
155
|
-
return rearrange(predictions, 'b (h d) -> b h d', h=self.prediction_horizon)
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## Dataset & DataModule
|
|
159
|
-
|
|
160
|
-
```python
|
|
161
|
-
from torch.utils.data import Dataset, DataLoader
|
|
162
|
-
import numpy as np
|
|
163
|
-
|
|
164
|
-
class SensorDataset(Dataset):
|
|
165
|
-
def __init__(self, data: np.ndarray, labels: np.ndarray = None,
|
|
166
|
-
sequence_length: int = 100, prediction_horizon: int = 12, normalize: bool = True):
|
|
167
|
-
self.sequence_length = sequence_length
|
|
168
|
-
self.prediction_horizon = prediction_horizon
|
|
169
|
-
self.labels = labels
|
|
170
|
-
|
|
171
|
-
if normalize:
|
|
172
|
-
self.mean, self.std = np.mean(data, axis=0), np.std(data, axis=0) + 1e-8
|
|
173
|
-
self.data = (data - self.mean) / self.std
|
|
174
|
-
else:
|
|
175
|
-
self.data = data
|
|
176
|
-
|
|
177
|
-
def __len__(self):
|
|
178
|
-
return len(self.data) - self.sequence_length - self.prediction_horizon + 1
|
|
179
|
-
|
|
180
|
-
def __getitem__(self, idx):
|
|
181
|
-
x = torch.tensor(self.data[idx:idx + self.sequence_length], dtype=torch.float32)
|
|
182
|
-
y = torch.tensor(self.data[idx + self.sequence_length:idx + self.sequence_length + self.prediction_horizon], dtype=torch.float32)
|
|
183
|
-
if self.labels is not None:
|
|
184
|
-
return x, torch.tensor(self.labels[idx + self.sequence_length - 1], dtype=torch.long)
|
|
185
|
-
return x, y
|
|
186
|
-
|
|
187
|
-
class SensorDataModule(L.LightningDataModule):
|
|
188
|
-
def __init__(self, data_path: str, batch_size: int = 32, num_workers: int = 4):
|
|
189
|
-
super().__init__()
|
|
190
|
-
self.data_path = data_path
|
|
191
|
-
self.batch_size = batch_size
|
|
192
|
-
self.num_workers = num_workers
|
|
193
|
-
|
|
194
|
-
def setup(self, stage=None):
|
|
195
|
-
data = np.load(self.data_path)
|
|
196
|
-
readings, labels = data['readings'], data.get('labels', None)
|
|
197
|
-
n = len(readings)
|
|
198
|
-
train_end, val_end = int(n * 0.7), int(n * 0.85)
|
|
199
|
-
|
|
200
|
-
self.train_dataset = SensorDataset(readings[:train_end], labels[:train_end] if labels else None)
|
|
201
|
-
self.val_dataset = SensorDataset(readings[train_end:val_end], labels[train_end:val_end] if labels else None)
|
|
202
|
-
self.test_dataset = SensorDataset(readings[val_end:], labels[val_end:] if labels else None)
|
|
203
|
-
|
|
204
|
-
def train_dataloader(self):
|
|
205
|
-
return DataLoader(self.train_dataset, batch_size=self.batch_size, shuffle=True, num_workers=self.num_workers, pin_memory=True)
|
|
206
|
-
|
|
207
|
-
def val_dataloader(self):
|
|
208
|
-
return DataLoader(self.val_dataset, batch_size=self.batch_size, num_workers=self.num_workers, pin_memory=True)
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
## Training Script
|
|
212
|
-
|
|
213
|
-
```python
|
|
214
|
-
import lightning as L
|
|
215
|
-
from lightning.pytorch.callbacks import ModelCheckpoint, EarlyStopping, LearningRateMonitor
|
|
216
|
-
from lightning.pytorch.loggers import WandbLogger
|
|
217
|
-
|
|
218
|
-
def train(data_path: str, max_epochs: int = 100):
|
|
219
|
-
datamodule = SensorDataModule(data_path=data_path, batch_size=32)
|
|
220
|
-
model = AnomalyDetectorModule(input_dim=5, learning_rate=1e-3)
|
|
221
|
-
|
|
222
|
-
callbacks = [
|
|
223
|
-
ModelCheckpoint(dirpath="checkpoints", filename="{epoch:02d}-{val_loss:.4f}",
|
|
224
|
-
monitor="val_loss", mode="min", save_top_k=3),
|
|
225
|
-
EarlyStopping(monitor="val_loss", patience=10, mode="min"),
|
|
226
|
-
LearningRateMonitor(logging_interval="epoch"),
|
|
227
|
-
]
|
|
228
|
-
|
|
229
|
-
trainer = L.Trainer(
|
|
230
|
-
max_epochs=max_epochs,
|
|
231
|
-
accelerator="auto",
|
|
232
|
-
callbacks=callbacks,
|
|
233
|
-
logger=WandbLogger(project="ml-training"),
|
|
234
|
-
precision="16-mixed",
|
|
235
|
-
gradient_clip_val=1.0,
|
|
236
|
-
)
|
|
237
|
-
|
|
238
|
-
trainer.fit(model, datamodule)
|
|
239
|
-
trainer.test(model, datamodule)
|
|
240
|
-
return model
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
## Inference
|
|
244
|
-
|
|
245
|
-
```python
|
|
246
|
-
class Predictor:
|
|
247
|
-
def __init__(self, model_path: str, threshold: float, device: str = "cuda"):
|
|
248
|
-
self.device = torch.device(device if torch.cuda.is_available() else "cpu")
|
|
249
|
-
self.model = AnomalyDetectorModule.load_from_checkpoint(model_path)
|
|
250
|
-
self.model.to(self.device).eval()
|
|
251
|
-
self.threshold = threshold
|
|
252
|
-
|
|
253
|
-
@torch.no_grad()
|
|
254
|
-
def predict(self, readings: np.ndarray):
|
|
255
|
-
x = torch.tensor(readings, dtype=torch.float32).unsqueeze(0).to(self.device)
|
|
256
|
-
x_recon, _ = self.model(x)
|
|
257
|
-
error = torch.mean((x - x_recon) ** 2, dim=-1).squeeze().cpu().numpy()
|
|
258
|
-
return error, error > self.threshold
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
## Best Practices
|
|
262
|
-
|
|
263
|
-
1. **Mixed precision** - `precision="16-mixed"` for faster training
|
|
264
|
-
2. **Gradient clipping** - Prevent exploding gradients with `gradient_clip_val=1.0`
|
|
265
|
-
3. **LR scheduling** - CosineAnnealingLR or ReduceLROnPlateau
|
|
266
|
-
4. **Save normalization params** - Include mean/std in checkpoint
|
|
267
|
-
5. **torch.compile** - Use for inference: `model = torch.compile(model, mode="reduce-overhead")`
|
|
268
|
-
|
|
269
|
-
## Related Skills
|
|
270
|
-
|
|
271
|
-
- `onnx-inference`: Model export and deployment
|
|
272
|
-
- `mlflow`: Experiment tracking
|
|
273
|
-
- `scikit-learn`: Classical ML comparison
|
|
274
|
-
- `ai-ml`: Full training pipelines
|