forked from zhaozhixu/TensorLight
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeep_network_diagnostic.c
More file actions
132 lines (107 loc) · 4.26 KB
/
Copy pathdeep_network_diagnostic.c
File metadata and controls
132 lines (107 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Diagnostic test for very deep networks
* Tracks layer-by-layer statistics to identify issues
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "tofu_tensor.h"
void relu(tofu_tensor* t) {
for (int i = 0; i < t->len; i++) {
float val;
TOFU_TENSOR_DATA_TO(t, i, val, TOFU_FLOAT);
if (val < 0) val = 0;
TOFU_TENSOR_DATA_FROM(t, i, val, TOFU_FLOAT);
}
}
void compute_stats(tofu_tensor* t, float* min, float* max, float* mean, int* zero_count) {
*min = INFINITY;
*max = -INFINITY;
float sum = 0;
*zero_count = 0;
for (int i = 0; i < t->len; i++) {
float val;
TOFU_TENSOR_DATA_TO(t, i, val, TOFU_FLOAT);
sum += val;
if (val < *min) *min = val;
if (val > *max) *max = val;
if (val == 0.0f) (*zero_count)++;
}
*mean = sum / t->len;
}
void init_random(tofu_tensor* t, float scale) {
for (int i = 0; i < t->len; i++) {
float val = ((float)rand() / RAND_MAX - 0.5f) * scale;
TOFU_TENSOR_DATA_FROM(t, i, val, TOFU_FLOAT);
}
}
int main() {
printf("============================================================\n");
printf("Deep Network Diagnostic\n");
printf("============================================================\n\n");
srand(42);
const int DEPTH = 10;
const int LAYER_SIZE = 64;
printf("Network: 10 layers, %d neurons each\n\n", LAYER_SIZE);
/* Initialize */
tofu_tensor* layers[DEPTH + 1];
tofu_tensor* weights[DEPTH];
layers[0] = tofu_tensor_zeros(2, (int[]){1, LAYER_SIZE}, TOFU_FLOAT);
init_random(layers[0], 1.0f);
for (int i = 0; i < DEPTH; i++) {
weights[i] = tofu_tensor_zeros(2, (int[]){LAYER_SIZE, LAYER_SIZE}, TOFU_FLOAT);
init_random(weights[i], 0.1f);
}
/* Track statistics through layers */
printf("Layer-by-layer statistics:\n");
printf("%-8s %-12s %-12s %-12s %-12s\n", "Layer", "Min", "Max", "Mean", "Zeros");
printf("----------------------------------------------------------------\n");
float min, max, mean;
int zero_count;
compute_stats(layers[0], &min, &max, &mean, &zero_count);
printf("%-8s %-12.6f %-12.6f %-12.6f %-12d\n", "Input", min, max, mean, zero_count);
for (int i = 0; i < DEPTH; i++) {
/* Before activation */
layers[i + 1] = tofu_tensor_matmul(layers[i], weights[i], NULL);
if (!layers[i + 1]) {
fprintf(stderr, "Layer %d matmul failed\n", i);
return 1;
}
compute_stats(layers[i + 1], &min, &max, &mean, &zero_count);
printf("L%-7d %-12.6f %-12.6f %-12.6f %-12d (before ReLU)\n",
i + 1, min, max, mean, zero_count);
/* After activation */
relu(layers[i + 1]);
compute_stats(layers[i + 1], &min, &max, &mean, &zero_count);
printf("L%-7d %-12.6f %-12.6f %-12.6f %-12d (after ReLU)\n",
i + 1, min, max, mean, zero_count);
}
printf("\n================================================================\n");
printf("Analysis:\n");
compute_stats(layers[DEPTH], &min, &max, &mean, &zero_count);
float zero_percent = (float)zero_count / layers[DEPTH]->len * 100.0f;
printf("Final layer: %.1f%% zeros (%d / %d elements)\n",
zero_percent, zero_count, layers[DEPTH]->len);
if (zero_percent > 99.0f) {
printf("\n⚠️ WARNING: Dying ReLU detected!\n");
printf(" - Most values became negative and were zeroed by ReLU\n");
printf(" - This is common in very deep networks without:\n");
printf(" • Batch normalization\n");
printf(" • Residual connections (skip connections)\n");
printf(" • Better weight initialization (Xavier/He)\n");
printf(" • Alternative activations (LeakyReLU, ELU)\n");
} else if (zero_percent > 50.0f) {
printf("\n⚠️ CAUTION: High sparsity detected (%.1f%% zeros)\n", zero_percent);
} else {
printf("\n✓ Network appears healthy\n");
}
/* Cleanup */
for (int i = 0; i <= DEPTH; i++) {
tofu_tensor_free_data_too(layers[i]);
}
for (int i = 0; i < DEPTH; i++) {
tofu_tensor_free_data_too(weights[i]);
}
printf("================================================================\n");
return 0;
}