2020-iuc-sw-skku / LSC-Systems

산학협력프로젝트: 머신러닝 기반 Wafer Map Defect Pattern Identification
8 stars 3 forks source link

Angle-based Features #7

Open illuminoplanet opened 4 years ago

illuminoplanet commented 4 years ago

Divide the wafer map in radial shape then get the density of each sector. Following features will be extracted:

  1. Density of each sector
  2. Proportion of failure points in each sector comparing to whole
  3. Density of each sector sorted
  4. Proportion of failure points in each sector comparing to whole sorted
HyeonjinChoi commented 4 years ago
import os
import numpy as np 
import pandas as pd
import math
import matplotlib.pyplot as plt
%matplotlib inline 

data_test = pd.read_pickle("/content/drive/My Drive/Data set/WM/sample.pkl")

def extract_angle(x):

  #배열의 중앙은 원점이고 x축 양의 방향이 시초선일 때, (x, y) 가 이루는 각의 degree 값을 구한다
  calculate_angle = lambda cen_x, cen_y, x, y : (np.degrees(np.arctan([(y-cen_y)/(x-cen_x)])))//10*10 if (x - cen_x > 0) and (y - cen_y > 0) \
  else ((180-np.degrees(np.arctan([(y-cen_y)/(cen_x-x)])))//10*10 if (x - cen_x < 0) and (y - cen_y > 0) 
  else ((180+np.degrees(np.arctan([(cen_y-y)/(cen_x-x)])))//10*10 if (x - cen_x < 0) and (y - cen_y < 0) 
  else ((360-np.degrees(np.arctan([(cen_y-y)/(x-cen_x)])))//10*10 if (x - cen_x > 0) and (y - cen_y < 0)
  else (0 if (x - cen_x > 0) and (y - cen_y == 0)
  else (90 if (x - cen_x == 0) and (y - cen_y > 0)
  else (180 if (x - cen_x < 0) and (y - cen_y == 0)
  else (270 if (x - cen_x == 0) and (y - cen_y < 0)
  else 0)))))))

  #원을 36등분하여 10도 간격으로 배열을 생성
  defect = np.zeros(36)
  whole = np.zeros(36)

  angle = {}
  feature_name = lambda x: f"angle_{str(x*10)}º"

  for i in range(0, len(x)):
    data = x['wafer_map'].to_numpy()[i]

    #원점은 배열의 중앙
    rows = np.size(data, axis = 0)
    cols = np.size(data, axis = 1)
    center_y = round(rows/2)
    center_x = round(cols/2)

    #값이 1, 2인 die 정보 파악
    for j in range(0, cols):
      for k in range(0, rows):
        if data[k][j] != 0:
          whole[int(calculate_angle(center_x, center_y, j, k) // 10)] += 1
          if data[k][j] == 2:
            defect[int(calculate_angle(center_x, center_y, j, k) // 10)] += 1

    #각도별 밀도
    sector = {}

    for j in range(0, 36):
      if whole[j] != 0:
        sector[feature_name(j)] = 100 * defect[j] / whole[j]

    angle[i] = sector

  return np.swapaxes(pd.DataFrame(angle), 0, 1)
HyeonjinChoi commented 4 years ago

ex) image image

illuminoplanet commented 4 years ago

Refactored

@HyeonjinChoi

def extract_angle(x):

  #배열의 중앙은 원점이고 x축 양의 방향이 시초선일 때, (x, y) 가 이루는 각의 degree 값을 구한다
  calculate_coor = lambda x: np.argwhere(x)-(np.array(x.shape)//2)
  calculate_angle = lambda coor: np.rad2deg(np.arctan2(coor[:, 0], coor[:, 1]))+180

  #원을 36등분하여 10도 간격으로 배열을 생성
  coor_defect = calculate_coor(x==2)
  angle_defect = calculate_angle(coor_defect)
  defect, _ = np.histogram(angle_defect, bins=36, range=(0, 360))

  coor_whole = calculate_coor(x!=0)
  angle_whole = calculate_angle(coor_whole)
  whole, _ = np.histogram(angle_whole, bins=36, range=(0, 360))

  angular_density = defect/whole

  angle = {}
  feature_name = lambda x: f"angle_{str(x*10)}º"

  for i in range(angular_density.size):
    angle[feature_name(i)] = angular_density[i]

  return pd.Series(angle)

if __name__ == "__main__":

  DATA_PATH = PATH
  data = pd.read_pickle(os.path.join(DATA_PATH, 'sample.pkl'))

  angle_based = data['wafer_map'].apply(extract_angle)

밀도를 0~1로 계산했고 반올림 생략때문에 값이 조금씩 다를 수 있습니다. 또 main 함수에서 데이터 프레임에 apply를 하는만큼 한번에 하나의 샘플만을 계산하도록 구현하였습니다.

HyeonjinChoi commented 4 years ago
def extract_angle(x):

  #배열의 중앙은 원점이고 x축 양의 방향이 시초선일 때, (x, y) 가 이루는 각의 degree 값을 구한다
  calculate_coor = lambda x: np.argwhere(x)-(np.array(x.shape)//2)
  calculate_angle = lambda coor: np.rad2deg(np.arctan2(coor[:, 0], coor[:, 1]))+180

  #원을 36등분하여 10도 간격으로 배열을 생성
  coor_defect = calculate_coor(x==2)
  angle_defect = calculate_angle(coor_defect)
  defect, _ = np.histogram(angle_defect, bins=36, range=(0, 360))

  coor_whole = calculate_coor(x!=0)
  angle_whole = calculate_angle(coor_whole)
  whole, _ = np.histogram(angle_whole, bins=36, range=(0, 360))

  angular_density = defect/whole
  density_proportion = defect/len(coor_defect)

  angle = {}
  proportion = {}
  feature_name_1 = lambda x: f"angle_{str(x*10)}º"
  feature_name_2 = lambda x: f"proportion_{str(x*10)}º"

  for i in range(angular_density.size):
    angle[feature_name_1(i)] = angular_density[i]

  for i in range(angular_density.size):
    proportion[feature_name_2(i)] = density_proportion[i]

  a = sorted(angle.items(), key=lambda x: x[1], reverse=True)
  b = sorted(proportion.items(), key=lambda x: x[1], reverse=True)

  angle = dict(a)
  proportion = dict(b)

  angle.update(proportion)

  return pd.Series(angle)

각 섹터별 결함 밀도 + 각 섹터별 전체 대비 결함 비율 (내림차순)

HyeonjinChoi commented 4 years ago

ex) image image

HyeonjinChoi commented 4 years ago

성능 평가

<왼쪽 : density + distance + geometry + radon // 오른쪽 : density + distance + geometry + radon + angle> ANN image

GBM image

LR image

RF image

HyeonjinChoi commented 4 years ago

정확도 평균

image

각도별 정확도 평균 image

dotoleeoak commented 4 years ago

보류