learning_model 1.0.46 → 1.0.47

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.
@@ -29,7 +29,7 @@ declare class DataModel implements LearningInterface {
29
29
  augmentData(data: number[]): number[];
30
30
  normalizeData(data: number[]): number[];
31
31
  train(): Promise<tf.History>;
32
- infer(data: number[]): Promise<any>;
32
+ infer(data: number[]): Promise<Map<string, number>>;
33
33
  saveModel(handlerOrURL: io.IOHandler | string, config?: io.SaveConfig): Promise<void>;
34
34
  running(): boolean;
35
35
  ready(): boolean;
@@ -132,10 +132,48 @@ class DataModel {
132
132
  if (!this.isReady || !this.model) {
133
133
  throw new Error('Model is not ready');
134
134
  }
135
+ // 입력 데이터를 텐서로 변환
135
136
  const input = tf.tensor2d([data], [1, data.length], 'float32');
136
- const prediction = this.model.predict(input);
137
- const result = prediction.argMax(-1).dataSync()[0];
138
- return Object.keys(this.dataManager.getLabelMap()).find(key => this.dataManager.getLabelMap()[key] === result);
137
+ try {
138
+ // 모델 예측 수행
139
+ const prediction = this.model.predict(input);
140
+ // 예측 결과 값들을 추출
141
+ const values = yield prediction.data();
142
+ // 클래스 이름과 확률을 저장할 Map 생성
143
+ const classProbabilities = new Map();
144
+ const EPSILON = 1e-6; // 매우 작은 값을 표현하기 위한 엡실론
145
+ // 라벨 맵을 가져옴
146
+ const labelMap = this.dataManager.getLabelMap();
147
+ const reverseLabelMap = Object.entries(labelMap).reduce((acc, [key, value]) => {
148
+ acc[value] = key;
149
+ return acc;
150
+ }, {});
151
+ // 각 클래스의 확률 계산 및 조정
152
+ for (let i = 0; i < values.length; i++) {
153
+ let probability = Math.max(0, Math.min(1, values[i])); // 확률 값을 0과 1 사이로 조정
154
+ probability = probability < EPSILON ? 0 : probability; // 매우 작은 확률 값을 0으로 간주
155
+ const className = reverseLabelMap[i]; // 클래스 이름을 문자열로 가져옴
156
+ if (className) {
157
+ const existingProbability = classProbabilities.get(className);
158
+ if (existingProbability !== undefined) {
159
+ classProbabilities.set(className, existingProbability + probability);
160
+ }
161
+ else {
162
+ classProbabilities.set(className, probability);
163
+ }
164
+ }
165
+ }
166
+ // 텐서 해제
167
+ prediction.dispose();
168
+ input.dispose();
169
+ console.log('classProbabilities', classProbabilities);
170
+ return classProbabilities;
171
+ }
172
+ catch (error) {
173
+ // 텐서 해제
174
+ input.dispose();
175
+ throw error;
176
+ }
139
177
  });
140
178
  }
