관리자

CNN(Convolutional Nerual Network) : 합성곱 신경망

앞서 본 classic한 NN(fully connected netowrk)에서는 한 뉴런이 전 layer의 모든 neuron과 연결되어있다.

CNN에서는 이전 layer의 일부 neuron과만 연결되어 있는 부분이 존재한다.

이런 연산 과정은 filterpooling을 통해 구현하는데, 이것은 조금 더 뒤에서 확인하자.

 

CNN은 이미지, 영상, 음성처럼 데이터량이 많고, locality가 있는 분야에 주로 사용된다.

이러한 분야의 데이터는 classic한 NN을 이용할 경우 몇 가지 문제가 생긴다.

1) 연산량이 너무 많다

2) 데이터가 조금만 변경되어도 다른 것으로 인식해버린다.

    이미지를 예를 들어 생각해보자. A가 쓰인 이미지가 있을 때,  글자의 크기가 커져도, 글자가 회전되어도 모두 A로 인식되어야한다. 

    fully connected network에서는 모든 경우에 대해 데이터를 만들고 학습을 해야한다. 따라서 많은 데이터가 필요하고, 그에 따라 연산량과 학습시간이 증가했다.

 

 

CNN 구조. 연산 과정

이런 한계를 극복하기 위해, 데이터에서 먼저 특징을 추출하고

그 다음에 fully connnected layer를 이용한다.

https://blog.naver.com/laonple/220608018546 참고

 

https://adeshpande3.github.io/A-Beginner%27s-Guide-To-Understanding-Convolutional-Neural-Networks/

 

https://deepestdocs.readthedocs.io/en/latest/004_deep_learning_part_2/0043/

 

 

Convolution(filter)

출처 :  https://adeshpande3.github.io/A-Beginner%27s-Guide-To-Understanding-Convolutional-Neural-Networks/ ("Neural Networks and Deep Learning" by Michael Nielsen)
http://taewan.kim/post/cnn/
http://taewan.kim/post/cnn/
http://taewan.kim/post/cnn/

Pooling

https://adeshpande3.github.io/A-Beginner%27s-Guide-To-Understanding-Convolutional-Neural-Networks/

 

 

출처 및 참고 자료 :

http://taewan.kim/post/cnn/

https://adeshpande3.github.io/A-Beginner%27s-Guide-To-Understanding-Convolutional-Neural-Networks/

https://deepestdocs.readthedocs.io/en/latest/004_deep_learning_part_2/0043/

https://blog.naver.com/laonple/220608018546

뒷 부분의 output은 벡터일수도, 스칼라 값일 수도 있다.
대체로 이런 형태를 갖는 것일뿐, 목적에 따라 다양한 형태를 갖는다.

앞서 neural network에서 학습의 목표는 알맞은 weight를 찾는 것이라 했다.

이번에는 어떻게 알맞은 weight를 계산하는지 다루려한다.

최적의 weight는

1) 계산

2) 실제 값과의 차이만큼 조정

하는 것을 반복함으로써 계산한다.

 

어떻게 계산하는지 - feedforward

실제 값과의 차이만큼 조정 - loss function, backpropagation

 

이렇게 나눌 수 있다.

 

 

Feedforward

3-2. neural network의 구조, activation function에서

neuron 단위에서 연산을 어떻게 이루어지는지 살펴보았다.

이 연산 과정은 input에서 output방향으로, 모든 neuron과 layer에서 일어난다. 이것을 feedfoward라고 한다.

input으로부터 output 방향으로 forward하게 이루어지기 때문에 이런 이름이 붙었다.

 

input이 vector이고 vector연산은 행렬을 통해 쉽게 계산할 수 있다.

따라서 feedforward연산은 다음과 같이 표현할 수 있다.

 

 

출처: https://www.jeremyjordan.me/intro-to-neural-networks/

 

Loss Function / cost function : 손실 함수

loss와 cost는 없어지는 것, 잃는 것, 손실이라는 비슷한 의미를 갖는다.
여기서 잃는다는 것은 정답과의 차이를 의미한다.

 

supervised learning은 정답을 아는 상태에서 학습하는 것이라 했다.

x를 넣어서 계산하면 y값을 얻는다.

이 y 값과 실제 정답인 t의 차이의 합을 loss/cost 라고 한다.

