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 +106 -37
- package/main_Serve.cjs +146 -61
- package/main_Study.cjs +159 -38
- package/package.json +5 -1
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
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
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
|
|
2086
|
-
|
|
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
|
-
//
|
|
2118
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
//
|
|
2616
|
-
|
|
2717
|
+
// 节点处应用激活函数(融合累计)
|
|
2718
|
+
const prev = signalMap.get(id) || 0;
|
|
2719
|
+
const merged = actFn(prev + value);
|
|
2720
|
+
signalMap.set(id, merged);
|
|
2617
2721
|
|
|
2618
|
-
|
|
2619
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
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
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
+
"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",
|