079project 3.0.0 → 4.0.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/forwarder.js CHANGED
@@ -285,6 +285,43 @@ app.get('/', (req, res) => {
285
285
  <button type="submit" class="btn btn-primary">应用参数</button>
286
286
  <button type="button" id="resetParams" class="btn btn-secondary">重置默认值</button>
287
287
  </div>
288
+ <hr class="my-4"/>
289
+ <h6 class="mb-3">激活与传递函数</h6>
290
+ <div class="row g-3">
291
+ <div class="col-md-6">
292
+ <label for="activationType" class="form-label">Activation Function</label>
293
+ <select id="activationType" class="form-select">
294
+ <option value="identity">identity</option>
295
+ <option value="relu" selected>relu</option>
296
+ <option value="leaky_relu">leaky_relu</option>
297
+ <option value="tanh">tanh</option>
298
+ <option value="sigmoid">sigmoid</option>
299
+ <option value="elu">elu</option>
300
+ <option value="softplus">softplus</option>
301
+ <option value="gelu">gelu</option>
302
+ <option value="custom">custom</option>
303
+ </select>
304
+ <small class="text-muted">Node 侧将对节点聚合与扩散值应用该激活</small>
305
+ <textarea id="activationCustom" class="form-control mt-2" rows="3" style="display:none;" placeholder="Custom activation JS. Example: return x > 0 ? x : 0;"></textarea>
306
+ </div>
307
+ <div class="col-md-6">
308
+ <label for="transferType" class="form-label">Transfer Function</label>
309
+ <select id="transferType" class="form-select">
310
+ <option value="linear" selected>linear</option>
311
+ <option value="exp">exp</option>
312
+ <option value="inverse">inverse</option>
313
+ <option value="capped">capped</option>
314
+ <option value="custom">custom</option>
315
+ </select>
316
+ <small class="text-muted">传递函数决定沿边传播的信号衰减方式</small>
317
+ <textarea id="transferCustom" class="form-control mt-2" rows="3" style="display:none;" placeholder="Custom transfer JS. Args: value, weight, decayK, ctx. Example: return value * Math.exp(-(decayK*weight));"></textarea>
318
+ </div>
319
+ </div>
320
+
321
+ <div class="d-flex justify-content-between mt-4">
322
+ <button type="submit" class="btn btn-primary">应用参数</button>
323
+ <button type="button" id="resetParams" class="btn btn-secondary">重置默认值</button>
324
+ </div>
288
325
 
289
326
  </form>
290
327
  </div>
@@ -534,6 +571,7 @@ app.get('/', (req, res) => {
534
571
  document.getElementById('confirmDeleteSnapshot').addEventListener('click', function() {
535
572
  deleteSnapshot();
536
573
  });
574
+ bindActivationEditors(); // 新增:绑定选择器与自定义编辑显隐
537
575
  });
538
576
 
539
577
  // 发送消息
@@ -595,6 +633,8 @@ app.get('/', (req, res) => {
595
633
  }
596
634
 
597
635
  // 加载模型参数
636
+
637
+ // 加载模型参数(保持接口不变)
598
638
  function loadModelParams() {
599
639
  fetch('/api/model/params')
600
640
  .then(response => response.json())
@@ -672,6 +712,13 @@ function updateParamSliders(params) {
672
712
  document.getElementById('waitingTimeRange').value = params.waitingTime;
673
713
  document.getElementById('waitingTimeValue').textContent = params.waitingTime;
674
714
  }
715
+ if (params.activationType) document.getElementById('activationType').value = params.activationType;
716
+ if (params.transferType) document.getElementById('transferType').value = params.transferType;
717
+ if (typeof params.activationCustom === 'string') document.getElementById('activationCustom').value = params.activationCustom;
718
+ if (typeof params.transferCustom === 'string') document.getElementById('transferCustom').value = params.transferCustom;
719
+
720
+ // 触发一次显隐同步
721
+ if (typeof bindActivationEditors === 'function') bindActivationEditors();
675
722
  } // 添加这个花括号
676
723
 
677
724
  function bindSliderEvents() {
@@ -705,43 +752,47 @@ function bindSliderEvents() {
705
752
  });
706
753
  }
707
754
  // 更新模型参数
708
- function updateModelParams() {
709
- const params = {
710
- decayFactor: parseFloat(document.getElementById('decayFactorRange').value),
711
- maxMemeWords: parseInt(document.getElementById('maxMemeWordsRange').value),
712
- minOverlapThreshold: parseInt(document.getElementById('minOverlapThresholdRange').value),
713
- maliciousThreshold: parseFloat(document.getElementById('maliciousThresholdRange').value),
714
- learningIterations: parseInt(document.getElementById('learningIterationsRange').value),
715
- iteration: parseInt(document.getElementById('iterationRange').value),
716
- threshold: parseInt(document.getElementById('thresholdRange').value),
717
- decay: parseFloat(document.getElementById('decayRange').value),
718
- decayK: parseFloat(document.getElementById('decayKRange').value),
719
- maxLen: parseInt(document.getElementById('maxLenRange').value),
720
- edgeWeight: parseFloat(document.getElementById('edgeWeightRange').value),
721
- communicateCount: parseInt(document.getElementById('communicateCountRange').value),
722
- waitingTime: parseInt(document.getElementById('waitingTime').value) // 添加这个参数
723
- };
724
-
725
- fetch('/api/model/params', {
726
- method: 'POST',
727
- headers: {
728
- 'Content-Type': 'application/json',
729
- },
730
- body: JSON.stringify(params),
731
- })
732
- .then(response => response.json())
733
- .then(data => {
734
- if (data.success) {
735
- alert('参数更新成功!');
736
- } else {
737
- alert('参数更新失败: ' + (data.error || '未知错误'));
755
+ // 更新模型参数:增加激活/传递函数字段
756
+ function updateModelParams() {
757
+ const params = {
758
+ decayFactor: parseFloat(document.getElementById('decayFactorRange').value),
759
+ maxMemeWords: parseInt(document.getElementById('maxMemeWordsRange').value),
760
+ minOverlapThreshold: parseInt(document.getElementById('minOverlapThresholdRange').value),
761
+ maliciousThreshold: parseFloat(document.getElementById('maliciousThresholdRange').value),
762
+ learningIterations: parseInt(document.getElementById('learningIterationsRange').value),
763
+ iteration: parseInt(document.getElementById('iterationRange').value),
764
+ threshold: parseInt(document.getElementById('thresholdRange').value),
765
+ decay: parseFloat(document.getElementById('decayRange').value),
766
+ decayK: parseFloat(document.getElementById('decayKRange').value),
767
+ maxLen: parseInt(document.getElementById('maxLenRange').value),
768
+ edgeWeight: parseFloat(document.getElementById('edgeWeightRange').value),
769
+ communicateCount: parseInt(document.getElementById('communicateCountRange').value),
770
+ waitingTime: parseInt(document.getElementById('waitingTime').value),
771
+ // 新增
772
+ activationType: document.getElementById('activationType').value,
773
+ transferType: document.getElementById('transferType').value,
774
+ activationCustom: document.getElementById('activationCustom').value,
775
+ transferCustom: document.getElementById('transferCustom').value
776
+ };
777
+
778
+ fetch('/api/model/params', {
779
+ method: 'POST',
780
+ headers: { 'Content-Type': 'application/json' },
781
+ body: JSON.stringify(params),
782
+ })
783
+ .then(response => response.json())
784
+ .then(data => {
785
+ if (data.success) {
786
+ alert('参数更新成功!');
787
+ } else {
788
+ alert('参数更新失败: ' + (data.error || '未知错误'));
789
+ }
790
+ })
791
+ .catch(error => {
792
+ console.error('Error updating parameters:', error);
793
+ alert('更新参数时发生错误: ' + error.message);
794
+ });
738
795
  }
739
- })
740
- .catch(error => {
741
- console.error('Error updating parameters:', error);
742
- alert('更新参数时发生错误: ' + error.message);
743
- });
744
- }
745
796
 
746
797
  // 重置模型参数
747
798
  function resetModelParams() {
@@ -776,6 +827,19 @@ function updateModelParams() {
776
827
  .catch(error => console.error('Error loading system status:', error));
777
828
  }
778
829
 
830
+ function bindActivationEditors() {
831
+ const actSel = document.getElementById('activationType');
832
+ const actTxt = document.getElementById('activationCustom');
833
+ const trSel = document.getElementById('transferType');
834
+ const trTxt = document.getElementById('transferCustom');
835
+ const sync = () => {
836
+ actTxt.style.display = (actSel.value === 'custom') ? '' : 'none';
837
+ trTxt.style.display = (trSel.value === 'custom') ? '' : 'none';
838
+ };
839
+ actSel.addEventListener('change', sync);
840
+ trSel.addEventListener('change', sync);
841
+ sync();
842
+ }
779
843
  function updateParamSliders(params) {
780
844
  // 定义一个更新滑块的辅助函数
781
845
  function updateSlider(paramName, sliderId, valueId) {
@@ -1080,7 +1144,12 @@ const modelDefaults = {
1080
1144
  minOverlapThreshold: 2,
1081
1145
  maliciousThreshold: 0.7,
1082
1146
  learningIterations: 3,
1083
- communicateCount: 1 // 新增
1147
+ communicateCount: 1,
1148
+ // 新增:激活与传递函数选择
1149
+ activationType: 'relu',
1150
+ transferType: 'linear',
1151
+ activationCustom: '',
1152
+ transferCustom: ''
1084
1153
  };
1085
1154
 
1086
1155
  // 当前应用的模型参数
package/main_Serve.cjs CHANGED
@@ -55,6 +55,71 @@ global.config = {
55
55
  peerServePorts: String(__args['peers'] || '').split(',').map(s => Number(s)).filter(n => Number.isFinite(n) && n > 0),
56
56
  isStudy: !!__args['study']
57
57
  };
58
+ // ...existing code...
59
+ const vm = require('vm'); // 新增:沙箱编译
60
+ // ...existing code...
61
+
62
+ // ==== 内置激活/传递函数注册表 + 安全编译工具 ====
63
+ const BuiltinActivations = {
64
+ identity: (x) => x,
65
+ relu: (x) => (x > 0 ? x : 0),
66
+ leaky_relu: (x) => (x > 0 ? x : 0.01 * x),
67
+ tanh: (x) => Math.tanh(x),
68
+ sigmoid: (x) => 1 / (1 + Math.exp(-x)),
69
+ elu: (x) => (x >= 0 ? x : (Math.exp(x) - 1)),
70
+ softplus: (x) => Math.log(1 + Math.exp(x)),
71
+ // 近似 GELU
72
+ gelu: (x) => 0.5 * x * (1 + Math.tanh(Math.sqrt(2 / Math.PI) * (x + 0.044715 * Math.pow(x, 3))))
73
+ };
74
+
75
+ const BuiltinTransfers = {
76
+ // 线性衰减:next = value - decayK*weight*(dirMult)
77
+ linear: (value, weight, decayK, ctx) => {
78
+ const dm = ctx?.direction === 0 ? (ctx?.bidirectionalMultiplier ?? 1.2) : (ctx?.directionalMultiplier ?? 0.7);
79
+ return value - (decayK * weight * dm);
80
+ },
81
+ // 指数衰减:next = value * exp(-decayK*weight*(dirMult))
82
+ exp: (value, weight, decayK, ctx) => {
83
+ const dm = ctx?.direction === 0 ? (ctx?.bidirectionalMultiplier ?? 1.2) : (ctx?.directionalMultiplier ?? 0.7);
84
+ return value * Math.exp(-(decayK * weight * dm));
85
+ },
86
+ // 反比例:next = value / (1 + decayK*weight*(dirMult))
87
+ inverse: (value, weight, decayK, ctx) => {
88
+ const dm = ctx?.direction === 0 ? (ctx?.bidirectionalMultiplier ?? 1.2) : (ctx?.directionalMultiplier ?? 0.7);
89
+ return value / (1 + (decayK * weight * dm));
90
+ },
91
+ // 截断线性:线性后下限截断为0,上限截断为value
92
+ capped: (value, weight, decayK, ctx) => {
93
+ const dm = ctx?.direction === 0 ? (ctx?.bidirectionalMultiplier ?? 1.2) : (ctx?.directionalMultiplier ?? 0.7);
94
+ const raw = value - (decayK * weight * dm);
95
+ return Math.max(0, Math.min(value, raw));
96
+ }
97
+ };
98
+
99
+ function compileCustomFunctionSafely(source, argNames, fallback) {
100
+ try {
101
+ const ctx = vm.createContext({ Math });
102
+ // 如果用户提供的是“表达式”,包一层 return
103
+ const body = source.includes('return') || source.includes('=>') || source.includes('function')
104
+ ? source
105
+ : `return (${source});`;
106
+
107
+ // 统一包成 function 体
108
+ const wrapper = `(function(${argNames.join(',')}) { "use strict"; ${body} })`;
109
+ const script = new vm.Script(wrapper, { timeout: 50 });
110
+ const fn = script.runInContext(ctx, { timeout: 50 });
111
+ if (typeof fn !== 'function') return fallback;
112
+ // 再包一层,避免传入异常导致抛出
113
+ return (...args) => {
114
+ try { return fn(...args); } catch (_e) { return fallback(...args); }
115
+ };
116
+ } catch (_e) {
117
+ return fallback;
118
+ }
119
+ }
120
+ // ...existing code...
121
+
122
+ // 顶部 modelDefaults 增加参数(与本文件后半段的重复默认值保持一致)
58
123
  const modelDefaults = {
59
124
  decayFactor: 0.5,
60
125
  maxMemeWords: 100,
@@ -66,7 +131,12 @@ const modelDefaults = {
66
131
  decay: 1,
67
132
  decayK: 1,
68
133
  maxLen: 16,
69
- edgeWeight: 1
134
+ edgeWeight: 1,
135
+ // 新增:激活/传递函数选择与自定义
136
+ activationType: 'relu', // identity|relu|leaky_relu|tanh|sigmoid|elu|softplus|gelu|custom
137
+ transferType: 'linear', // linear|exp|inverse|capped|custom
138
+ activationCustom: '', // 自定义激活函数源码/表达式:f(x) 或 return ...
139
+ transferCustom: '' // 自定义传递函数源码/表达式:f(value, weight, decayK, ctx) 或 return ...
70
140
  };
71
141
  const currentModelParams = { ...modelDefaults };
72
142
  // 反触发机制
@@ -1615,7 +1685,9 @@ class Runtime {
1615
1685
  baseDir: path.join(__dirname, 'graph_parts'),
1616
1686
  backend: this.config.graphBackend || 'fs' // 可选 'fs' | 'lmdb' | 'level'
1617
1687
  });
1618
-
1688
+ this._act = BuiltinActivations.relu;
1689
+ this._transfer = BuiltinTransfers.linear;
1690
+ this._activationMeta = { activationType: 'relu', transferType: 'linear' };
1619
1691
  this.wordGraph = new GraphDB();
1620
1692
  this.kvm = new KVM();
1621
1693
  this.changer = new Changer();
@@ -1636,6 +1708,37 @@ class Runtime {
1636
1708
  batchSizeMultiplier: 1
1637
1709
  };
1638
1710
  this.memeBarrier = new memeBarrier(this);
1711
+ }
1712
+ // 获取/设置激活-传递函数配置
1713
+ getActivationConfig() {
1714
+ return {
1715
+ activationType: this._activationMeta.activationType,
1716
+ transferType: this._activationMeta.transferType,
1717
+ activationCustom: this.config?.activationCustom || '',
1718
+ transferCustom: this.config?.transferCustom || ''
1719
+ };
1720
+ }
1721
+
1722
+ setActivationConfig({ activationType, transferType, activationCustom, transferCustom } = {}) {
1723
+ const aType = String(activationType || this._activationMeta.activationType || 'relu');
1724
+ const tType = String(transferType || this._activationMeta.transferType || 'linear');
1725
+
1726
+ let act = BuiltinActivations[aType] || BuiltinActivations.relu;
1727
+ let tr = BuiltinTransfers[tType] || BuiltinTransfers.linear;
1728
+
1729
+ if (aType === 'custom' && activationCustom) {
1730
+ act = compileCustomFunctionSafely(activationCustom, ['x'], BuiltinActivations.relu);
1731
+ }
1732
+ if (tType === 'custom' && transferCustom) {
1733
+ tr = compileCustomFunctionSafely(transferCustom, ['value', 'weight', 'decayK', 'ctx'], BuiltinTransfers.linear);
1734
+ }
1735
+
1736
+ this._act = (typeof act === 'function') ? act : BuiltinActivations.relu;
1737
+ this._transfer = (typeof tr === 'function') ? tr : BuiltinTransfers.linear;
1738
+ this._activationMeta = { activationType: aType, transferType: tType };
1739
+ this.config = this.config || {};
1740
+ this.config.activationCustom = activationCustom || this.config.activationCustom || '';
1741
+ this.config.transferCustom = transferCustom || this.config.transferCustom || '';
1639
1742
  }
1640
1743
  // 新增资源监控方法
1641
1744
  monitorSystemLoad() {
@@ -2075,95 +2178,65 @@ class Runtime {
2075
2178
  * options.bidirectionalMultiplier: 双向连接的衰减倍率
2076
2179
  * @returns {Object|Map} 激活结果
2077
2180
  */
2181
+ // 用于多源扩散:将“传递函数+激活函数”应用在每一步
2078
2182
  propagateSignalMultiSource(startIDs, strengths, decayK, maxStep, options = {}) {
2079
2183
  decayK = decayK !== undefined ? decayK : (this.config.decayK !== undefined ? this.config.decayK : 1);
2080
2184
  maxStep = maxStep !== undefined ? maxStep : (this.config.maxStep !== undefined ? this.config.maxStep : 10);
2081
2185
  const maxActiveNodes = options.maxActiveNodes || 5000;
2082
2186
  const minSignal = options.minSignal || 0.01;
2083
2187
  const trackPath = options.trackPath || false;
2084
- // 单向和双向连接的衰减系数调整
2085
- const directionalMultiplier = options.directionalMultiplier || 0.7; // 单向连接的衰减倍率(较慢)
2086
- const bidirectionalMultiplier = options.bidirectionalMultiplier || 1.2; // 双向连接的衰减倍率(较快)
2188
+ const directionalMultiplier = options.directionalMultiplier || 0.7;
2189
+ const bidirectionalMultiplier = options.bidirectionalMultiplier || 1.2;
2190
+
2191
+ const actFn = this._act || BuiltinActivations.relu;
2192
+ const transferFn = this._transfer || BuiltinTransfers.linear;
2087
2193
 
2088
- // 节点信号累加表
2089
2194
  const signalMap = new Map();
2090
- // 路径追踪表(可选)
2091
2195
  const activationPaths = trackPath ? new Map() : null;
2092
- // 记录节点激活类型
2093
2196
  const activationTypes = trackPath ? new Map() : null;
2094
2197
 
2095
- // 初始化活跃队列,每个元素{id, value, from, connectionType}
2096
2198
  let active = startIDs.map((id, i) => ({
2097
- id,
2098
- value: strengths[i],
2099
- from: null,
2100
- connectionType: -1 // 起点无连接类型
2199
+ id, value: strengths[i], from: null, connectionType: -1
2101
2200
  }));
2102
-
2103
2201
  let step = 0;
2104
2202
 
2105
2203
  while (active.length > 0 && step < maxStep) {
2106
- // 限制活跃节点数,优先保留信号强的
2107
2204
  if (active.length > maxActiveNodes) {
2108
2205
  active.sort((a, b) => b.value - a.value);
2109
2206
  active = active.slice(0, maxActiveNodes);
2110
- console.log(`[LIMIT] 多源扩散活跃节点数已限制为 ${maxActiveNodes}`);
2111
2207
  }
2112
2208
 
2113
2209
  const next = [];
2114
2210
  for (const { id, value, from, connectionType } of active) {
2115
2211
  if (value < minSignal) continue;
2116
2212
 
2117
- // 信号融合:累加到signalMap
2118
- signalMap.set(id, (signalMap.get(id) || 0) + value);
2213
+ // 节点处应用激活函数(融合累计)
2214
+ const prev = signalMap.get(id) || 0;
2215
+ const merged = actFn(prev + value);
2216
+ signalMap.set(id, merged);
2119
2217
 
2120
- // 记录激活类型
2121
2218
  if (trackPath && connectionType !== -1) {
2122
- if (!activationTypes.has(id)) {
2123
- activationTypes.set(id, new Set());
2124
- }
2219
+ if (!activationTypes.has(id)) activationTypes.set(id, new Set());
2125
2220
  activationTypes.get(id).add(connectionType);
2126
2221
  }
2127
-
2128
- // 路径追踪
2129
2222
  if (trackPath && from) {
2130
- if (!activationPaths.has(id)) {
2131
- activationPaths.set(id, []);
2132
- }
2223
+ if (!activationPaths.has(id)) activationPaths.set(id, []);
2133
2224
  activationPaths.get(id).push({ from, connectionType, value });
2134
2225
  }
2135
2226
 
2136
- // 传播到邻居(考虑连接方向)
2137
2227
  const point = this.graph.points.get(id);
2138
2228
  if (!point) continue;
2139
2229
 
2140
- // 限制每个节点最多处理的邻居数量
2141
2230
  const MAX_NEIGHBORS = 30;
2142
2231
  const neighbors = point.connect.slice(0, MAX_NEIGHBORS);
2143
2232
 
2144
2233
  for (const [weight, neighborID, direction = 0] of neighbors) {
2145
- // 根据连接类型决定衰减系数
2146
- let effectiveDecay = decayK;
2147
-
2148
- if (direction === 0) {
2149
- // 双向连接 - 衰减较大(语义关联较弱)
2150
- effectiveDecay *= bidirectionalMultiplier;
2151
- } else {
2152
- // 单向连接 - 衰减较小(语义流向强)
2153
- effectiveDecay *= directionalMultiplier;
2154
- }
2155
-
2156
- // 计算传播后的信号强度
2157
- const nextValue = value - effectiveDecay * weight;
2234
+ const ctx = { direction, directionalMultiplier, bidirectionalMultiplier };
2235
+ const rawNext = transferFn(value, weight, decayK, ctx);
2236
+ const nextValue = actFn(rawNext);
2158
2237
 
2159
- // 仅当信号足够强时才继续传播
2160
2238
  if (nextValue >= minSignal) {
2161
- next.push({
2162
- id: neighborID,
2163
- value: nextValue,
2164
- from: id,
2165
- connectionType: direction
2166
- });
2239
+ next.push({ id: neighborID, value: nextValue, from: id, connectionType: direction });
2167
2240
  }
2168
2241
  }
2169
2242
  }
@@ -2171,15 +2244,9 @@ class Runtime {
2171
2244
  step++;
2172
2245
  }
2173
2246
 
2174
- // 返回结果,根据跟踪路径选项决定返回格式
2175
2247
  if (trackPath) {
2176
- return {
2177
- signalMap,
2178
- activationPaths,
2179
- activationTypes
2180
- };
2248
+ return { signalMap, activationPaths, activationTypes };
2181
2249
  }
2182
-
2183
2250
  return signalMap;
2184
2251
  }
2185
2252
 
@@ -3504,7 +3571,11 @@ app.post('/api/graph/prefetch', async (req, res) => {
3504
3571
  decay: 1, // 新增
3505
3572
  decayK: 1, // 新增
3506
3573
  maxLen: 16, // 新增
3507
- edgeWeight: 1 // 新增,GraphDB默认边权重
3574
+ edgeWeight: 1, // 新增
3575
+ activationType: 'relu',
3576
+ transferType: 'linear',
3577
+ activationCustom: '',
3578
+ transferCustom: ''
3508
3579
  };
3509
3580
  const currentModelParams = { ...modelDefaults };
3510
3581
 
@@ -3610,10 +3681,10 @@ app.post('/api/adversary/start', (req, res) => {
3610
3681
 
3611
3682
  console.log('已设置交错自主学习定时任务,每200s执行一次');
3612
3683
  }
3613
- // plainObjToRuntime: 将protobuf对象同步到runtime实例
3614
- // 扩展 applyModelParams
3615
3684
  function applyModelParams(runtime) {
3616
3685
  if (!runtime) return;
3686
+
3687
+ // 同步通用参数
3617
3688
  runtime.MAX_MEME_WORDS = currentModelParams.maxMemeWords;
3618
3689
  runtime.MIN_OVERLAP = currentModelParams.minOverlapThreshold;
3619
3690
  runtime.config = runtime.config || {};
@@ -3624,11 +3695,12 @@ function applyModelParams(runtime) {
3624
3695
  runtime.config.iteration = currentModelParams.iteration;
3625
3696
  runtime.config.threshold = currentModelParams.threshold;
3626
3697
  runtime.config.decay = currentModelParams.decay;
3698
+
3627
3699
  // memeBarrier
3628
3700
  if (runtime.memeBarrier) {
3629
3701
  runtime.memeBarrier.maliciousThreshold = currentModelParams.maliciousThreshold;
3630
3702
  }
3631
- // GraphDB边权重(如需全局调整,可遍历所有边)
3703
+ // 全局边权
3632
3704
  if (runtime.graph && currentModelParams.edgeWeight !== undefined) {
3633
3705
  for (const point of runtime.graph.getAllPoints()) {
3634
3706
  for (const conn of point.connect) {
@@ -3636,7 +3708,20 @@ function applyModelParams(runtime) {
3636
3708
  }
3637
3709
  }
3638
3710
  }
3639
- console.log('[PARAMS] 已更新运行时参数:', currentModelParams);
3711
+
3712
+ // 新增:激活/传递函数配置
3713
+ runtime.setActivationConfig({
3714
+ activationType: currentModelParams.activationType,
3715
+ transferType: currentModelParams.transferType,
3716
+ activationCustom: currentModelParams.activationCustom,
3717
+ transferCustom: currentModelParams.transferCustom
3718
+ });
3719
+
3720
+ console.log('[PARAMS] 已更新运行时参数:', {
3721
+ ...currentModelParams,
3722
+ activationType: runtime.getActivationConfig().activationType,
3723
+ transferType: runtime.getActivationConfig().transferType
3724
+ });
3640
3725
  }
3641
3726
  // plainObjToRuntime: 将protobuf对象同步到runtime实例
3642
3727
  async function plainObjToRuntime(runtime, obj) {
package/main_Study.cjs CHANGED
@@ -41,6 +41,71 @@ global.config = {
41
41
  masterPortOfMain: process.argv[2],
42
42
  emitExitport: process.argv[3] || 8641
43
43
  };
44
+ // ...existing code...
45
+ const vm = require('vm'); // 新增:沙箱编译
46
+ // ...existing code...
47
+
48
+ // ==== 内置激活/传递函数注册表 + 安全编译工具 ====
49
+ const BuiltinActivations = {
50
+ identity: (x) => x,
51
+ relu: (x) => (x > 0 ? x : 0),
52
+ leaky_relu: (x) => (x > 0 ? x : 0.01 * x),
53
+ tanh: (x) => Math.tanh(x),
54
+ sigmoid: (x) => 1 / (1 + Math.exp(-x)),
55
+ elu: (x) => (x >= 0 ? x : (Math.exp(x) - 1)),
56
+ softplus: (x) => Math.log(1 + Math.exp(x)),
57
+ // 近似 GELU
58
+ gelu: (x) => 0.5 * x * (1 + Math.tanh(Math.sqrt(2 / Math.PI) * (x + 0.044715 * Math.pow(x, 3))))
59
+ };
60
+
61
+ const BuiltinTransfers = {
62
+ // 线性衰减:next = value - decayK*weight*(dirMult)
63
+ linear: (value, weight, decayK, ctx) => {
64
+ const dm = ctx?.direction === 0 ? (ctx?.bidirectionalMultiplier ?? 1.2) : (ctx?.directionalMultiplier ?? 0.7);
65
+ return value - (decayK * weight * dm);
66
+ },
67
+ // 指数衰减:next = value * exp(-decayK*weight*(dirMult))
68
+ exp: (value, weight, decayK, ctx) => {
69
+ const dm = ctx?.direction === 0 ? (ctx?.bidirectionalMultiplier ?? 1.2) : (ctx?.directionalMultiplier ?? 0.7);
70
+ return value * Math.exp(-(decayK * weight * dm));
71
+ },
72
+ // 反比例:next = value / (1 + decayK*weight*(dirMult))
73
+ inverse: (value, weight, decayK, ctx) => {
74
+ const dm = ctx?.direction === 0 ? (ctx?.bidirectionalMultiplier ?? 1.2) : (ctx?.directionalMultiplier ?? 0.7);
75
+ return value / (1 + (decayK * weight * dm));
76
+ },
77
+ // 截断线性:线性后下限截断为0,上限截断为value
78
+ capped: (value, weight, decayK, ctx) => {
79
+ const dm = ctx?.direction === 0 ? (ctx?.bidirectionalMultiplier ?? 1.2) : (ctx?.directionalMultiplier ?? 0.7);
80
+ const raw = value - (decayK * weight * dm);
81
+ return Math.max(0, Math.min(value, raw));
82
+ }
83
+ };
84
+
85
+ function compileCustomFunctionSafely(source, argNames, fallback) {
86
+ try {
87
+ const ctx = vm.createContext({ Math });
88
+ // 如果用户提供的是“表达式”,包一层 return
89
+ const body = source.includes('return') || source.includes('=>') || source.includes('function')
90
+ ? source
91
+ : `return (${source});`;
92
+
93
+ // 统一包成 function 体
94
+ const wrapper = `(function(${argNames.join(',')}) { "use strict"; ${body} })`;
95
+ const script = new vm.Script(wrapper, { timeout: 50 });
96
+ const fn = script.runInContext(ctx, { timeout: 50 });
97
+ if (typeof fn !== 'function') return fallback;
98
+ // 再包一层,避免传入异常导致抛出
99
+ return (...args) => {
100
+ try { return fn(...args); } catch (_e) { return fallback(...args); }
101
+ };
102
+ } catch (_e) {
103
+ return fallback;
104
+ }
105
+ }
106
+ // ...existing code...
107
+
108
+ // 顶部 modelDefaults 增加参数(与本文件后半段的重复默认值保持一致)
44
109
  const modelDefaults = {
45
110
  decayFactor: 0.5,
46
111
  maxMemeWords: 100,
@@ -52,7 +117,12 @@ const modelDefaults = {
52
117
  decay: 1,
53
118
  decayK: 1,
54
119
  maxLen: 16,
55
- edgeWeight: 1
120
+ edgeWeight: 1,
121
+ // 新增:激活/传递函数选择与自定义
122
+ activationType: 'relu', // identity|relu|leaky_relu|tanh|sigmoid|elu|softplus|gelu|custom
123
+ transferType: 'linear', // linear|exp|inverse|capped|custom
124
+ activationCustom: '', // 自定义激活函数源码/表达式:f(x) 或 return ...
125
+ transferCustom: '' // 自定义传递函数源码/表达式:f(value, weight, decayK, ctx) 或 return ...
56
126
  };
57
127
  const currentModelParams = { ...modelDefaults };
58
128
  // ...existing code...
@@ -2045,6 +2115,40 @@ class Runtime {
2045
2115
  batchSizeMultiplier: 1
2046
2116
  };
2047
2117
  this.memeBarrier = new memeBarrier(this);
2118
+ this._act = BuiltinActivations.relu;
2119
+ this._transfer = BuiltinTransfers.linear;
2120
+ this._activationMeta = { activationType: 'relu', transferType: 'linear' };
2121
+ }
2122
+ // 获取/设置激活-传递函数配置
2123
+ getActivationConfig() {
2124
+ return {
2125
+ activationType: this._activationMeta.activationType,
2126
+ transferType: this._activationMeta.transferType,
2127
+ activationCustom: this.config?.activationCustom || '',
2128
+ transferCustom: this.config?.transferCustom || ''
2129
+ };
2130
+ }
2131
+
2132
+ setActivationConfig({ activationType, transferType, activationCustom, transferCustom } = {}) {
2133
+ const aType = String(activationType || this._activationMeta.activationType || 'relu');
2134
+ const tType = String(transferType || this._activationMeta.transferType || 'linear');
2135
+
2136
+ let act = BuiltinActivations[aType] || BuiltinActivations.relu;
2137
+ let tr = BuiltinTransfers[tType] || BuiltinTransfers.linear;
2138
+
2139
+ if (aType === 'custom' && activationCustom) {
2140
+ act = compileCustomFunctionSafely(activationCustom, ['x'], BuiltinActivations.relu);
2141
+ }
2142
+ if (tType === 'custom' && transferCustom) {
2143
+ tr = compileCustomFunctionSafely(transferCustom, ['value', 'weight', 'decayK', 'ctx'], BuiltinTransfers.linear);
2144
+ }
2145
+
2146
+ this._act = (typeof act === 'function') ? act : BuiltinActivations.relu;
2147
+ this._transfer = (typeof tr === 'function') ? tr : BuiltinTransfers.linear;
2148
+ this._activationMeta = { activationType: aType, transferType: tType };
2149
+ this.config = this.config || {};
2150
+ this.config.activationCustom = activationCustom || this.config.activationCustom || '';
2151
+ this.config.transferCustom = transferCustom || this.config.transferCustom || '';
2048
2152
  }
2049
2153
  // 新增:应用可调参数(含 spiderMix / decayK / maxLen 等)
2050
2154
  applyTunableParams(partial = {}) {
@@ -2585,59 +2689,58 @@ class Runtime {
2585
2689
  const maxActiveNodes = options.maxActiveNodes || 5000;
2586
2690
  const minSignal = options.minSignal || 0.01;
2587
2691
  const trackPath = options.trackPath || false;
2692
+ const directionalMultiplier = options.directionalMultiplier || 0.7;
2693
+ const bidirectionalMultiplier = options.bidirectionalMultiplier || 1.2;
2694
+
2695
+ const actFn = this._act || BuiltinActivations.relu;
2696
+ const transferFn = this._transfer || BuiltinTransfers.linear;
2588
2697
 
2589
- // 节点信号累加表
2590
2698
  const signalMap = new Map();
2591
- // 路径追踪表(可选)
2592
2699
  const activationPaths = trackPath ? new Map() : null;
2700
+ const activationTypes = trackPath ? new Map() : null;
2593
2701
 
2594
- // 初始化活跃队列,每个元素{id, value, from}
2595
2702
  let active = startIDs.map((id, i) => ({
2596
- id,
2597
- value: strengths[i],
2598
- from: null // 起点无前驱
2703
+ id, value: strengths[i], from: null, connectionType: -1
2599
2704
  }));
2600
-
2601
2705
  let step = 0;
2602
2706
 
2603
2707
  while (active.length > 0 && step < maxStep) {
2604
- // 1. 限制活跃节点数,优先保留信号强的
2605
2708
  if (active.length > maxActiveNodes) {
2606
2709
  active.sort((a, b) => b.value - a.value);
2607
2710
  active = active.slice(0, maxActiveNodes);
2608
- console.log(`[LIMIT] 多源扩散活跃节点数已限制为 ${maxActiveNodes}`);
2609
2711
  }
2610
2712
 
2611
2713
  const next = [];
2612
- for (const { id, value, from } of active) {
2714
+ for (const { id, value, from, connectionType } of active) {
2613
2715
  if (value < minSignal) continue;
2614
2716
 
2615
- // 信号融合:累加到signalMap
2616
- signalMap.set(id, (signalMap.get(id) || 0) + value);
2717
+ // 节点处应用激活函数(融合累计)
2718
+ const prev = signalMap.get(id) || 0;
2719
+ const merged = actFn(prev + value);
2720
+ signalMap.set(id, merged);
2617
2721
 
2618
- // 路径追踪
2619
- if (trackPath) {
2722
+ if (trackPath && connectionType !== -1) {
2723
+ if (!activationTypes.has(id)) activationTypes.set(id, new Set());
2724
+ activationTypes.get(id).add(connectionType);
2725
+ }
2726
+ if (trackPath && from) {
2620
2727
  if (!activationPaths.has(id)) activationPaths.set(id, []);
2621
- if (from !== null) activationPaths.get(id).push(from);
2728
+ activationPaths.get(id).push({ from, connectionType, value });
2622
2729
  }
2623
2730
 
2624
- // 传播到邻居(不防环,允许信号多次叠加)
2625
2731
  const point = this.graph.points.get(id);
2626
- if (point) {
2627
- // 限制每个节点最多处理的邻居数量
2628
- const MAX_NEIGHBORS = 30;
2629
- const neighbors = point.connect.slice(0, MAX_NEIGHBORS);
2630
-
2631
- for (const [weight, neighborID] of neighbors) {
2632
- // 信号可按边权重调整(如weight越小越容易传播)
2633
- const nextValue = value - decayK * weight;
2634
- if (nextValue >= minSignal) {
2635
- next.push({
2636
- id: neighborID,
2637
- value: nextValue,
2638
- from: id
2639
- });
2640
- }
2732
+ if (!point) continue;
2733
+
2734
+ const MAX_NEIGHBORS = 30;
2735
+ const neighbors = point.connect.slice(0, MAX_NEIGHBORS);
2736
+
2737
+ for (const [weight, neighborID, direction = 0] of neighbors) {
2738
+ const ctx = { direction, directionalMultiplier, bidirectionalMultiplier };
2739
+ const rawNext = transferFn(value, weight, decayK, ctx);
2740
+ const nextValue = actFn(rawNext);
2741
+
2742
+ if (nextValue >= minSignal) {
2743
+ next.push({ id: neighborID, value: nextValue, from: id, connectionType: direction });
2641
2744
  }
2642
2745
  }
2643
2746
  }
@@ -2646,7 +2749,7 @@ class Runtime {
2646
2749
  }
2647
2750
 
2648
2751
  if (trackPath) {
2649
- return { signalMap, activationPaths };
2752
+ return { signalMap, activationPaths, activationTypes };
2650
2753
  }
2651
2754
  return signalMap;
2652
2755
  }
@@ -4471,7 +4574,11 @@ app.post('/api/adversary/start', (req, res) => {
4471
4574
  decay: 1, // 新增
4472
4575
  decayK: 1, // 新增
4473
4576
  maxLen: 16, // 新增
4474
- edgeWeight: 1 // 新增,GraphDB默认边权重
4577
+ edgeWeight: 1, // 新增
4578
+ activationType: 'relu',
4579
+ transferType: 'linear',
4580
+ activationCustom: '',
4581
+ transferCustom: ''
4475
4582
  };
4476
4583
  const currentModelParams = { ...modelDefaults };
4477
4584
 
@@ -4571,10 +4678,10 @@ app.post('/api/adversary/start', (req, res) => {
4571
4678
  console.log('已设置交错自主学习定时任务,每200s执行一次');
4572
4679
  }
4573
4680
 
4574
- // 将参数应用到运行时
4575
- // 扩展 applyModelParams
4576
4681
  function applyModelParams(runtime) {
4577
4682
  if (!runtime) return;
4683
+
4684
+ // 同步通用参数
4578
4685
  runtime.MAX_MEME_WORDS = currentModelParams.maxMemeWords;
4579
4686
  runtime.MIN_OVERLAP = currentModelParams.minOverlapThreshold;
4580
4687
  runtime.config = runtime.config || {};
@@ -4585,11 +4692,12 @@ function applyModelParams(runtime) {
4585
4692
  runtime.config.iteration = currentModelParams.iteration;
4586
4693
  runtime.config.threshold = currentModelParams.threshold;
4587
4694
  runtime.config.decay = currentModelParams.decay;
4695
+
4588
4696
  // memeBarrier
4589
4697
  if (runtime.memeBarrier) {
4590
4698
  runtime.memeBarrier.maliciousThreshold = currentModelParams.maliciousThreshold;
4591
4699
  }
4592
- // GraphDB边权重(如需全局调整,可遍历所有边)
4700
+ // 全局边权
4593
4701
  if (runtime.graph && currentModelParams.edgeWeight !== undefined) {
4594
4702
  for (const point of runtime.graph.getAllPoints()) {
4595
4703
  for (const conn of point.connect) {
@@ -4597,7 +4705,20 @@ function applyModelParams(runtime) {
4597
4705
  }
4598
4706
  }
4599
4707
  }
4600
- console.log('[PARAMS] 已更新运行时参数:', currentModelParams);
4708
+
4709
+ // 新增:激活/传递函数配置
4710
+ runtime.setActivationConfig({
4711
+ activationType: currentModelParams.activationType,
4712
+ transferType: currentModelParams.transferType,
4713
+ activationCustom: currentModelParams.activationCustom,
4714
+ transferCustom: currentModelParams.transferCustom
4715
+ });
4716
+
4717
+ console.log('[PARAMS] 已更新运行时参数:', {
4718
+ ...currentModelParams,
4719
+ activationType: runtime.getActivationConfig().activationType,
4720
+ transferType: runtime.getActivationConfig().transferType
4721
+ });
4601
4722
  }
4602
4723
  // 如果直接运行此文件,启动主函数
4603
4724
  if (require.main === module) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "079project",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "a GNN-GA BASED ai that might pass the turing test,which use little resources.its startpoint initialize it and you can start it as ```node mainStarter.cjs```",
5
5
  "keywords": [
6
6
  "ai",
@@ -11,6 +11,10 @@
11
11
  "turing",
12
12
  "test"
13
13
  ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://gitee.com/mumu2009/079-project.git"
17
+ },
14
18
  "license": "LGPL-3.0",
15
19
  "author": "mumu2009",
16
20
  "type": "commonjs",