흔히 쓰이는 loss function에는  평균오차제곱(MSE : Mean Squared Errror), cross entropy(교차 엔트로피)가 있다.

 

 

평균 오차 제곱은 아래와 같다.

cross entropy는 아래와 같다.

unsupervised learning에서는 조금 다른 개념을 사용한다.

unsupervised learning은 정답이 없다. 따라서 알고리즘에 따라 loss function을 다르게 정의한다.

 

abstact class vs. trait

abstract class

abstract class는 class의 template으로,
implementation은 하지 않고 
어떤 variable과 method가 필요한지만 정의한다.

어떤 abstract class를 상속하는 class를 정의할 때는
abstract class에 명시된 값과 함수들을 모두 implement(작성)해야한다.

 

trait

trait도 abstract class와 동일한 개념이다.
하지만 abstract class는 1개의 class만 상속할 수 있는 반면,
trait는 여러 class를 상속할 수 있다.

따라서 가급적이면 trait을 쓰는 것이 좋다.

abstract class를 사용해야하는 경우

1) constructor argument를 요구하는 base class를 만드는 경우
2) java에서 이용할 코드인 경우

1) 의 예시
trait Animal(name: String)
//compile error


case class

scala에는 case class라는 재미있는 class가 있다.
switch case 문처럼 scala 에서는
match case문이 존재한다.
특이한 것은 match case와 case class문을 조합하면,
object의 class에 대해서도 switch case를 할 수 있다.

예를 들어보자.
어떤 수학 수식은 숫자(number)와 연산자(operator)로 구성된다.
숫자와 연산자를 포함하는 Expression이라는 abstract class(trait)을 정의하면,
수식을 Expression의 List로 나타낼 수 있다.

triat Expression
case class Number(val: Int) extends Expression {...}
case class Operator(name: String) extends Expression {...}
// Expression을 상속하는 class Number, class Operator 정의


object O {

    def expr(x : Base) = x match {
        case Number(val: Int) => println("x is in class Number")
        case Operator(name: String) => println("x is in class Operator")
    }

    // x가 Number의 instance 이면 "x is in class Name!"를 출력하고
    // x가 Operator의 instance 이면 "x is in class Operator!"를 출력한다.
}

 


Singleton object

Singleton은 class의 instance가 하나만 존재하는 object이다.
class의 instance가 하나만 존재해야하는 경우가 있다.
이 경우에는 class 대신 object를 이용한다.

class Person {...} 대신
object Person {...}


그리고 singleton object는 다음과 같은 특징을 갖는다.
1) 유일하다.
2) 생성자를 정의하지 않는다.
3) new를 이용해서 생성하지 않는다.


Companion Object

class와 이름이 같은 object이다.
static 변수와 method를 정의할 때 companion object를 이용한다.

class Pizza() {...}

Object Pizza {
    val size = 26
    def alertAllergy = println("It contains cheese")
}

standard class

constructor

primary constructor
scala는 java와 달리 class 이름 옆에 parameter를 명시함으로써 primary constructor를 정의한다.

auxilary constructor
추가적인 constructor는 this를 이용해서 아래와 같이 정의한다.

class Person(first_name:String, last_name:String){
	var age = -1
	
    def this(first_name, last_name:String, age:Int) {
    	this(first_name, last_name)this.age = age
    }
}

 

private constructor : private 생성자

class Person private(name: String ){ ... }


default value : 기본값 지정

class Person private(name: String = "hello" ){ ... }



extends를 이용할 때 어떤 생성자를 이용할지 명시할 수 있다.

class Employee(name:String) extends Person (name: String){ ... }

 

 

instance 생성(new)

new를 통해 생성한다.

parameter가 없는 생성자인 경우, ()를 생략할 수 있다.

function의 경우에도 parameter가 없는 경우 ()를 생략할 수 있다.

class AA {
  var vv = 0
  def kk = println("without ()")
  def kk2() = println("with ()")
}


object O {
  def main(args: Array[String]):Unit = {
    val a = new AA
    val b = new AA()
    
    println("a", a)
    println("b", b)
    
    //실행 결과
    //(a,AA@7112f2df)
    //(b,AA@f8ec7ed)
    
    a.kk
    b.kk() // compile error
    
    실행 결과
    //without ()
    
    a.kk2
    b.kk2()
    
    실행 결과
    //with ()
    //with ()
    
    }
}

 

+ Recent posts