Silverback9

#야생으로

Creative Coding 독학 제343일 2025년03월05일(수) 보충 2025년03월08일(토)에 함

네~~^^*

새로운 한 주, 새로운 스케쥴에 적응하느라…새벽과 밤시간 활용 습관이 흐트러졌어요…

이제, 새로운 한 주에 잘 적응하고, 맞이하는 휴일입니다.

수요일 고민했던 문제를 해결하였습니다~^^* processing에서는 Class 안의 함수를 같은 이름 다른 parameter 의 경우 덮어쓰기 기능이 있는 것 같은데요…p5.js에는 작동이 안되는 것 같았어요….

그래서…덮어쓰기 기능 대신, 함수를 호출할 때 parameter 특성을 통일하고, 그대신, 각각의 경우에, parameter를 다르게 입력하도록 해 보았어요….

설명하기가 좀 그런데요…

일단 작동이 잘 되는 것을 확인한 p5.js 코드를 함께 살펴보시죠~^^*

이제, threshold 기준선의 slope 기울기와 intercept 절편을 자유롭게 지정하여 기준선의 각도와 위치를 바꾸고, 그에 따라 변화된 threshold에 대해 perceptron을 훈련시킬 수 있습니다~~^^*

let slope = 0.3;
let intercept = 0.2;

function f(x) {
   return slope * x + intercept;
}
//기울기 slope의 값과 
//절편 intercept의 값을 
//다양하게 바꾸면
//threshhold 기준선을 다양하게 적용할 수 있을 것 같습니다~^^*

class Point{

  constructor(x, y) {
    this.x = x; 
    this.y = y;
    this.label;
 
    if(this.y > f(this.x)) {
      this.label = 1;
    } else 
     {this.label = -1;
    }
    //f(x) = slope * x + intercept
    //현재 정의된 f(x)는 0.3*X+0.2입니다. 
    //f(x)를 threshold 기준선으로 하여, 
    //this.y > f(x) (기준선 위의 경우): 1
    //this.y =< f(x) (기준선 아래의 경우): -1
    //판별값 label을 정하겠습니다. 
  }  
  
  pixelX() {
    return map(this.x, -1, 1, 0, width);
  }
  //왼쪽 끝 -1 오른쪽 끝 1 값을 가지도록 하겠습니다. 
  
  pixelY() {
    return map(this.y, -1, 1, height, 0);
  }
  //위쪽 끝 1 아래쪽 끝 -1 값을 가지도록 하겠습니다. 
  
  show() {
  
    stroke(0);
    if (this.label == 1) {
      fill(255);
    } else{
      fill(0);
    }
    //판별값이 1인 경우 흰색으로 칠합니다.
    //판별값이 -1인 경우 검은색으로 칠합니다.
    
    let px = this.pixelX();
    let py = this.pixelY();
    
    ellipse(px, py, 16, 16);
    //데카르트 위치좌표(px, py)에 동그라미를 그리겠습니다~^^*
  }  
}
let perceptron;
let points = [];

let trainingIndex = 0;



function setup() {
  createCanvas(400, 400);
  
  perceptron = new Perceptron(2, 0.0001);
  
  for (i = 0; i < 100; i++) {
    let x = random(-1,1);
    let y = random(-1,1);
    points[i] = new Point(x, y);
  }
  //클래스 Point를 생성하기 전에, 
  //x축 위치좌표값과 y축 위치좌표값을
  //-1과 1 사이의 무작위 수로 생성한 후  
  //클래스 Point를 생성할 때 parameter로 전달하겠습니다.
}

function draw() {
  background(150);
  stroke(0);
  
  let x1 = -1;
  let y1 = f(-1);
  let x2 = 1;
  let y2 = f(1);
  
  //함수 f()를 호출하며 x1, x2 값을 parameter로 전달하겠습니다. 
  //함수 f()가 return하는 값을 y1, y2에 저장하겠습니다. 
  //y1 = slope * x1 + intercept
  //y2 = slppe * x2 + intercept
  //값을 가지고 있을 것입니다. 
  
  let p1 = new Point(x1, y1);
  let p2 = new Point(x2, y2);
  line(p1.pixelX(), p1.pixelY(), p2.pixelX(), p2.pixelY());
  //threshold 기준선을 그립니다. 
   
  for(i = 0; i < points.length; i++) {
    points[i].show();
  }
  
  for(i = 0; i < points.length; i++) {
    let inputs = [points[i].x, points[i].y];
    let target = points[i].label;
    let guess = perceptron.feedforward(inputs);
  
    if (guess == target) {
      fill(0, 255, 0);
    } else {
      fill(255, 0, 0);
    }  
    noStroke();
    ellipse(points[i].pixelX(), points[i].pixelY(), 8, 8); 
    //데카르트 위치좌표에 동그라미를 그리겠습니다. 
    //perceptron이 추측한 값이 known answer인 points.label과 같으면 초록색 다르면 빨간색 동그라미를 point 위에 그리겠습니다.  
   
    
  }
  
   let training = new Point();
   training  = points[trainingIndex];
   
   let inputs = [training.x, training.y];
   let target = training.label;
   
   perceptron.train(inputs,target);
   
   trainingIndex++;
   
   if(trainingIndex == points.length){
     trainingIndex = 0;
   }
  //배열 points의 모든 구성원을
  //0번째 구성원 points[0]부터 마지막 번째 구성원 points[points.length -1]까지에 대해 
  //차례로 개별적으로
  //perceptron을 훈련시키겠습니다.
  //모든 구성원에 대한 순차적 개별적 훈련이 다 되면(trainingIndex == points.length)
  //처음부터 다시 개별적 순차적 훈련을 하겠습니다. 
}  

그럼 우리 새로운 threshold 기준선 f(x) = 0.3 * x + 0.2에 대해 perceptron이 훈련되는 모습을 관찰해 볼까요~^^* 시간이 지나면서 서서히 모든 Point들 내부 색깔이 초록색으로 바뀔 것 같습니다~^^*.

우리 threshold 기준선을 또 바꾸어 훈련시켜 볼까요~^^* f(x) = -0.7 * x + 0.7로 바꾸어 보겠습니다~^^* perceptron 훈련이 잘 되나요?

네~~^^* threshold 기준선을 자유롭게 바꾸어서 perceptron을 훈련시키는 프로그램을 저와 함께 만들어 주셔서 감사합니다~^^*

며칠 공부도 못하고 있었는데요. 다시 공부하며 수요일의 문제를 잘 해결할 수 있도록 기다려 주셔서 감사합니다!

새로운 스케쥴 잘 적응하며, 매일 코딩 공부를 다시 잘 이어나가겠습니다!

함께 해 주실거지요~~^^*

네~^^* 좋아요~^^* 고마워요~^^*

넵!!! 새로운 스케쥴도 즐겨버리는 멋진 survivor가 됩시다!!!

네~^^* 꿈은 이루어 집니다~^^*

댓글 남기기