141
179
  saveModel(handlerOrURL, config) {
@@ -16,7 +16,9 @@ const data_model_1 = __importDefault(require("./data_model"));
16
16
  describe('LearningModel', () => {
17
17
  let learningModel;
18
18
  beforeEach(() => {
19
- learningModel = new data_model_1.default();
19
+ learningModel = new data_model_1.default({
20
+ epochs: 10,
21
+ });
20
22
  });
21
23
  it('should add sufficient data and train the model', () => __awaiter(void 0, void 0, void 0, function* () {
22
24
  // 훈련 데이터 생성
@@ -39,6 +41,7 @@ describe('LearningModel', () => {
39
41
  const classLabel = i % 2 === 0 ? 'class1' : 'class2'; // 두 개의 클래스를 번갈아가며 생성
40
42
  const data = Array.from({ length: 3 }, () => Math.random() * 10); // 임의의 데이터 생성
41
43
  yield learningModel.addData(classLabel, data);
44
+ yield learningModel.addData(classLabel, [1, 2, 4]);
42
45
  }
43
46
  // 모델 훈련
44
47
  yield learningModel.train();
@@ -49,6 +52,5 @@ describe('LearningModel', () => {
49
52
  console.log('result', result);
50
53
  // 결과 평가
51
54
  expect(result).toBeDefined();
52
- expect(['class1', 'class2']).toContain(result);
53
55
  }), 30000);
54
56
  });
@@ -29,7 +29,7 @@ declare class DataModel implements LearningInterface {
29
29
  augmentData(data: number[]): number[];
30
30
  normalizeData(data: number[]): number[];
31
31
  train(): Promise<tf.History>;
32
- infer(data: number[]): Promise<any>;
32
+ infer(data: number[]): Promise<Map<string, number>>;
33
33
  saveModel(handlerOrURL: io.IOHandler | string, config?: io.SaveConfig): Promise<void>;
34
34
  running(): boolean;
35
35
  ready(): boolean;
@@ -4,7 +4,9 @@ describe('LearningModel', () => {
4
4
  let learningModel: LearningModel;
5
5
 
6
6
  beforeEach(() => {
7
- learningModel = new LearningModel();
7
+ learningModel = new LearningModel({
8
+ epochs: 10,
9
+ });
8
10
  });
9
11
 
10
12
  it('should add sufficient data and train the model', async () => {
@@ -32,6 +34,7 @@ describe('LearningModel', () => {
32
34
  const classLabel = i % 2 === 0 ? 'class1' : 'class2'; // 두 개의 클래스를 번갈아가며 생성
33
35
  const data = Array.from({ length: 3 }, () => Math.random() * 10); // 임의의 데이터 생성
34
36
  await learningModel.addData(classLabel, data);
37
+ await learningModel.addData(classLabel, [1,2,4]);
35
38
  }
36
39
 
37
40
  // 모델 훈련
@@ -46,6 +49,5 @@ describe('LearningModel', () => {
46
49
 
47
50
  // 결과 평가
48
51
  expect(result).toBeDefined();
49
- expect(['class1', 'class2']).toContain(result);
50
52
  }, 30000);
51
53
  });
@@ -122,17 +122,63 @@ class DataModel implements LearningInterface {
122
122
  return history;
123
123
  }
124
124
 
125
- async infer(data: number[]): Promise<any> {
125
+ public async infer(data: number[]): Promise<Map<string, number>> {
126
126
  if (!this.isReady || !this.model) {
127
127
  throw new Error('Model is not ready');
128
128
  }
129
129
 
130
+ // 입력 데이터를 텐서로 변환
130
131
  const input = tf.tensor2d([data], [1, data.length], 'float32');
131
- const prediction = this.model.predict(input) as tf.Tensor;
132
- const result = prediction.argMax(-1).dataSync()[0];
133
132
 
134
- return Object.keys(this.dataManager.getLabelMap()).find(key => this.dataManager.getLabelMap()[key] === result);
133
+ try {
134
+ // 모델 예측 수행
135
+ const prediction = this.model.predict(input) as tf.Tensor<tf.Rank>;
136
+
137
+ // 예측 결과 값들을 추출
138
+ const values = await prediction.data();
139
+
140
+ // 클래스 이름과 확률을 저장할 Map 생성
141
+ const classProbabilities = new Map<string, number>();
142
+ const EPSILON = 1e-6; // 매우 작은 값을 표현하기 위한 엡실론
143
+
144
+ // 라벨 맵을 가져옴
145
+ const labelMap = this.dataManager.getLabelMap();
146
+ const reverseLabelMap = Object.entries(labelMap).reduce((acc, [key, value]) => {
147
+ acc[value] = key;
148
+ return acc;
149
+ }, {} as { [key: number]: string });
150
+
151
+ // 각 클래스의 확률 계산 및 조정
152
+ for (let i = 0; i < values.length; i++) {
153
+ let probability = Math.max(0, Math.min(1, values[i])); // 확률 값을 0과 1 사이로 조정
154
+ probability = probability < EPSILON ? 0 : probability; // 매우 작은 확률 값을 0으로 간주
155
+ const className = reverseLabelMap[i]; // 클래스 이름을 문자열로 가져옴
156
+ if (className) {
157
+ const existingProbability = classProbabilities.get(className);
158
+ if (existingProbability !== undefined) {
159
+ classProbabilities.set(className, existingProbability + probability);
160
+ } else {
161
+ classProbabilities.set(className, probability);
162
+ }
163
+ }
164
+ }
165
+
166
+ // 텐서 해제
167
+ prediction.dispose();
168
+ input.dispose();
169
+
170
+ console.log('classProbabilities', classProbabilities);
171
+ return classProbabilities;
172
+ } catch (error) {
173
+ // 텐서 해제
174
+ input.dispose();
175
+ throw error;
176
+ }
135
177
  }
178
+
179
+
180
+
181
+
136
182
 
137
183
  async saveModel(handlerOrURL: io.IOHandler | string, config?: io.SaveConfig): Promise<void> {
138
184
  if (!this.model) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "learning_model",
3
- "version": "1.0.46",
3
+ "version": "1.0.47",
4
4
  "description": "learning model develop",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",