brunch

You can make anything
by writing

C.S.Lewis

by 라인하트 Oct 15. 2020

앤드류 응의 머신러닝 정리 (5-5): 옥타브 제어문

   온라인 강의 플랫폼 코세라의 창립자인 앤드류 응 (Andrew Ng) 교수는 인공지능 업계의 거장입니다. 그가 스탠퍼드 대학에서 머신 러닝 입문자에게 한 강의를 그대로 코세라 온라인 강의 (Coursera.org)에서 무료로 배울 수 있습니다. 이 강의는 머신러닝 입문자들의 필수코스입니다. 인공지능과 머신러닝을 혼자 공부하면서 자연스럽게 만나게 되는 강의입니다. 


Octave / Matlab Tutorial 

옥타브 / 매트랩 튜토리얼 


Control Statements: for, while, if statement (조건문과 제어문)



   In this video, I'd like to tell you how to write control statements for your Octave programs, so things like "for", "while" and "if" statements and also how to define and use functions. 


   이번 강의에서 옥타브 프로그램에서 'for', 'while' 및 'if' 문과 같은 제어문을 작성하는 방법과 함수를 정의하고 사용하는 방법에 대해 설명합니다.  



   Here's my Octave window. Let me first show you how to use a "for" loop. I'm going to start by setting v to be a 10 by 1 vector 0. Now, here's I write a "for" loop for I equals 1 to 10. That's for i equals 1 colon 10. And let's see, I'm going to set v of i equals two to the power of I, and finally end. The white space does not matter, so I am putting the spaces just to make it look nicely indented, but you know spacing doesn't matter.    But if I do this, then the result is that v gets set to, you know, two to the power one, two to the power two, and so on.


   여기 옥타브 창이 있습니다. 먼저 'for' 루프를 사용하는 법을 설명합니다. 'v = zeros(10,1)'명령어는 행렬 성분이 0인 10X1 벡터를 만듭니다. 다음과 같이 설정합니다. 


    for  i = 1:10,          % 루프 시작, i가 1부터 10까지 반복 

         v(i) = 2^i;         % 벡터 v의 각 성분의 값을 2^i 승으로 입력 

    end;                      % 루프 종료


   들여 쓰기는 'for' 루프를 보기 좋게 합니다. 공백은 중요하지 않습니다. 결과는 벡터 v의 성분이 바뀌었습니다. 2 = 2^1 승, 4 = 2^2승 등으로 표시합니다.



    So this is syntax for i equals one colon 10 that makes I loop through the values one through 10.  And by the way, you can also do this by setting your index equals one to 10, and so the index in the array from one to 10. You can also write for i equals index. And this is actually the same as if i equals one to 10. You can do, you know, display i and this would do the same thing. So, that is a "for" loop, if you are familiar with "break" and "continue", there's "break" and "continue" statements, you can also use those inside loops in octave. 


    'for i = 1:10' 명령어는 i가 1부터 10까지 반복하게 만드는 구문입니다. 반복하는 구문은 'index = 1:10' 명령어도  1부터 10까지 반복합니다. 즉, 'i = 1 : 10'는 'i = index'와 같은 것입니다. 'disp(i)' 명령어는 i의 값을 표시합니다. 


    index = 1:10            % index 변수는 1부터 10까지 순열을 가짐

    for  i = index,          % 루프 시작, i가 index의 순열이 10개 이므로 10번 반복 

         disp(i);               % i의 값을 표시  

    end;                        % 루프 종료


