์ 2ํ ์ฐ๊ตฌ๊ฐ๋ฐํน๊ตฌ ์ธ๊ณต์ง๋ฅ ๊ฒฝ์ง๋ํ AI SPARK ์ฑ๋ฆฐ์ง
๐ Top 5% in mAP(0.75) (443๋ช ์ค 13๋ฑ, mAP: 0.98116)
- Edge ํ๊ฒฝ์์์ ๊ฐ์ถ Object Detection (Pig, Cow)
- ์ค์ ํ๊ฒฝ์์ ํ์ฉ๊ฐ๋ฅํ Edge Device (ex: ์ ฏ์จ ๋๋ ธ๋ณด๋ ๋ฑ) ๊ธฐ๋ฐ์ ๊ฐ๋ฒผ์ด ๊ฒฝ๋ํ ๋ชจ๋ธ์ ๊ฐ๋ฐํ๋ ๊ฒ์ด ๋ชฉํ์ด๋ค.
- ๊ฐ์ค์น ํ์ผ์ ์ฉ๋์ 100MB๋ก ์ ํํ๋ค.
- ๊ฐ์ค์น ํ์ผ์ ์ฉ๋์ด 100MB์ดํ์ด๋ฉด์ mAP(IoU 0.75)๋ฅผ ๊ธฐ์ค์ผ๋ก ์์๋ฅผ ๋งค๊ธด๋ค.
- ๋ณธ ๋ํ์ ๋ชจ๋ ๊ณผ์ ์ Colab Pro ํ๊ฒฝ์์ ์งํ ๋ฐ ์ฌํํ๋ค.
- Colab Pro (P100 or T4)
- AI Hub์์ ์ ๊ณตํ๋ ๊ฐ์ถ ํ๋ ์์ ๋ฐ์ดํฐ์ (๋ค์ด๋ก๋ ๋งํฌ)
- [์์ฒ]์_bbox.zip: ์ image ํ์ผ
- [๋ผ๋ฒจ]์_bbox.zip: ์ annotation ํ์ผ
- [์์ฒ]๋ผ์ง_bbox.zip: ๋ผ์ง image ํ์ผ
- [๋ผ๋ฒจ]๋ผ์ง_bbox.zip: ๋ผ์ง annotation ํ์ผ
- ์ถ๊ฐ์ ์ผ๋ก, annotation์์์ "categories"์ ๊ฐ๊ณผ annotation list์ "category_id"๋ ์, ๋ผ์ง ํด๋์ค์ ๋ฌด๊ดํ๋ฏ๋ก ์ด๋ฅผ ํ์ฉํ ๊ฒฝ์ฐ ์๋ชป๋ ๊ฒฐ๊ณผ๋ก ์ด์ด์ง ์ ์๋ค.
+- data (.gitignore) => zipํ์ผ๋ง ์ต์ด ์์ฑ(AI Hub) ํ ์ถ๊ฐ ๋ฐ์ดํฐ๋ EDA ํด๋ ์ฝ๋๋ก๋ถํฐ ์์ฑ
| +- [๋ผ๋ฒจ]๋ผ์ง_bbox.zip
| +- [๋ผ๋ฒจ]์_bbox.zip
| +- [์์ฒ]๋ผ์ง_bbox.zip
| +- [์์ฒ]์_bbox.zip
| +- Train_Dataset.tar (EDA - Make_Dataset_Multilabel.ipynb์์ ์์ฑ)
| +- Valid_Dataset.tar (EDA - Make_Dataset_Multilabel.ipynb์์ ์์ฑ)
| +- Train_Dataset_Full.tar (EDA - Make_Dataset_Full.ipynb์์ ์์ฑ)
| +- Train_Dataset_mini.tar (EDA - Make_Dataset_Mini.ipynb์์ ์์ฑ)
| +- Valid_Dataset_mini.tar (EDA - Make_Dataset_Mini.ipynb์์ ์์ฑ)
| +- plus_image.tar (EDA - Data_Augmentation.ipynb์์ ์์ฑ)
| +- plus_lable.tar (EDA - Data_Augmentation.ipynb์์ ์์ฑ)
+- data_test (.gitignore) => Inference์ ์ฌ์ฉํ test data (AI Hub์ผ๋ก๋ถํฐ ๋ค์ด๋ก๋)
| +- [์์ฒ]๋ผ์ฌ_bbox.zip
| +- [์์ฒ]์_bbox.zip
+- trained_model (.gitignore) => ํ์ต ๊ฒฐ๊ณผ๋ฌผ ์ ์ฅ
| +- m6_pretrained_full_b10_e20_hyp_tuning_v1_linear.pt
+- EDA
| +- Data_Augmentation.ipynb (Plus Dataset ์์ฑ)
| +- Data_Checking.ipynb (Error Analysis)
| +- EDA.ipynb
| +- Make_Dataset_Multilabel.ipynb (Train / Valid Dataset ์์ฑ)
| +- Make_Dataset_Full.ipynb (Train + Valid Dataset ์์ฑ)
| +- Make_Dataset_Mini.ipynb (Train mini / Valid mini Dataset ์์ฑ)
+- hyp
| +- experiment_hyp_v1.yaml (์ต์ข
HyperParameter)
+- exp
| +- hyp_train.py (๋ณธ ์ฝ๋์ ๊ฐ์ด ์์ ํ์ฌ, ์ฌ๋ฌ ์คํ ์งํ)
| +- YOLOv5_hp_search_lr_momentum.ipynb (HyperParameter Tuning with mini dataset)
+- train
| +- YOLOv5_ExpandDataset_hp_tune.ipynb (Plus Dataset์ ํ์ฉํ์ฌ ํ์ต)
| +- YOLOv5_FullDataset_hp_tune.ipynb (์ต์ข
๊ฒฐ๊ณผ๋ฌผ ์์ฑ)
| +- YOLOv5_MultiLabelSplit.ipynb (์ด๊ธฐ ํ์ต ์ฝ๋)
+- YOLOv5_inference.ipynb
+- answer.csv (์ต์ข
์ ๋ต csv)
- YOLOv5m6 Pretrained Model ์ฌ์ฉ (68.3MB)
- MultiLabelStratified KFold (Box count, Class, Box Ratio, Box Size)
- HyperParameter Tuning (with GA Algorithm)
- Data Augmentation with Error Analysis
- Inference Tuning (IoU Threshold, Confidence Threshold)
์์ธํ
PIG | COW | |
---|---|---|
Image ๊ฐ์ | 4303 | 12152 |
- Data์ ๋ถํฌ๊ฐ "Cow : Pig = 3 : 1"
- Train / Valid splitํ ๊ฒฝ์ฐ, ๊ณจ๊ณ ๋ฃจ ๋ถํฌํ๋๋ก ์งํ
Pig Image Size | Cow Image Size | |
---|---|---|
1920x1080 | 3131 | 12152 |
1280x960 | 1172 | 0 |
- ๋๋ถ๋ถ์ Image์ ํฌ๊ธฐ๋ 1920x1080
- Pig Data์์ ์ผ๋ถ image์ ํฌ๊ธฐ๊ฐ 1280x960
- ์ขํ๋ณํ ์ ์ฉ์, Image size๋ฅผ ๊ณ ๋ คํ์ฌ ๋ณํ
- pig data์ cow data์์ Box์ ๊ฐ์๊ฐ ์๋ก ์์ดํ๊ฒ ๋ถํฌ
- Train / Valid splitํ ๊ฒฝ์ฐ, ๊ฐ image๋ณ๋ก ๊ฐ์ง๋ Box์ ๊ฐ์์ ๋ฐ๋ผ์ ๊ณจ๊ณ ๋ฃจ ๋ถํฌํ ์ ์๋๋ก ์งํ.
- pig data์ cow data์์ Box์ ๋น์จ์ ์ ์ฌ
- Train / Valid splitํ ๊ฒฝ์ฐ, ๊ฐ image๋ณ๋ก ๊ฐ์ง๋ Box์ ๋น์จ์ ๋ฐ๋ผ์ ๊ณจ๊ณ ๋ฃจ ๋ถํฌํ ์ ์๋๋ก ์งํ.
- pig data, cow data ๋ชจ๋ small size bounding box (๋์ด: 1000~10000)์ ๊ฐ์๊ฐ ์๋์ ์ผ๋ก ์ ์.
- small size bounding box๋ฅผ ์ง์ธ ๊ฒ์ธ๊ฐ? => ์ ํ์ ๋ฌธ์ (๋ณธ ๊ณผ์ ์์๋ ์ง์ฐ์ง ์์)
๋์ด๊ฐ 4000์ดํ์ธ Data์ ๊ฐ์ | PIG | COW |
---|---|---|
๊ฐ์ | 137 | 71 |
๋น์จ | 0.003 | 0.0018 |
- ๋์ด๊ฐ 4000์ดํ์ธ Data์ ๊ฐ์๊ฐ pig data 137๊ฐ, cow data 71๊ฐ
- ์ ์ฒด Data์ ๋ํ ๋น์จ (137 -> 0.003, 71 -> 0.0018). ์ฆ, 0.3%, 0.18%
- ๋์ด๊ฐ 4000์ดํ์ธ Bounding Box๋ฅผ ์ง์ธ ๊ฒ์ธ๊ฐ? => ์ ํ์ ๋ฌธ์ (๋ณธ ๊ณผ์ ์์๋ ์ง์ฐ์ง ์์)
Box๊ฐ ์๋ ์ด๋ฏธ์ง | PIG | COW |
---|---|---|
๊ฐ์ | 0 | 3 |
- Cow Image์์ 3๊ฐ ์กด์ฌ
- White Noise๋ก ํ๋จํ์ฌ ์ญ์ ํ์ง ์์.
- YOLOv5m6 Pretrained Model ์ฌ์ฉ
- YOLOv5 ๊ณ์ด Pretrained Model ์ค 100MB ์ดํ์ธ Model ์ ์
YOLOv5l Pretrained | YOLOv5m6 w/o Pretrained | YOLOv5m6 Pretrained | |
---|---|---|---|
[email protected] | 0.9806 | 0.9756 | 0.9838 |
[email protected]:.95 | 0.9002 | 0.8695 | 0.9156 |
- ์ต์ข ์ฌ์ฉ Model๋ก์ YOLOv5m6 Pretrained Model ์ ํ
- PIG / COW์ Data์ ๊ฐ์์ ๋ํ ์ฐจ์ด
- Image๋ณ ์์ ํ๋ Box์ ๊ฐ์์ ๋ํ ์ฐจ์ด
- ์ ๋ Label์ ๋ฐํ์ผ๋ก Stratifiedํ๊ฒ Train/valid Split ์งํ
Cow-Many | Cow-Medium | Cow-Little | Pig-Many | Pig-Medium | Pig-Little | |
---|---|---|---|---|---|---|
Train | 2739 | 1097 | 5886 | 2190 | 827 | 425 |
Valid | 674 | 259 | 1497 | 559 | 221 | 81 |
- Genetic Algorithm์ ํ์ฉํ HyperParameter Tuning (YOLOv5 default ์ ๊ณต)
- Runtime์ ์ ์ฝ(Colab Pro)์ผ๋ก ์ธํ, Mini Dataset(50% ์ฌ์ฉ) ์ ์ ๋ฐ HyperParameter Search ๊ฐ๋ณํ ์์ ์งํ
์์ธํ
meta = {'lr0': (1, 1e-5, 1e-1), # initial learning rate (SGD=1E-2, Adam=1E-3)
'lrf': (1, 0.01, 1.0), # final OneCycleLR learning rate (lr0 * lrf)
'momentum': (0.3, 0.6, 0.98), # SGD momentum/Adam beta1
}
with open(opt.hyp, errors='ignore') as f:
hyp = yaml.safe_load(f) # load hyps dict
if 'anchors' not in hyp: # anchors commented in hyp.yaml
hyp['anchors'] = 3
# Updateํ HyperParameter๋ง new_hyp์ ์ ์ฅ
new_hyp = {}
for k, v in hyp.items():
if k in meta.keys():
new_hyp[k] = v
opt.noval, opt.nosave, save_dir = True, True, Path(opt.save_dir) # only val/save final epoch
# ei = [isinstance(x, (int, float)) for x in hyp.values()] # evolvable indices
evolve_yaml, evolve_csv = save_dir / 'hyp_evolve.yaml', save_dir / 'evolve.csv'
if opt.bucket:
os.system(f'gsutil cp gs://{opt.bucket}/evolve.csv {save_dir}') # download evolve.csv if exists
for _ in range(opt.evolve): # generations to evolve
if evolve_csv.exists(): # if evolve.csv exists: select best hyps and mutate
# Select parent(s)
parent = 'single' # parent selection method: 'single' or 'weighted'
x = np.loadtxt(evolve_csv, ndmin=2, delimiter=',', skiprows=1)
n = min(5, len(x)) # number of previous results to consider
x = x[np.argsort(-fitness(x))][:n] # top n mutations
w = fitness(x) - fitness(x).min() + 1E-6 # weights (sum > 0)
if parent == 'single' or len(x) == 1:
# x = x[random.randint(0, n - 1)] # random selection
x = x[random.choices(range(n), weights=w)[0]] # weighted selection
elif parent == 'weighted':
x = (x * w.reshape(n, 1)).sum(0) / w.sum() # weighted combination
# Mutate
mp, s = 0.8, 0.2 # mutation probability, sigma
npr = np.random
npr.seed(int(time.time()))
# new_hyp์ ์๋ HyperParameter์ ๋ํด์๋ง meta๊ฐ ๋ถ๋ฌ์ค๊ธฐ
g = np.array([meta[k][0] for k in new_hyp.keys()]) # gains 0-1
ng = len(meta)
v = np.ones(ng)
while all(v == 1): # mutate until a change occurs (prevent duplicates)
v = (g * (npr.random(ng) < mp) * npr.randn(ng) * npr.random() * s + 1).clip(0.3, 3.0)
for i, k in enumerate(hyp.keys()): # plt.hist(v.ravel(), 300)
if k in new_hyp.keys(): # new_hyp์ ์กด์ฌํ๋ hyperParameter์ ๋ํด์๋ง Update
hyp[k] = float(x[i + 7] * v[i]) # mutate
# Constrain to limits
for k, v in meta.items():
hyp[k] = max(hyp[k], v[1]) # lower limit
hyp[k] = min(hyp[k], v[2]) # upper limit
hyp[k] = round(hyp[k], 5) # significant digits
# Train mutation
results = train(hyp.copy(), opt, device, callbacks)
- obj, box, cls์ ๋ํ HyperParameter์ ๋ฐ๋ฅธ ์ฑ๋ฅ ๋ณํํญ ์ฆ๊ฐ (NOTE: ํ์ต ํ๊ฒฝ์ ์ ์ฝ์ผ๋ก ์ธํด, ๊ฐ ์ฑ๋ฅ๋น๊ตํ ๋ง๋ค Epoch ์์ ์ฐจ์ด๊ฐ ์กด์ฌํ์ฌ ์ฑ๋ฅ์ ์ฐจ์ด๊ฐ ์๋ค. ์ฑ๋ฅ ๋น๊ต์๋ง ์ฐธ๊ณ ํ๋๋ก ํ์)
Default | Tuning | |
---|---|---|
obj_loss | 0.023 | 0.003 |
box_loss | 0.0095 | 0.0038 |
cls_loss | 0.00003 | 0.00001 |
Default | Tuning | |
---|---|---|
[email protected] | 0.9826 | 0.9824 |
[email protected]:.95 | 0.8924 | 0.9016 |
- Optimizer
Adam | AdamW | SGD | |
---|---|---|---|
[email protected] | 0.9635 | 0.9804 | 0.9848 |
[email protected]:.95 | 0.8302 | 0.8994 | 0.914 |
optimizer | lr_scheduler | lr0 | lrf | momentum | weight_decay | warmup_epochs | warmup_momentum | warmup_bias_lr | box | cls | cls_pw | obj | obj_pw | iou_t | anchor_t | fl_gamma | hsv_h | hsv_s | hsv_v | degrees | translate | scale | shear | perspective | flipud | fliplr | mosaic | mixup | copy_paste |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
SGD | linear | 0.009 | 0.08 | 0.94 | 0.001 | 0.11 | 0.77 | 0.0004 | 0.02 | 0.2 | 0.95 | 0.2 | 0.5 | 0.2 | 4.0 | 0.0 | 0.009 | 0.1 | 0.9 | 0.0 | 0.1 | 0.5 | 0.0 | 0.0 | 0.0095 | 0.1 | 1.0 | 0.0 | 0.0 |
Data ์ | Train | Valid |
---|---|---|
PIG | 3442 | 881 |
COW | 9722 | 2430 |
์์ธก ๊ฒฐ๊ณผ | Label ๊ฐ์ | Precision | Recall | [email protected] | [email protected]:.95 |
---|---|---|---|---|---|
PIG | 3291 | 0.984 | 0.991 | 0.993 | 0.928 |
COW | 3291 | 0.929 | 0.911 | 0.974 | 0.889 |
- ์์ ํ์ ๊ฐ์ด, Cow์ Data์ ์์ด PIG์ Data๋ณด๋ค ๋ ๋ง๋ค.
- YOLOv5 Pretrained Model์ ๊ฒฝ์ฐ COCO Dataset์์ Cow ์ด๋ฏธ์ง๋ฅผ ๋ณด์ ํ๊ณ ์๋ค.
- ์์ ๋ ๊ฐ์ง ์ด์ ์๋ ๋ถ๊ตฌํ๊ณ , Model์ด Cow Detection์์์ ์ด๋ ค์์ ๊ฒช๋๋ค.
- ์ ๋ฐ์ ์ผ๋ก Cow Dataset์์์ Bounding Box์ ๊ฐ์๊ฐ ์ ๋ค.
- Image๋ฅผ Plottingํ ๊ฒฐ๊ณผ, Cow Dataset์์์ Labeling์ด ์ ๋๋ก ๋์ด์์ง ์๋ค.
- FP์ ์ฆ๊ฐ๋ก ์ด์ด์ง ์ ์๋ค. (Labeling์ด ๋์ด์์ง ์์ง๋ง, Cow๋ผ๊ณ ์์ธก)
- ์ด๋ฌํ ๊ฒฐ๊ณผ๋ก๋ถํฐ, Silver Dataset์ ๋ง๋ค์ด ์ฌํ์ต์ํค๋๋ก ํ๋ค.
- ํ์ต๋ Model๋ก Cow Image์ ๋ํ์ฌ Bounding Box๋ฅผ ์์ธกํ๋ค.
- ์์ธก๋ ๊ฒฐ๊ณผ๋ฅผ ์ถ๊ฐํ์ต๋ฐ์ดํฐ๋ก ํ์ฉํ๋ค.
- YOLOv5m6 Pretrained with Full_Dataset(Train + Valid) (๊ธฐ์กด Dataset์ผ๋ก ํ์ตํ ๋ชจ๋ธ ํ์ฉ)
- ์ด 12151๊ฐ์ Cow Data์ ๋ํ์ฌ Detection ์งํ (IoU threshod: 0.7, Confidence threshold: 0.05)
- ์์ ์๊ฐํ์๋ฃ๋ก ๋ถํฐ, ๋ถ์๊ฐ(๋ณธ์ธ)์ ์์๋๋ก Bounding Box์ ๊ฐ์๊ฐ 4๊ฐ ์ด์์ธ Image๋ง ์ต์ข ์ ์
- ์ด 6628๊ฐ์ Cow์ ๋ํ Silver Dataset ์ถ๊ฐ
- Dataset: Train + Valid Dataset์ ํ์ต
- YOLOv5m6 Pretrained Model ํ์ฉ
- HyperParameter Tuning (์์ HyperParameter Tuning์์ ์์ฑํ ํ ์ฐธ๊ณ )
- Inference Tuning (IoU Threshold: 0.68, Confidence Threshold: 0.001)
Silver Dataset ๊ฒฐ๊ณผ๋น๊ต | [email protected] |
---|---|
์ต์ข ๋ชจ๋ธ(w/o Silver Dataset) | 0.98116 |
Plus Model(w Silver Dataset) | 0.97965 |
Full vs Split ๊ฒฐ๊ณผ๋น๊ต | [email protected] | [email protected]:.95 |
---|---|---|
Full(Train + Valid) | 0.9858 | 0.9271 |
Split(Train) | 0.9845 | 0.9215 |
- 1 Stage Model to 1 Stage Model
- ์ฑ๋ฅ์ด ๋์ 1 Stage Model์ ์ฐพ์ผ๋ ค๊ณ ํ์ผ๋ YOLOv5x6์ ์ ์ฉํ์์ ๋, [email protected]: 0.9821 / [email protected]:.95: 0.939๋ก ์ ์์ ํฐ ๊ฐ์ ์ด ์์์.
- ์ฆ, Teacher Model๋ก ํ์ฉํจ์ผ๋ก์ ์ป์ด์ง๋ ์ด๋์ด ์ ๋ค.
- Pretrained Model
- COCO Dataset์์์ Cow Image์ ํํ๋ ์ด๋ ํ์ง?
- Pig(COCO Dataset์ ์์)์ ๊ฒฝ์ฐ, ์ ๋ง์ท๊ธฐ ๋๋ฌธ์ PreTrained Weight์ ์ฌ์ฉํ์ง ์๊ณ Epoch์ ๋๋ ค์ ํ์ตํ๋ฉด ๋ ์ข์ ๊ฒฐ๊ณผ๋ก ์ด์ด์ง์ง ์์๊น?
- Silver Dataset
- Silver Dataset์ ๋ง๋๋ ๊ณผ์ ์ ์์ด์, IoU Threshold์ Confidence Threshold๋ฅผ ์ต์ ํํ๋ค๋ฉด ์ฑ๋ฅ๊ฐ์ ์ผ๋ก ์ด์ด์ง ์ ์์ง ์์๊น?
- Test Datsaet์์ ์ ์ด์ Labeling์ด ์ ๋๋ก ๋์ด์์ง ์๋๋ค๋ฉด, ์ด๋ฌํ ์ด์ ๋ก ์ธํด ํ์ฐ์ ์ผ๋ก ์ฑ๋ฅ๊ฐ์ ์ด ์ ์ด๋ฃจ์ด์ง ์ ์์ง ์์๊น?
- MultiLabelStratified SPlit
- Bounding Box์ Ratio์ Size์ ๋ฐ๋ฅธ ๋ถ๋ฅ๋ฅผ ํจ๊ป ์งํํด๋ณด๋ฉด ์ด๋จ๊น?
- ๋๋ถ์ด, Bounding Box์ ๊ฒฝ์ฐ, Image๊ฐ ๊ฐ์ง๊ณ ์๋ Box๋ง๋ค ๋ค๋ฅธ๋ฐ ์ด๋ ์ด๋ป๊ฒ MultiLabelํ๊ฒ Splitํ ์ ์์๊น?
- ํ์คํ ๋ฐฉ๋ฒ์ผ๋ก์ ๊ธฐ์กด Train Dataset์ Cow Image์ ๋ํ Labeling์ ์ง์ ํ๋ค๋ฉด ์ฑ๋ฅ ๊ฐ์ ์ผ๋ก ์ด์ด์ง์ง ์์์๊น?!
- MultiLabelStratified Split ์งํ์, ๊ฐ ์ด๋ฏธ์ง๊ฐ ๊ฐ์ง๋ Bounding Box์ Ratio, Size์ ๋ฐ๋ฅธ ๋ถ๋ฅ ๋ฐฉ๋ฒ ์ฐ๊ตฌ
- BackGround Image ๋ฃ๊ธฐ => ํ์งํ ๋ฌผ์ฒด๊ฐ ์๋ Image๋ฅผ ์ถ๊ฐํด์ค์ผ๋ก์ False Positive๋ฅผ ์ค์ผ ์ ์๋ค๊ณ ํ๋ค.
- ๊ณ ๋ํ๋ HyperParameter Tuning ๊ธฐ๋ฒ ์ ์ฉ (ex, Bayesian Algorithm)
- Train Dataset์ ๋ํ Silver Dataset์ ๋ง๋ค์ด ์ด๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ํ์ตํ ๊ฒฝ์ฐ ์ฑ๋ฅ ํฅ์์ผ๋ก ์ด์ด์ง๋์ง ์์๋ณด๊ธฐ (Train Gold + Train Silver)
- Object Detection์์ SGD๊ฐ AdamW๋ณด๋ค ์ข์ ๊ฒ์ ๊ฒฝํ์ ์ธ ๊ฒฐ๊ณผ์ธ์ง ํน์ ์ฐ๊ตฌ๊ฒฐ๊ณผ๊ฐ ์๋์ง ํ์ธํ๊ธฐ
- Pruning, Tensor Decomposition ์ ์ฉํด๋ณด๊ธฐ
- Object Detection Knowledge Distillation์ ๊ฒฝ์ฐ, 2 Stage to 1 Stage์ ๋ํ ๋ฐฉ๋ฒ๋ก ์ฐพ์๋ณด๊ธฐ