이것이 'for' 루프입니다. 'break'와 'continue' 명령어도 For 루프에서 사용할 수 있습니다. 



   But first let me show you how a 'while' loop works. So, here's my vector v. Let's write the while loop. i equals 1, while i is less than or equal to 5, let's set v(i) equals one hundred and increment I by one, end. So this says what? I starts off equal to one and then I'm going to set v(i) equals one hundred and increment I by one until I is, you know, greater than five. And as a result of that, whereas previously V was this powers of two vector. I've now taken the first five elements of my vector and overwritten them with this value one hundred. So that's a syntax for a while loop. 


   우선 'while' 루프의 동작 방법을 설명합니다. 여기 벡터 v가 있습니다. 'while' 루프를 작성합니다. 


   i = 1,                    

  while i <= 5,            % 루프 시작 i 가 5 보다 작을 때까지 

          v(i) = 100         % 베터 v의 성분의 값을 100으로 입력 

          i = i+1;             % 변수 i를 1 증가 

   end;                        %  루프 종료


   'while' 루프는 i의 값이 5보다 클 때까지 반복합니다. 결과는 벡터 v의 5 번째 성분까지 값이 100으로 바뀌었습니다. 전에는 2^i승의 값이었습니다. 이것이 'while' 루프입니다.



   Let's do another example. Y equals one while true and here I wanted to show you how to use a break statement. Let's say V I equals 999 and I equals i+1 if i equals 6 break and end. And this is also our first use of an if statement, so I hope the logic of this makes sense. Since i equals one and, you know, increment loop. While repeatedly set v(i) equals 1 and increment i by 1, and then when 1 i gets up to 6, do a break which breaks here although the while do and so, the effective is should be to take the first five elements of this vector V and set them to 999. And yes, indeed, we're taking V and overwritten the first five elements with 999. So, this is the syntax for "if" statements, and for "while" statement, and notice the end. We have two ends here. This ends here ends the if statement and the second end here ends the while statement. 


   다른 예를 봅시다. 'break' 명령어를 사용하는 법을 설명합니다. if 문을 여기에서 처음 사용합니다. 이 로직이 논리적이길 바랍니다. 


   i = 1;                          % 변수 i를 선언하고 1을 입력 

   while true,                % 조건이 참일 때까지 반복  

           v(i) = 999;          % 베터 v의 성분의 값을 999로 입력 

           i = i+1;               % 변수 i를 1씩 증가시킴

           if i == 6;             % 변수 i의 값이 6이면 참

               break;            % 루프를 탈출

           end;                   % if 문 루프 종료 

   end;                           % while 루프 종료


   while 루프는 v(i)의 값을 999로 변경한 후 i의 값을 1씩 증가시킵니다. while 루프를 탈출하는 조건은  i의 값이 6이 되었을 때 break 명령어를 실행합니다. 'break'명령어는 루프를 강제로 탈출시킵니다. 



   Now let me show you the more general syntax for how to use an if-else statement. So, let's see, V 1 is equal to 999, let's type V1 equals to 2 for this example. So, let me type if V 1 equals 1 display the value as one. Here's how you write an else statement, or rather here's an else if: V 1 equals 2. This is, if in case that's true in our example, display the value as 2, else display, the value is not one or two. Okay, so that's a if-else if-else statement it ends. And of course, here we've just set v 1 equals 2, so hopefully, yup, displays that the value is 2.


   if-else 문을 사용하는 일반적인 구문을 설명합니다. v(1)의 값은 999입니다. 이 예제를 위해 v(1)의 값을 2로 변경합니다.   


   v(1) = 2;                                                    % 벡터 v의 첫 번째 성분의 값을 2로 설정

   if v(1) == 1,                                               % 조건문 시작, v(1)의 값이 1이면 참이면 실행

         disp('The value is one');                    % 문자열을 출력

    elseif v(1) == 2,                                        % v(1)의 값이 2면 참이면 실행

          disp('The value is two;);                    % 문자열을 출력

     else                                                           % 위의 모든 조건이 거짓이면 실행

            disp('The value is not one or two'); % 문자열을 출력

    end;                                                           % 조건문 종료


      따라서, 위의 구문을 실행하면 옥타브 프로그램은 'The value is two'를 출력합니다. 


   And finally, I don't think I talked about this earlier, but if you ever need to exit Octave, you can type the exit command and you hit enter that will cause Octave to quit or the 'q'--quits command also works. 


   exit.       % 옥타브 프로그램 종료


마지막으로  강의 시작할 때 이야기를 안 한 것 같습니다. 'exit' 명령어는 옥타브 프로그램을 종료합니다. 



   Finally, let's talk about functions and how to define them and how to use them. Here's my desktop, and I have predefined a file or pre-saved on my desktop a file called "squarethisnumber.m". This is how you define functions in Octave. You create a file called, you know, with your function name and then ending in. m, and when Octave finds this file, it knows that this where it should look for the definition of the function "squarethisnumber.m". 

Let's open up this file. Notice that I'm using the Microsoft program Wordpad to open up this file. I just want to encourage you, if your using Microsoft Windows, to use Wordpad rather than Notepad to open up these files, if you have a different text editor that's fine too, but notepad sometimes messes up the spacing. If you only have Notepad, that should work too, that could work too, but if you have Wordpad as well, I would rather use that or some other text editor, if you have a different text editor for editing your functions. 


   마지막으로 함수를 정의하고 사용하는 방법에 대해 설명합니다. 여기 바탕화면이 있습니다. 사전에 "squareThisNumber.m" 파일을 바탕화면에 저장했습니다. 이것이 옥타브 프로그램에서 함수를 정의하는 방법입니다. 함수 이름과 확장자 '. m'으로 끝나는 파일명을 씁니다. 옥타브 프로그램이 이 파일을 찾아서 'squareThisNumber.m' 함수의 정의를 이해합니다. 파일을 엽니다. 마이크로소프트 프로그램 워드패드가 이 파일을 엽니다. 윈도즈 운영체제를 사용할 때 메모장 대신에 워드패드로 함수 파일을 열겠을 권장 합니다. 다른 텍스트 편집기도 좋지만 메모장이 때때로 공백을 엉망으로 만드는 경우가 있습니다. 

메모장에서도 작동할 수 있지만 함수 편집을 위해 워드패드 또는 다른 텍스트 편집기를 사용합니다.  


   So, here's how you define the function in Octave. Let me just zoom in a little bit. And this file has just three lines in it. The first line says function Y equals square root number of X, this tells Octave that I'm gonna return the value y, I'm gonna return one value and that the value is going to be saved in the variable Y and moreover, it tells Octave that this function has one argument, which is the argument X, and the way the function body is defined, if Y equals X squared. 


   여기에 옥타브 프로그램에서 함수를 정의하는 방법입니다. 조금 더 확대합니다. 이 파일은 3 줄만 있습니다. 첫 번째 줄은 함수 'y = x^2;'라고 적혀 있습니다. 이것은 옥타브 프로그램에게 y의 값을 반환하라는 명령입니다. 즉, 하나의 값 x를 주면 옥타브 프로그램은 그 값을 y에 저장합니다. 이 함수는 변수 x이고 'y=x^2' 함수가 정의되었다고 옥타브 프로그램에 알려줍니다. (함수 파일은 공백과 대소문자가 정확히 구분됩니다.)



   So, let's try to call this function "square", this number 5, and this actually isn't going to work, and Octave says square this number it's undefined. That's because Octave doesn't know where to find this file.. So as usual, let's use PWD, or not in my directory,


   square 함수라고 부릅시다. 'squareThisNumber(5)' 명령을 입력하면 제대로 실행되지 않습니다. 옥타브 프로그램은 함수가 정의되지 않았다고 말합니다. 원인은 옥타브 프로그램이 이 함수 파일의 위치를 모르기 때문입니다. 'pwd' 명령어는 현재의 디렉터리 위치합니다. 




   So let's see this c:\users\ang\desktop. That's where my desktop is. Oops, a little typo there. Users ANG desktop and if I now type square root number 5, it returns the answer 25. 


   함수 파일이 있는 곳으로 디렉터리를 이동시킵니다.  'squareThisNumber(5)' 명령어는 새로 만든 squareThisNumber.m 파일에 정의된 함수 식에 따라 값을 돌려줍니다. 여기서는 25입니다. 



As kind of an advanced feature, this is only for those of you that know what the term search path means. But so if you want to modify the Octave search path and you could, you just think of this next part as advanced or optional material. Only for those who are either familiar with the concepts of search paths and permit languages, but you can use the term addpath, safety colon, slash users/ANG/desktop to add that directory to the Octave search path so that even if you know, go to some other directory I can still, Octave still knows to look in the users ANG desktop directory for functions so that even though I'm in a different directory now, it still knows where to find the squareThisNumber function. Okay? But if you're not familiar with the concept of search path, don't worry about it. Just make sure as you use the 'cd' command to go to the directory of your function before you run it and that actually works just fine. 


  일종의 고급 기능으로 '검색 경로'라는 것이 있습니다. 옥타브 검색 경로에 대한 수정은 고급이나 옵션 강의로 다음에 알려드릴 것입니다. 검색 경로는 옥타브 프로그램이 언제든지 명령어나 함수를 실행할 떄 참조하는 디렉토리입니다.   


   addpath ('C;\Users\ang\Desktop') % 옥타브 프로그램이 검색 경로를 추가 지정 


   따라서, 디렉터리를 변경합니다. 옥타브 프로그램은 함수를 검색할 때 추가한 검색 경로를 살펴봅니다. 지금은 다른 디렉터리에 있지만 squareThisNumber 함수를 호출하여 같은 값을 얻습니다. 그러나, 검색 경로의 개념이 익숙하지 않더라도 걱정할 필요 없습니다. 처음 하던 대로 함수를 실행하기 전에 'cd'명령으로 함수가 있는 디렉터리에 이동했는 지를 확인합니다.



   One concept that Octave has that many other programming languages don't is that it can also let you define functions that return multiple values or multiple arguments. So here's an example of that. Define the function called squareAndCubeThisNumber(x) and what this says is this function returns 2 values, y1 and y2. When I set down, this follows, y1 is squared, y2 is execute. And what this does is this really returns 2 numbers. So, some of you depending on what programming language you use, if you're familiar with, you know, CC++ your offer. Often, we think of the function as return in just one value. But just so the syntax in Octave 

that should return multiple values. 


   옥타브 프로그램은 다른 많은 프로그래밍 언어에는 없는 개념들이 있습니다. 그중에 하나는 여러 개의 값 또는 여러 변수를 반환하는 함수를 정의할 수 있다는 것입니다. 여기에 예제가 있습니다. 

'squareAndCubeThisNumber(x)' 함수를 정의합니다. 이 함수는 y1과 y2, 2 개의 값을 반환합니다.' y1 = x^2' 함수이고 'y2 = x^3' 함수입니다. 이 함수는 실제로 2 개의 숫자를 반환합니다. 따라서, 어떤 프로그래밍 언어를 사용하는지에 따라서 다르지만, C 나 C++ 에서는 비슷한 개념을 제공합니다. 함수는 단지 하나의 값만이 아니라 여러개의 값을 반환할 수 있습니다.  



   Now back in the Octave window. If I type, you know, a, b equals square and cube this number 5 then a is now equal to 25 and b is equal to the cube of 5 equal to 125. So, this is often convenient if you needed to define a function that returns multiple values. 


   [a, b] = squareAndCubeThisNumber(5)

                      % 함수의 연산 결과가 두 개일 때 변수 a 및 b 로 반환


   여기서, a는 5의 제곱인 25이고, b는 5의 세제곱인 125입니다. 따라서, 여러 개의 값을 반환해야 하는 경우에 편리하게 사용할 수 있습니다. 




   Finally, I'm going to show you just one more sophisticated example of a function. Let's say I have a data set that looks like this, with data points at (1, 1), (2, 2), (3, 3). And what I'd like to do is to define an octave function to compute the cost function J of theta for different values of theta. 


   마지막으로 좀 더 복잡한 함수의 예제를 봅시다. (1,1), (2,2), (3,3)에 해당하는 데이터가 도식화되었다고 가정합시다. 여기서 비용 함수 J(θ)의 값을 구합시다. 옥타브 프로그램에 함수 정의를 활용해 보겠습니다. 



   First let's put the data into octave. So I set my design matrix to be 1,1,1,2,1,3. So, this is my design matrix X with x0, the first column being the said term and the second term being you know, my the x-values of my three training examples. And let me set y to be 1-2-3 as follows, which were the y axis values. So let's say theta is equal to 0 semicolon 1. 


   우선 데이터를 옥타브 프로그램에 입력합니다. 가설 함수 hθ(x) = θ0x0 + θx1 이고, 디자인 행렬 X = [1,1 ; 1,2; 1,3]를 설정합니다. 첫 번째 열은 x0의 값이고 두 번째 열은 x1의 값으로 3 개의 훈련용 데이터 셋의 x의 값입니다. x의 변화에 따른 실제 값 벡터 y = [1; 2; 3]입니다. 또 다른 벡터 theta = [0;1]입니다. 



   Here at my desktop, I've predefined does cost function j and if I bring up the definition of that function it looks as follows. So function j equals cost function j equals x y theta, some commons, specifying the inputs and then vary few steps set m to be the number training examples thus the number of rows in x. Compute the predictions, predictions equals x times theta and so this is a common that's wrapped around, so this is probably the preceding comment line. Computer script errors by, you know, taking the difference between your predictions and the y values and taking the element of y squaring and then finally computing the cost function J. And Octave knows that J is a value I want to return because J appeared here in the function definition.  Feel free by the way to pause this video if you want to look at this function definition for. longer and kind of make sure that you understand the different steps. 


   여기 바탕화면이 있습니다. 사전에 이미 비용 함수 J에 대한 함수 정의를 하였습니다. Predictions은 행렬 X와 세타의 값을 곱합니다.  sqrErrors는 예측값과 실제값의 차이를 구하고 이 값을 제곱합니다. 


function J = costFunctionJ(X, y, theta)  


% X는 학습 데이터 셋 중 피처만을 포함하는 디자인 행렬

% y는 학습 데이터 셋 중 x에 따른 실제 예측 (레이블)


m = size(X,1);                               % m은 훈련용 예제의 개수 (행렬 X의 행의 개수)

Predictions = X * theta;               % predictions는 디자인 행렬과 세타 벡터의 곱 

sqrErrors = (Predictions - y).^2;  % 오차 행렬의 각 성분을 제곱


J = 1/(2*m) * sum(sqrErrors);   % 비용 함수 식


   옥타브 프로그램은 비용 함수 J 가 반환해야 할 값이라는 것을 알고 있습니다. 함수 정의를 자세히 보고 싶다면 동영상을 멈추셔도 괜찮습니다. 



   But when I run it in Octave, I run j equals cost function j x y theta. It computes. Oops, made a typo there. It should have been capital X. It computes J equals 0 because if my data set was, you know, 123, 123 then setting, theta 0 equals 0, theta 1 equals 1, this gives me exactly the 45-degree line that fits my data set perfectly. 


   옥타브 프로그램에서 'j = costFuctionJ(X, y, theta)'를 실행합니다. 오타가 났습니다. 대문자 X와 소문자 x를 혼동했습니다. 훈련용 데이터 셋은 (1,1), (2,2), (3,3)이고 가설 함수 hθ(x) = θ0x0 + θx1입니다.  θ0 =0,  θ1= 1이면 h(x) = x1입니다. 이것은 훈련용 데이터셋에 정확히 일치하는 정확히 45도 각도의 직선입니다. 

   


   Whereas in contrast if I set theta equals say 0, 0, then this hypothesis is predicting zeroes on everything the same, theta 0 equals 0, theta 1 equals 0 and I compute the cost function 

then it's 2.333 and that's actually equal to 1 squared, which is my squared error on the first example, plus 2 squared, plus 3 squared and then divided by 2m, which is 2 times number of training examples, which is indeed 2.33 and so, that sanity checks that this function here is, you know, computing the correct cost function and these are the couple examples we tried out on our simple training example.  And so that sanity tracks that the cost function J, as defined here, that it is indeed, you know, seeming to compute the correct cost function, at least on our simple training set that we had here with X and Y being this simple training example that we solved. 



   반면에 가설 hθ(x) = θ0x0 + θ1x1 일 때 파라미터 θ0 =0, θ1= 0 으로 설정하고 비용함수 J의 값을 구합니다. 


   theta = [0;0]

   j = costFunctionJ(X, y, theta);   % ans = 2.3333


   가설은 수평축과 동일합니다. 오차는 (예측값 - 실제값)^2 이므로 비용 함수 J를 수동으로 계산하면 (1^2 + 2^2+3^2)/ (2*3) = 2.3333 입니다. 타당성 검사(sanity check)는 비용 함수가 올바르게 계산했는 지를 검산합니다. 여기서 처럼 간단한 학습 데이터 셋의 값으로 확인할 수 있습니다. 


   So, now you know how to right control statements like for loops, while loops and if statements in octave as well as how to define and use functions. In the next video, I'm going to just very quickly step you through the logistics of working on and submitting problem sets for this class and how to use our submission system. And finally, after that, in the final octave tutorial video, I wanna tell you about vectorization, which is an idea for how to make your octave programs run much fast.


   지금까지 옥타브 프로그램의 for 루프, while 루프, if 문과 같은 제어문을 사용하는 법과 함수를 정의하고 사용하는 방법을 배웠습니다. 다음 강의에서는 수업에 대한 문제를 이해하고 제출하는 과정과 시스템 사용법을 빠르게 설명합니다.  마지막으로 옥타브 튜토리얼 강의에서 백터화에 대해 설명합니다. 이것이 프로그램을 훨씬 빠르게 실행하는 방법입니다. 



앤드류 응의 동영상 강의 




옥타브 프로그램으로 따라 할 때 필요한 파일들



정리하며 - 제어문


1) For 

     순차적으로 마지막까지 루프가 돌아갑니다.     


     v = zeros(10,1)      % 행렬 성분이 0인 10X1 벡터 생성 

    for  i = 1:10,          % 루프 시작, i가 1부터 10까지 반복 

         v(i) = 2^i;         % 벡터 v의 각 성분의 값을 2^i 승으로 입력 

    end;                      % 루프 종료


    index = 1:10            % index 변수는 1부터 10까지 순열을 가짐

    for  i = index,          % 루프 시작, i가 index의 순열이 10개 이므로 10번 반복 

         disp(i);               % i의 값을 표시  

    end;                        % 루프 종료



2) while

    특정 조건에 부합할 때까지 루프가 돌아갑니다. IF 문과 FOR 문이 합쳐진 형태 


   i = 1,                    

  while i <= 5,            % 루프 시작 i 가 5 보다 작을 때까지 

          v(i) = 100         % 베터 v의 성분의 값을 100으로 입력 

          i = i+1;             % 변수 i를 1 증가 

   end;                        %  루프 종료




3) if

    조건에 따라 명령을 수행


   v(1) = 2;                                                    % 벡터 v의 첫 번째 성분의 값을 2로 설정

   if v(1) == 1,                                               % 조건문 시작, v(1)의 값이 1이면 참이면 실행

         disp('The value is one');                    % 문자열을 출력

    elseif v(1) == 2,                                        % v(1)의 값이 2면 참이면 실행

          disp('The value is two;);                    % 문자열을 출력

    else                                                            % 위의 모든 조건이 거짓이면 실행

            disp('The value is not one or two'); % 문자열을 출력

    end;                                                           % 조건문 종료



4) while과 if 문의 조합


   i = 1;                          % 변수 i는 1입니다

   while true,                % 조건이 참일 때까지 반복  

           v(i) = 999;          % 베터 v의 성분의 값을 999로 입력 

           i = i+1;               % 변수 i를 1씩 증가시킴

           if i == 6;             % 변수 i의 값이 6이면 참

               break;            % 루프를 탈출

           end;                   % if 문 루프 종료 

   end;                           % while 루프 종료



5) 옥타브 프로그램 제어

    exit                           % 옥타브 프로그램을 종료

    addpath ('C;\Users\ang\Desktop')    % 함수를 실행하기 위한 검색 경로 지정 

   break                        % 루프를 강제 탈출 



6) 사용자 정의 함수 만들기

    윈도즈 운영체제에서 워드패드를 사용하는 것이 좋습니다. 노트패드는 가끔씩 문제를 일으킵니다. 파일의 확장자는. m으로 합니다. 파일을 만드는 방법은 다음과 같습니다. 


function J = costFunctionJ(X, y, theta)  


% X는 훈련용 데이터 셋을 포함하는 디자인 행렬이다. 

% y는 훈련용 데이터 셋에서 x에 따른 실제 결괏값이다(클래스 라벨)


m = size(X,1);                  % m은 훈련용 예제의 개수 (행렬 X의 행의 개수)

Predictions = X * theta;   % predictions는 디자인 행렬과 세타 벡터의 곱 

sqrErrors = (Predictions - y).^2;  % 오차 행렬의 각 성분을 제곱


J = 1/(2*m) * sum(sqrErrors);   % 비용 함수 식

매거진의 이전글 앤드류 응의 머신러닝 정리 (5-4):데이터 시각화
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari