Tools (124)

반응형

5. If, if else, switch



If 문


x <- 30L
if(is.integer(x)) {
   print("X is an Integer")
}


[1] "X is an Integer"



If else 문


x <- c("what","is","truth")

if("Truth" %in% x) {
   print("Truth is found")
} else {
   print("Truth is not found")
}


[1] "Truth is not found"



Switch 문


switch 문은 일반적인 C, Java등의 프로그래밍 언어와는 조금 다르다.


# by index
switch(1, "one", "two")
## [1] "one"


# by index with complex expressions
switch(2, {"one"}, {"two"})
## [1] "two"


# by index with complex named expression
switch(1, foo={"one"}, bar={"two"})
## [1] "one"


# by name with complex named expression
switch("bar", foo={"one"}, bar={"two"})
## [1] "two"

아래 튜토리얼을 참고한 포스팅입니다. 

https://www.tutorialspoint.com/r/r_operators.htm 

반응형

'Tools > R' 카테고리의 다른 글

R - (7) 함수  (0) 2017.02.19
R - (6) 반복문  (0) 2017.02.17
R - (4) 연산자  (0) 2017.02.15
R - (3) 변수  (0) 2017.02.15
R - (2) R의 데이터 타입 (자료구조)  (0) 2017.02.13

Tools/R

R - (4) 연산자

2017. 2. 15. 01:53
반응형
4. 연산자

연산자는 산술적, 논리적 연산을 위한 것이다.  R에는 아래와 같은 연산자들이 있다.

  • 산술 연산자 (Arithmetic Operators)
  • 관계 연산자 (Relational Operators)
  • 논리 연산자 (Logical Operators)
  • 할당 연산자 (Assignment Operators)
  • 기타 연산자

산술 연산자 


OperatorDescriptionExample
+두 벡터를 더함

v <- c(2,5.5,6) t <- c(8, 3, 4) print(v+t)

[1] 10.0  8.5  10.0
두 벡터를 뺌

v <- c( 2,5.5,6) t <- c(8, 3, 4) print(v-t)

[1] -6.0  2.5  2.0
*두 벡터를 곱함
v <- c( 2,5.5,6)
t <- c(8, 3, 4)
print(v*t)
[1] 16.0 16.5 24.0
/두 벡터를 나눔
v <- c( 2,5.5,6)
t <- c(8, 3, 4)
print(v/t)
[1] 0.250000 1.833333 1.500000
%%

두 벡터를 나눈 후 나머지

v <- c( 2,5.5,6)
t <- c(8, 3, 4)
print(v%%t)
[1] 2.0 2.5 2.0
%/%

나눗셈의 몫

v <- c( 2,5.5,6)
t <- c(8, 3, 4)
print(v%/%t)
[1] 0 1 1
^

지수

v <- c( 2,5.5,6)
t <- c(8, 3, 4)
print(v^t)
[1]  256.000  166.375 1296.000
관계 연산자


OperatorDescriptionExample
>

왼쪽에 있는 벡터의 엘리먼트가 오른쪽에 있는 벡터의 엘리먼트보다 큰지를 체크한다. 

v <- c(2,5.5,6,9)
t <- c(8,2.5,14,9)
print(v>t)
[1] FALSE  TRUE FALSE FALSE
<

오른쪽에 있는 벡터의 엘리먼트가 왼쪽에 있는 벡터의 엘리먼트보다 큰지를 체크한다.

v <- c(2,5.5,6,9)
t <- c(8,2.5,14,9)
print(v < t)
[1]  TRUE FALSE  TRUE FALSE
==

벡터들의 엘리먼트들이 같은지를 체크한다.

v <- c(2,5.5,6,9)
t <- c(8,2.5,14,9)
print(v == t)
[1] FALSE FALSE FALSE  TRUE
<=

왼쪽에 있는 벡터들의 엘리먼트가 오른쪽에 있는 벡터의 엘리먼트보다 작거나 같은지를 체크한다.

v <- c(2,5.5,6,9)
t <- c(8,2.5,14,9)
print(v<=t)
[1]  TRUE FALSE  TRUE  TRUE
>=

왼쪽에 있는 벡터들의 엘리먼트가 오른쪽에 있는 벡터의 엘리먼트보다 크거나 같은지를 체크한다.

v <- c(2,5.5,6,9)
t <- c(8,2.5,14,9)
print(v>=t)
[1] FALSE  TRUE FALSE  TRUE
!=

벡터들의 엘리먼트가 다른지를 체크한다.

다르면 TRUE, 같으면 FALSE

v <- c(2,5.5,6,9)
t <- c(8,2.5,14,9)
print(v!=t)
[1]  TRUE  TRUE  TRUE FALSE
논리 연산자

논리 연산자는 logical, numeric, complex 타입의 벡터에만 적용 가능하며, numeric이나 complex 타입에 적용될 경우 1보다 큰 모든 수들은 TRUE라고 간주된다. 즉, 논리 연산자는 0과 1을 대상으로 적용된다.

OperatorDescriptionExample
&

&은 element-wise AND 이다. 각 원소별로 AND 연산을 적용한 결과를 만든다.

v <- c(3,1,TRUE,2+3i)
t <- c(4,1,FALSE,2+3i)
print(v&t)
[1]  TRUE  TRUE FALSE  TRUE
|&은 element-wise OR 이다. 각 원소별로 OR연산을 적용한 결과를 만든다.
v <- c(3,0,TRUE,2+2i)
t <- c(4,0,FALSE,2+3i)
print(v|t)
[1]  TRUE FALSE  TRUE  TRUE
!

element-wise NOT 이다.

v <- c(3,0,TRUE,2+2i)
print(!v)
[1] FALSE  TRUE FALSE FALSE
&, | 연산자가 element-wise 연산자인 반면, &&과 ||은 벡터의 첫번째 element 끼리 논리 연산을 적용한다.

OperatorDescriptionExample
&&

벡터의 첫번째 원소끼리 & 연산한 값

v <- c(3,0,TRUE,2+2i)
t <- c(1,3,TRUE,2+3i)
print(v&&t)
[1] TRUE
||벡터의 첫번째 원소끼리 | 연산한 값
v <- c(0,0,TRUE,2+2i)
t <- c(0,3,TRUE,2+3i)
print(v||t)
[1] FALSE

할당 연산자

벡터에 값을 할당할 때 쓰이는 연산자이다.

OperatorDescriptionExample

<−

or

=

or

<<−

왼쪽에 있는 변수에 값을 할당한다.
v1 <- c(3,1,TRUE,2+3i)
v2 <<- c(3,1,TRUE,2+3i)
v3 = c(3,1,TRUE,2+3i)
print(v1)
print(v2)
print(v3)
[1] 3+0i 1+0i 1+0i 2+3i
[1] 3+0i 1+0i 1+0i 2+3i
[1] 3+0i 1+0i 1+0i 2+3i

->

or

->>

오른쪽에 있는 변수에 값을 할당한다. 

c(3,1,TRUE,2+3i) -> v1
c(3,1,TRUE,2+3i) ->> v2 
print(v1)
print(v2)
[1] 3+0i 1+0i 1+0i 2+3i
[1] 3+0i 1+0i 1+0i 2+3i
기타 연산자

이 연산자는 일반적인 논리, 산술 연산자가 아니며, 특수한 상황에서 쓰이는 연산자이다.

OperatorDescriptionExample
:숫자의 시퀀스를 생성하는 연산자
v <- 2:8
print(v) 
[1] 2 3 4 5 6 7 8
%in%

엘리멘터가 벡터에 속해있는지를 체크하는 연산자

v1 <- 8
v2 <- 12
t <- 1:10
print(v1 %in% t) 
print(v2 %in% t) 
[1] TRUE
[1] FALSE
%*%

행렬을 그것의 transpose와 행렬곱셈을 할 때 쓰인다.

M = matrix( c(2,6,5,1,10,4), nrow = 2,ncol = 3,byrow = TRUE)
t = M %*% t(M)
print(t)
      [,1] [,2]
[1,]   65   82
[2,]   82  117

아래 튜토리얼을 참고한 포스팅입니다. 

https://www.tutorialspoint.com/r/r_operators.htm 

반응형

'Tools > R' 카테고리의 다른 글

R - (6) 반복문  (0) 2017.02.17
R - (5) If, else if, switch  (0) 2017.02.15
R - (3) 변수  (0) 2017.02.15
R - (2) R의 데이터 타입 (자료구조)  (0) 2017.02.13
R - (1) Introduction  (0) 2017.02.13

Tools/R

R - (3) 변수

2017. 2. 15. 01:38
반응형

https://www.tutorialspoint.com/r/r_variables.htm



변수


변수는 변수명을 통해 프로그램에서 데이터를 조작할 수 있도록 한다. 변수를 통하여 여러가지 자료구조를(atomic vector, vector, R-Object들의 여러가지 조합) 저장할 수 있다. 변수명에는 숫자, 문자, ., _가 포함될 수 있으며, 문자 또는 .을 첫글자로 하여야 한다. 단 .를 첫글자로 할 때는 .뒤에 숫자가 오면 안된다. 아래의 예를 참고하라.





변수 할당


# Assignment using equal operator.
var.1 = c(0,1,2,3)           

# Assignment using leftward operator.
var.2 <- c("learn","R")   

# Assignment using rightward operator.   
c(TRUE,1) -> var.3           

print(var.1)
cat ("var.1 is ", var.1 ,"\n")
cat ("var.2 is ", var.2 ,"\n")
cat ("var.3 is ", var.3 ,"\n")


변수할당은 = 또는 <-, -> 을 통해 할 수 있다. 또한 출력은 print(), cat()을 통해 할 수 있다. cat() 함수는 여러개의 인풋을 합쳐서 프린트한다.


결과


[1] 0 1 2 3
var.1 is  0 1 2 3 
var.2 is  learn R 
var.3 is  1 1 



변수들의 데이터 타입


R에서 변수의 데이터 타입은 변수에 할당되는 R-Object의 데이터 타입을 따른다. 그래서 R을 동적인 언어(dynamically typed language)라고 부른다. R에서는 변수의 데이터 타입이 하나에 고정되는 것이 아니라 계속해서 바꿀 수 있다. 


var_x <- "Hello"
cat("The class of var_x is ",class(var_x),"\n")

var_x <- 34.5
cat("  Now the class of var_x is ",class(var_x),"\n")

var_x <- 27L
cat("   Next the class of var_x becomes ",class(var_x),"\n")


The class of var_x is  character 
   Now the class of var_x is  numeric 
      Next the class of var_x becomes  integer



변수 찾기


현재 사용되고 있는 변수들의 목록을 보기 위해서는 ls() 함수를 이용한다. 또한 ls() 함수는 변수를 찾기 위해 '패턴'을 이용할 수도 있다. 


print(ls())


[1] "my var"     "my_new_var" "my_var"     "var.1"      
[5] "var.2"      "var.3"      "var.name"   "var_name2."
[9] "var_x"      "varname" 



# List the variables starting with the pattern "var".
print(ls(pattern = "var"))   


[1] "my var"     "my_new_var" "my_var"     "var.1"      
[5] "var.2"      "var.3"      "var.name"   "var_name2."
[9] "var_x"      "varname"  



주의할 점은 .으로 시작하는 변수들은 hidden 이다. 이것을 보기 위해서는 아래와 같이 all.name 파라미터를 TRUE로 설정한다.


print(ls(all.name = TRUE))



변수 삭제


변수는 rm() 함수를 사용해 지울 수 있다. 


rm(var.3)
print(var.3)


위의 스크립트를 실행시키면 var.3 변수를 삭제시키고 두 번째 줄에서는 에러가 뜬다.


rm(list = ls())
print(ls())


모든 변수를 지우고 싶으면 rm()과 ls()를 위와 같이 결합한다.



반응형

'Tools > R' 카테고리의 다른 글

R - (6) 반복문  (0) 2017.02.17
R - (5) If, else if, switch  (0) 2017.02.15
R - (4) 연산자  (0) 2017.02.15
R - (2) R의 데이터 타입 (자료구조)  (0) 2017.02.13
R - (1) Introduction  (0) 2017.02.13
반응형

https://www.tutorialspoint.com/r/r_data_types.htm


일반적인 프로그래밍에서는 값들을 저장하기 위하여 다양한 변수(Variables)들이 필요하다. 변수는 값을 저장한 메모리의 위치를 나타낸다. 이것은 변수를 만들면 그것이 메모리를 일정 공간을 차지한다는 것을 뜻한다. 문자, 정수, 실수, 진릿값 등 다양한 데이터를 변수에 저장하는 것이 필요할 것이다. 운영체제는 이러한 데이터 타입에 알맞게 변수에 메모리를 할당한다. 


R에서는 C나 Java와 같은 프로그래밍 언어와는 다르게 R 에서는 변수를 만들 때 데이터 타입을 선언하지 않는다. 변수는 R-Object로 할당되며 R-Object의 데이터타입이 변수의 데이터타입이 된다. 다양한 타입의 R-Object가 있지만 자주 사용되는 R-Object의 타입은 아래와 같다.



자주 사용하는 데이터 타입


  • Vectors
  • Lists
  • Matrices
  • Arrays
  • Factors
  • Data Frames

R-Object 중 가장 심플한 것은 vector object이고, 이 atomic vectors 또는 classes of vectors라고 불리는 것에는 아래와 같이 6개의 데이터 타입이 있다. 다른 R-Object들은 이 atomic vectors를 기반으로 한다.


  • Logical     
      • ex) TRUE, FALSE
  • Numeric
      • 12.3, 5, 999
  • Integer
      • 2L, 34L
  • Complex
      • 3+2i
  • Character
      • 'a', 'good'
  • Raw
      • "Hello" 는 48 64 6c 6c 6f로 저장된다.

atomic vectors

v <- TRUE 
print(class(v))

v <- 23.5
print(class(v))

v <- 2L
print(class(v))

v <- 2+5i
print(class(v))

v <- "TRUE"
print(class(v))

v <- charToRaw("Hello")
print(class(v))


결과 : 

[1] "logical"

[1] "numeric"
[1] "integer"
[1] "complex"
[1] "character"
[1] "raw"



Vectors

R 언어에서 가장 많이 사용되고 기본적인 R-Object는 Vectors이다. 이것은 위의 열거된 atomic vector들을 저장한다. Vectors는 c() 함수를 사용하여 만들 수 있다. 이것은 엘리먼트들을 벡터로 합친다는 뜻이다. (combine의 c)



# Create a vector.
apple <- c('red','green',"yellow")
print(apple)

# Get the class of the vector.
print(class(apple))



[1] "red"   "green" "1"    
[1] "character"




Matrices



매트릭스는 2차원의 데이터셋이다. 이것은 매트릭스 함수에 벡터를 제공함으로써 만들 수 있다.



# Create a matrix.
M = matrix( c('a','a','b','c','b','a'), nrow = 2, ncol = 3, byrow = TRUE)
print(M)
print(class(M))


     [,1] [,2] [,3]
[1,] "a"  "a"  "b" 
[2,] "c"  "b"  "a" 
[1] "matrix"


Arrays


매트릭스는 2차원에 한정되지만 arrays는 어떠한 차원으로 만들 수 있다.


# Create an array.

a <- array(c('green','yellow'),dim = c(3,3,2))

print(a)


, , 1

     [,1]     [,2]     [,3]    
[1,] "green"  "yellow" "green" 
[2,] "yellow" "green"  "yellow"
[3,] "green"  "yellow" "green" 

, , 2

     [,1]     [,2]     [,3]    
[1,] "yellow" "green"  "yellow"
[2,] "green"  "yellow" "green" 
[3,] "yellow" "green"  "yellow"


위 코드는 3차원의 array를 만들고, 원소들을 차례대로 green, yellow로 지정한다.


Factors


Factors는 vector로 만들어지는 R-object이다. Factors는 vector의 element들의 고유값(distinct value)를 레이블로 저장한다. 이 레이블들은 벡터 원소 타입이 어떻든 간에 항상 문자이다. Factors는 통계적 모델링에 유용하다. Factors는 factor()함수를 사용하여 만들 수 있다. nlevels() 함수를 통해 factors의 레벨을 알 수 있다.



# Create a vector.
apple_colors <- c('green','green','yellow','red','red','red','green')

# Create a factor object.
factor_apple <- factor(apple_colors)

# Print the factor.
print(factor_apple)
print(nlevels(factor_apple))

[1] green  green  yellow red    red    red    green 
Levels: green red yellow
[1] 3


Data Frames


데이터프레임은 구조화된 데이터 오브젝트이다. 매트릭스와 다른점은 데이터프레임은 컬럼으로 어떠한 데이터타입이든 넣을 수 있다. 첫 번째 컬럼은 numeric, 두 번째 컬럼은 문자열, 세 번째 컬럼은 논릿값 등 자유롭게 지정할 수 있다. 이것은 같은 길이의 vector들의 list로 볼 수 있다.


데이터 프레임은 data.frame() 함수를 통해 생성할 수 있다.


# Create the data frame.

BMI <-  data.frame(
   gender = c("Male", "Male","Female"), 
   height = c(152, 171.5, 165), 
   weight = c(81,93, 78),
   Age = c(42,38,26)
)
print(BMI)

gender height weight Age
1   Male  152.0     81  42
2   Male  171.5     93  38
3 Female  165.0     78  26



반응형

'Tools > R' 카테고리의 다른 글

R - (6) 반복문  (0) 2017.02.17
R - (5) If, else if, switch  (0) 2017.02.15
R - (4) 연산자  (0) 2017.02.15
R - (3) 변수  (0) 2017.02.15
R - (1) Introduction  (0) 2017.02.13

Tools/R

R - (1) Introduction

2017. 2. 13. 01:06
반응형

원문 : https://www.tutorialspoint.com/r/index.htm


R tutorial


R은 통계 분석, 그래픽 표현 그리고 리포팅을 위한 프로그래밍 언어 및 소프트웨어 환경이다. R은 뉴질랜드 오클랜드 대학교의 Ross Ihaka and Robert Gentleman에 의해 만들어졌고, 현재는 R Development Core Team가 R을 개발하고 있다. R은 GNU(General Public License) 라이센스하에서 자유롭게 이용가능하며, 리눅스, 윈도우즈, 맥과 같은 다양한 운영체제에 컴파일된 바이너리를 제공하고 있다.  이 프로그래밍 언어 R은 두 명의 개발자, Ross Ihaka and Robert Gentleman 이름의 가장 앞 글자를 딴 것이다. 그리고 Bell Labs에서 만든 프로그래밍 언어 S를 근간으로한다.


대상 독자


이 튜토리얼은 R을 이용하여 통계 소프트웨어를 만들고자하는 소프트웨어 개발자, 통계학자, 데이터 마이너를 대상으로 한다. 만약 당신이 R에 처음이라면, 이 튜토리얼을 통해 R 언어의 대부분의 컨셉을 이해할 수 있고, 이를 통해 더 높은 레벨의 전문가가 될 수 있을 것이다.


선행 조건


이 튜토리얼을 시작하기 앞서 컴퓨터 프로그래밍 언어의 용어들에 대한 기본적인 이해가 필요하다. 프로그래밍 언어에 대한 기본적인 이해는 R 언어의 컨셉을 이해하고 학습하는데 도움이 될 것이다. 


반응형

'Tools > R' 카테고리의 다른 글

R - (6) 반복문  (0) 2017.02.17
R - (5) If, else if, switch  (0) 2017.02.15
R - (4) 연산자  (0) 2017.02.15
R - (3) 변수  (0) 2017.02.15
R - (2) R의 데이터 타입 (자료구조)  (0) 2017.02.13
반응형

/**

2017.02.02 작성자 : 3개월

Tensorflow - MNIST 단일 계층 신경망 트레이닝

*/


환경 : windows tensorflow, anaconda 4.3, python 3.5



Tensorflow를 통해 단일 계층 신경망을 구축하고 MNIST 데이터를 training하고 test 하는 예제입니다. 많은 예제들이 tensorflow 내부에 example로 있는 MNIST 데이터를 이용하지만 이 포스팅에서는 외부에 있는 MNIST pickle 파일을 다운로드하고 이를 읽어들여 모델을 구축해보았습니다. 사용한 MNIST pickle 파일은 https:na//github.com/mnielsen/neural-networks-and-deep-learning/blob/master/data/mnist.pkl.gz 이곳에서 다운로드 받을 수 있습니다. 


1. 데이터 읽기


import tensorflow as tf
import gzip, numpy
import pickle as cPickle
import pandas as pd

# Load the dataset
f = open('data/mnist.pkl', 'rb')
train_set, valid_set, test_set = cPickle.load(f, encoding='latin1')
f.close()

x_train, y_train = train_set
x_test, y_test = test_set


pickle로 불러온 변수에는 train_set, valid_set, test_set이 나뉘어져 있기 때문에 위와 같이 load하면 알아서 training, validation, test set으로 나눌 수 있습니다. 또한 각각은 튜플 자료구조형으로 또 다시 x, y로 나뉘어져 있기 때문에 x_train, y_train = train_set 구문을 통해 feature과 label을 분리할 수 있습니다. 이렇게 데이터를 빠르게 training을 적용할 수 있는 형태로 만들어낼 수 있다는 것이 pickle 파일의 좋은 점입니다. 하지만 예제가 아닌 실제 머신러닝 모델을 구축할 때는 이러한 과정을 모두 직접하여야 합니다. 이미지 파일을 읽어들여야하고 또 이것을 적절한 사이즈의 numpy array로 바꾸어야합니다. 


2. 데이터 전처리


y_train = pd.get_dummies(y_train)
y_test = pd.get_dummies(y_test)


label들을 one hot encoding합니다. tensorflow에서는 label을 one hot encoding 하여 제공하여야 합니다.


print('x_train shape : ',x_train.shape) # (50000, 784)
print('y_train shape : ',y_train.shape) # (50000, 10)
print('x_test shape : ',x_test.shape) # (10000, 784)
print('y_test shape : ',y_test.shape) # (10000, 10)


training data와 test data의 형태(shape)를 프린트하여 보겠습니다. MNIST 데이터는 28*28 흑백 이미지이므로 총 784개의 픽셀이 있는데 이를 feature로 보아 784개의 feature가 있음을 알 수 있습니다. 


[mnist 데이터 모양]



또한 training data의 갯수는 50000개이기 때문에 x_train의 모양은 50000*784 입니다. label의 갯수도 50000개이며 class의 갯수가 0~9까지 10개이므로 y_train은 50000*10입니다. 만약 label이 1인 경우 y는 [0 1 0 0 0 0 0 0 0 0 0] 으로 encoding 됩니다. y_train에는 이러한 y가 50000개 있다고 생각하면 됩니다.


3. 모델 작성


x = tf.placeholder('float', [None, 784]) W = tf.Variable(tf.zeros([784,10])) b = tf.Variable(tf.zeros([10])) y = tf.nn.softmax(tf.matmul(x, W) + b) y_ = tf.placeholder('float', [None, 10]) cross_entropy = -tf.reduce_sum(y_*tf.log(y)) train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)


윗 부분은 데이터를 읽어들이고 numpy와 pandas를 이용하여 데이터를 전처리 한 것이었다면 이제부터는 본격적으로 tensorflow 코드를 작성하여 보겠습니다.


x = tf.placeholder('float', [None, 784])


우선 placeholder을 이용해 x가 들어갈 공간을 만들어줍니다. 이 때 [None, 784]에서 None은 데이터의 갯수는 자유롭게 설정하겠다는 뜻입니다. 하지만 feature의 갯수 784는 고정되어 있습니다. 


W = tf.Variable(tf.zeros([784,10]))


그 다음 weight matrix를 만드는데 input layer의 노드가 784개이고 output layer의 노드가 10개이므로 총 784*10개의 weights가 필요한 것을 알 수 있습니다. 이를 위해 W라는 tensorflow 변수를 만들고 0으로 초기화 시킵니다. 


b = tf.Variable(tf.zeros([10]))


bias는 output layer의 node수만큼 필요하므로 10개를 만들고 0으로 초기화 시킵니다.


y = tf.nn.softmax(tf.matmul(x, W) + b)


그 다음 x와 W를 매트릭스 곱셈을 하고 bias를 더한 것에 softmax 함수를 취하여 이를 y 변수로 만들어줍니다. 수식으로 표현하면  y = softmax(xW+b) 이 됩니다. 이 때 y는 '예측값' 입니다.


cross_entropy = -tf.reduce_sum(y_*tf.log(y)) train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)


손실 함수로는 classification의 경우 크로스 엔트로피를 사용하게 됩니다. -y_*log(y) 에는 데이터들의 크로스 엔트로피들의 2차원 텐서가 담겨져 있습니다. reduce_sum 함수를 통해 이 크로스 엔트로피들의 평균을 구합니다. 이 때 reduce_sum 함수는 지정된 차원을 따라 평균을 내는 것입니다. 2차원인 경우 지정할 차원이 1개 밖에 없으므로 차원을 따로 지정한 필요가 없습니다. 그래서 이 경우에는 reduce_sum 함수는 평균을 구한다고 생각하시면 됩니다.



4. 배치 트레이닝


sess = tf.Session()
sess.run(tf.global_variables_initializer())

batch_size = 100 # 배치 사이즈 지정
training_epochs = 3 # epoch 횟수 지정

# epoch 횟수만큼 반복
for epoch in range(training_epochs) :
    batch_count = int(x_train.shape[0]/100) # 배치의 갯수
    for i in range(batch_count) : # 배치를 순차적으로 읽는 루프
        # 배치사이즈 만큼 데이터를 읽어옴
        batch_xs, batch_ys = x_train[i*batch_size:i*batch_size+batch_size], y_train[i*batch_size:i*batch_size+batch_size] 
        
        # training, 이를 통해 W, b Variable 값을 조정함
        sess.run(train_step, feed_dict = {x : batch_xs, y_ : batch_ys})
        
        # [True False True False False True True ....] 와 같은 boolean vector
        correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
        
        # [1 0 1 0 0 1 1 ...]로 변환 후 평균값을 구하면 accuracy 구할 수 있음
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
        
        # 5번 배치를 읽고 이를 트레이닝한 후 정확도 출력
        if i % 5 == 0 : 
            print(str(epoch+1)+' epoch '+ str(i)+' batch ', sess.run(accuracy, feed_dict={x: x_test[0:100], y_: y_test[0:100]}))


이 부분을 이해하기 위해서는 우선 배치 트레이닝에 대하여 알아야 합니다. 배치 트레이닝이란 트레이닝 데이터를 일정 사이즈로 쪼갠 미니 배치(mini batch)를 통해 Gradient Descent를 하는 방법입니다. 일반적인 Gradient Descent 방법은 전체 트레이닝 데이터를 한 번 쭉 보고 gradient를 구한 후 weights와 bias를 '한 번' 업데이트 시킵니다. 하지만 이런 방법은 computation cost가 높습니다. 하지만 미니 배치를 이용한 방법은 전체 데이터의 샘플인 미니 배치를 통해 전체 데이터를 근사 시킵니다. 그리고 이것만 보고 gradient를 구한 후 weight, bias를 업데이트 시킵니다. 예를 들어 배치 사이즈가 128이면 128개의 데이터 샘플들만 보고 gradient를 구한 후 weight, bias를 업데이트 하게 됩니다. 이전 방식에 비해 훨씬 빠르게 weight를 업데이트 시킬 수 있죠. 이렇게 weight를 구하는 방식은 Stochastic Gradient Descent 방법이라고 부릅니다. 실제로 일반적인 Gradient Descent 방법보다는 Stochastic Gradient Descent 방법이 더 많이 쓰입니다. 팁으로는 배치 사이즈는 메모리가 허용하는 범위 내에서 최대한 크게 잡는 것이 좋습니다. 그리고 보통 배치사이즈는 128, 256, 512와 같이 2의 배수로 잡는 경우가 많은데 혹자는 이를 CPU 연산의 효율을 증가시킨다고 합니다. 하지만 111, 234와 같이 아무 배치 사이즈나 잡아도 트레이닝은 잘 합니다.


이러한 배치 트레이닝의 방식을 이해한다면 위의 텐서플로우 코드도 어렵지 않게 이해할 수 있습니다. 


sess = tf.Session()
sess.run(tf.global_variables_initializer())

세션을 만들고 variable을 초기화 시킵니다. 

  • 텐서플로우에서 Variable은 반드시 위와 같이 초기화 시키고 이용해야합니다.

batch_size = 100 # 배치 사이즈 지정
training_epochs = 3 # epoch 횟수 지정


배치 사이즈와 epoch를 정합니다. epoch은 '전체 데이터를 보는 횟수' 입니다.


# epoch 횟수만큼 반복 for epoch in range(training_epochs) : batch_count = int(x_train.shape[0]/100) # 배치의 갯수 for i in range(batch_count) : # 배치를 순차적으로 읽는 루프 # 배치사이즈 만큼 데이터를 읽어옴 batch_xs, batch_ys = x_train[i*batch_size:i*batch_size+batch_size], y_train[i*batch_size:i*batch_size+batch_size] # training, 이를 통해 W, b Variable 값을 조정함 sess.run(train_step, feed_dict = {x : batch_xs, y_ : batch_ys}) # [True False True False False True True ....] 와 같은 boolean vector correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) # [1 0 1 0 0 1 1 ...]로 변환 후 평균값을 구하면 accuracy 구할 수 있음 accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) # 5번 배치를 읽고 이를 트레이닝한 후 정확도 출력 if i % 5 == 0 : print(str(epoch+1)+' epoch '+ str(i)+' batch ', sess.run(accuracy, feed_dict={x: x_test[0:100], y_: y_test[0:100]}))


이제 마지막 트레이닝 파트입니다. 미니 배치를 구할 때 전체 데이터에서 샘플 데이터를 랜덤으로 뽑는 방식도 있지만 여기서는 그냥 순차적으로 배치를 만들었습니다. 0번부터 100번까지를 1배치, 101번부터 200번까지를 2배치와 같은 방식으로 말입니다. (사실 데이터의 순서에 어떠한 규칙이 있다면 이러한 방식은 좋지 않을 수 있습니다.) epoch만큼 전체 데이터를 보아아햐고 또 배치 사이즈만큼 전체 데이터를 쪼개야하니까 이중 for문을 써야하는 것을 알 수 있습니다. 그리고 두 번째 for문에서는 i라는 인덱스와 batch_size라는 변수를 이용하여 원하는 만큼 데이터를 계속해서 불러온후 Gradient Descent를 하면됩니다. 각각의 문장이 의미하는바는 코드에 주석으로 써두었습니다. 


5. 결과



 배치 트레이닝을 100번 했을 때 이미 정확도가 0.93에 육박하는 것을 알 수 있습니다.




트레이닝이 끝났을 때의 최종 정확도는 0.96 이었습니다. 이미 100번 트레이닝을 했을 때 정확도가 0.93이었기 때문에 그 이상의 training은 의미가 없었을지도 모릅니다. 지금은 validation과정 없이 마구잡이로 트레이닝을 했지만 보통은 언제 training을 끝내야하는지 잘 선택하여야합니다. 계속되는 불필요한 training은 overfitting을 유발할 수 있기 때문입니다. 


반응형
반응형

문제

ImportError: No module named cv2


해결


파이썬 opencv 가 설치되어있지 않아서 생기는 문제로 이를 해결하기 위해 conda install opencv, pip install opencv 등을 해보았지만 제대로 되지 않았습니다. 그래서 opencv 홈페이지에서 직접 윈도우즈용 opencv를 설치하였고 설치된 폴더, opencv\build\python\2.7\x64 이곳에서 파이썬 모듈 cv2.pyd를 Anaconda2\Lib\site-packages에 복사하였더니 문제가 해결되었습니다. 

 

http://speark.tistory.com/9


위 블로그를 참고하였습니다.

반응형
반응형

/**

날짜 : 2017/1/30

작성자 : 3개월

텐서플로우 상수, 변수, 플레이스 홀더

**/


어떠한 프로그래밍 언어를 배울 때 해당 언어의 자료구조에 대한 이해는 매우 중요하다. 자료를 대상으로 어플리케이션을 만들거나 예측 모델을 만들기 때문이다. 텐서플로우에서의 자료구조는 크게 상수(Constant), 변수(Variable), 심볼릭변수(placeholder)로 나뉜다. 세 종류는 특성이 모두 다르므로 이를 제대로 아는 것이 중요하다. 아래는 텐서플로우에서 이 자료 구조들을 어떻게 생성하고 다루는지 실습한 것이다. 


1. 상수


기본적인 상수 생성 방법 


""" 텐서플로우 상수
    references : 텐서플로우 첫걸음 &
    https://tensorflowkorea.gitbooks.io/tensorflow-kr/content/g3doc/api_docs/python/constant_op.html
"""
import tensorflow as tf

points = [[1,2,3],[4,5,6]] # 2차원 배열
print(points)

vectors = tf.constant(points) # 텐서플로우 상수 생성

print(vectors) # Tensor("Const_9:0", shape=(2, 3), dtype=int32)
print(vectors.get_shape()) # 2x3

expanded_vectors = tf.expand_dims(vectors, 0) # 2-D 텐서를 3-D 텐서로 차원 확장

print(expanded_vectors) # Tensor("ExpandDims_6:0", shape=(1, 2, 3), dtype=int32)
print(expanded_vectors.get_shape()) # 1x2x3

# value 를 출력하려면 아래와 같이 세션 생성 후 run 해야함
sess = tf.Session()
print(sess.run(vectors)) # [[1 2 3]
                         # [4 5 6]]
print(sess.run(expanded_vectors)) #[[[1 2 3]
                                  # [4 5 6]]]


상수를 생성하는 여러가지 방법


""" 상수를 생성하는 여러가지 방법 """
zeros = tf.zeros_like([4,3,3], dtype=tf.int32, name='zeros')
print(sess.run(zeros)) # [0,0,0] (입력으로 받은 텐서와 같은 shape의 텐서인데 0으로 초기화된 것)

# zeros와 zeros_like의 차이점 잘 비교. 일반적으로 zeros를 많이 쓸거 같음.
zeros2 = tf.zeros([3,4,5], dtype=tf.int32, name='zeros2')
print(sess.run(zeros2)) # 0으로 초기화된 3x4x5 텐서가 만들어짐

ones = tf.ones([2,2,3], dtype=tf.float32)
print(sess.run(ones)) # 1로 초기화된 2x2x3 텐서가 만들어짐

fill = tf.fill([2,3], 9) # 9로 초기화된 2x3 텐서
print(sess.run(fill))

contant = tf.constant([2,3,4]) # 주어진 텐서를 그대로 텐서플로우 변수로 전환
print(sess.run(contant)) # [2 3 4]

tensor = tf.constant(-1.0, shape=[2, 3])# tf.fill([2,3], -1.0) 과 같음
print(sess.run(tensor))


* 난수 상수 생성 -> weight 초기화 할 때 자주 이용


""" 난수 상수 생성 """
# 정규분포 난수
norm = tf.random_normal([2, 3], mean=-1, stddev=4)
print(sess.run(norm))

# 주어진 값들을 shuffle
c = tf.constant([[1, 2], [3, 4], [5, 6]])
shuff = tf.random_shuffle(c)
print(sess.run(shuff))

# 균등분포 난수
unif = tf.random_uniform([2,3], minval=0, maxval=3)
print(sess.run(unif))


시퀀스 상수 생성


""" 시퀀스 """
lin = tf.linspace(10.0, 12.0, 3, name="linspace")
print(sess.run(lin))

# start부터 시작하여 limit까지 (limit는 포함하지 않음) delta의 증가량만큼 확장하며 정수 리스트를 생성합니다.
ran = tf.range(start=3, limit=7, delta=1) 
print(sess.run(ran)) # [3 4 5 6]

# start의 default는 0
ran2 = tf.range(8)
print(sess.run(ran2)) # [0 1 2 3 4 5 6 7]


난수 생성시 Seed의 활용

  • seed를 활용함으로써 매 실행마다 같은 결과를 내도록 할 수 있다.


""" 난수 생성시 seed의 활용 """
a = tf.random_uniform([1], seed=1) # seed를 주고 random한 값을 생성하면 매 session마다 값이 같음
b = tf.random_normal([1])

# Repeatedly running this block with the same graph will generate the same
# sequence of values for 'a', but different sequences of values for 'b'.
print("Session 1")
with tf.Session() as sess1:
  print(sess1.run(a))  # generates 'A1'
  print(sess1.run(a))  # generates 'A2'
  print(sess1.run(b))  # generates 'B1'
  print(sess1.run(b))  # generates 'B2'

print("Session 2")
with tf.Session() as sess2:
  print(sess2.run(a))  # generates 'A1'
  print(sess2.run(a))  # generates 'A2'
  print(sess2.run(b))  # generates 'B3'
  print(sess2.run(b))  # generates 'B4'
    
# tf.set_random_seed를 통해 모든 random value generation function들이 매번 같은 값을 반환함    
tf.set_random_seed(1234)
a = tf.random_uniform([1])
b = tf.random_normal([1])

# Repeatedly running this block with the same graph will generate different
# sequences of 'a' and 'b'.
print("Session 1")
with tf.Session() as sess1:
  print(sess1.run(a))  # generates 'A1'
  print(sess1.run(a))  # generates 'A2'
  print(sess1.run(b))  # generates 'B1'
  print(sess1.run(b))  # generates 'B2'

print("Session 2")
with tf.Session() as sess2:
  print(sess2.run(a))  # generates 'A1'
  print(sess2.run(a))  # generates 'A2'
  print(sess2.run(b))  # generates 'B1'
  print(sess2.run(b))  # generates 'B2'


2. 변수


변수 생성


""" 텐서플로우 변수 
    reference : https://tensorflowkorea.gitbooks.io/tensorflow-kr/content/g3doc/how_tos/variables/
"""
# 두 변수를 생성.
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
                      name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")

# 변수는 반드시 initialization 해야한다.


변수 초기화

  • 변수는 초기화하지 않으면 사용할 수 없다. 반드시 initialization 하여야 한다.


# 변수 초기화

# 두 변수를 생성
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
                      name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")

# 변수 초기화 오퍼레이션을 초기화
init_op = tf.global_variables_initializer()

# 나중에 모델을 실행할때
with tf.Session() as sess:
    sess.run(init_op) # initialization 연산 실행
    print(sess.run(weights))
    print(sess.run(biases))


다른 변수값을 참조하여 변수 초기화


# 다른 변수값을 참조하여 초기화 하기

# 랜덤 값으로 새로운 변수 초기화
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
                      name="weights")
# weights와 같은 값으로 다른 변수 초기화
w2 = tf.Variable(weights.initialized_value(), name="w2")
# weights의 2배 값으로 다른 변수 초기화
w_twice = tf.Variable(weights.initialized_value() * 2.0, name="w_twice")

# 변수 초기화 오퍼레이션을 초기화
init_op = tf.global_variables_initializer()

with tf.Session() as sess : 
    sess.run(init_op)
    print(sess.run(w2))
    print(sess.run(w_twice))



3. 플레이스홀더

실행시에 데이터를 제공하는 방법으로 실제 딥러닝 모델 구축시 많이 쓰인다. sess.run 에서 feed_dict에 dictionary 형식으로 값을 넣어주면 되고 이를 feeding이라 한다.


""" 텐서플로우 심볼릭 변수(플레이스홀더)
"""
a = tf.placeholder("float")
b = tf.placeholder("float")

y = tf.mul(a,b)

sess = tf.Session()

print(sess.run(y, feed_dict={a : 3, b: 5})) # 15.0


반응형
반응형

/**

날짜 : 2017.1.22

작성자 : 3개월

제목 : MNIST 데이터로 CNN Training 해보기

*/



1. 패키지 로드 & 데이터 읽기


""" Simple Convolutional Neural Network for MNIST """
import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Convolution2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering('th')
import cPickle, gzip, numpy

# Load the dataset
f = gzip.open('mnist.pkl.gz', 'rb')
train_set, valid_set, test_set = cPickle.load(f)
f.close()


필요한 패키지들을 불러오고 데이터들을 불러옵니다.

mnist.pkl.gz는 

https://github.com/mnielsen/neural-networks-and-deep-learning/blob/master/data/mnist.pkl.gz 

에서 다운로드 후 코드와 같은 폴더에 붙여 넣으시면 됩니다.


# train_set 은 튜플로 두 개의 ndsarray를 원소로 가지고 있음
print train_set
print type(train_set)
print len(train_set)

# 튜플을 이렇게 둘로 나눌 수 있음
X_train, y_train = train_set
X_test, y_test = test_set

print type(X_train)
print len(X_train)
print len(y_train)
print X_train
print y_train


이제 MNIST 데이터를 읽어들였고, training set과 test set이 준비 완료되었습니다. 하지만 cnn에서는 x vector의 형태를 알맞게 고치는 preprocessing 작업이 필요합니다.  


2. 데이터 preprocessing


""" In Keras, the layers used for two-dimensional convolutions expect pixel values with the dimensions [pixels][width][height]. """
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype('float32') X_test = X_test.reshape(X_test.shape[0], 1, 28, 28).astype('float32') # normalize inputs from 0-255 to 0-1 X_train = X_train / 255 X_test = X_test / 255 # one hot encode outputs y_train = np_utils.to_categorical(y_train) y_test = np_utils.to_categorical(y_test) num_classes = y_test.shape[1] # fix random seed for reproducibility seed = 7 numpy.random.seed(seed)


위와 같이 numpy의 reshape함수를 이용하여 X vector를 [pixels][width][height] 형태로 바꿔줍니다. (이 때 X_train.shape = (50000L, 784L) 라서 X_train.shape[0] = 50000 입니다.)


  • keras에서 cnn을 구현할 때 [pixels][width][height] 형태로 input을 받습니다. (Theano Backend의 경우)

piexels는 흑백이므로 1을 입력하고 MNIST데이터는 28x28 손글씨 이미지이므로 width = 28, height = 28을 입력합니다. 만약 컬러라면 3을 넣어야합니다. 이제 모든 training 데이터와 test 데이터의 준비는 끝났습니다.


3. CNN 모델 


def cnn_model():
    # create model
    model = Sequential()
    model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(1, 28, 28), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.2))
    model.add(Flatten())
    model.add(Dense(127, activation='relu'))
    model.add(Dense(num_classes, activation='softmax'))
    # Compile model
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model


CNN 모델을 구축하여보겠습니다. 

위 모델은 Convolution Layer-ReLU-Pooling Layer-(Dropout)-Fully Connected Network로 이어지는 구조이며 기본적인 CNN의 구조입니다.


  • Convolution2D(32,5,5...)에서 32는 feature map의 갯수라 할 수 있고 5,5는 5x5 필터 사이즈를 의미합니다. 
  • border_mode는 zero-padding에 관한 세팅입니다. valid는 valid convolution을 의미하여 padding을 주지 않습니다. 만약 same인 경우 same convolution이며 zero-padding을 넣어 convolution 결과의 사이즈과 인풋과 같게 합니다.


4. Training & Test


# build the model
model = cnn_model()
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), nb_epoch=10, batch_size=200, verbose=2)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Baseline Error: %.2f%%" % (100-scores[1]*100))



이제 CNN을 트레이닝해보겠습니다. validation set은 test set으로 대체하였고, epoch=10, batch_size=200으로 하였습니다. verbose는 로깅에 관한 세팅으로 개념을 이해할 때는 무시하셔도 좋습니다.





error는 validation error을 기준으로 하며 마지막 epoch의 validation error에서 (1-0.9370)*100을 하여 6.3%가 됩니다. 앞서 MLP로 training하였을때는 7% 대에 error를 보였지만 CNN을 통해서 error rate를 낮출 수 있었습니다.






반응형
반응형

/**

Keras Mnist Learning Using Multi Layer Perceptron

작성자 : 3개월

날짜 : 2017.1.20

코드하이라이터 : http://markup.su/highlighter/

*/


1. 데이터 읽기


import cPickle, gzip, numpy

# Load the dataset
f = gzip.open('mnist.pkl.gz', 'rb')
train_set, valid_set, test_set = cPickle.load(f)
f.close()


mnist.pkl.gz는

https://github.com/mnielsen/neural-networks-and-deep-learning/blob/master/data/mnist.pkl.gz 

에서 다운로드 후 코드와 같은 폴더에 붙여 넣으시면 됩니다.


cPickle.load(f)를 하면 train_set, valid_set, test_set이 알아서 나뉘어집니다.


# train_set 은 튜플로 두 개의 ndsarray를 원소로 가지고 있음
print train_set
print type(train_set)
print len(train_set)

# 튜플을 이렇게 둘로 나눌 수 있음
X_train, y_train = train_set
X_test, y_test = test_set

print type(X_train)
print len(X_train)
print len(y_train)
print X_train
print y_train


train_set을 위와 같이 X_train, y_train 으로 나눌 수 있습니다.

train_set은 2개의 원소(X, Y)를 갖고 있는 '튜플' 인데 튜플인 경우 저러한 문법이 가능합니다.


2. Multi Layer Perceptron 구현


CNN을 활용하기 전에 Multi Layer Perceptrons을 이용하여 데이터셋을 러닝해봅니다. universal approximation theorem에 의해 사실 이 MLP로도 이미지 classification을 포함한 이 세상에 존재하는 모든 문제를 해결할 수 있습니다. (다만 데이터가 부족할뿐) 


# multi-layer perceptron
import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.utils import np_utils


패키지를 임포트합니다.


seed = 7
numpy.random.seed(seed)


계속 실행하더라도 동일한 결과를 갖기 위해 numpy random seed를 설정해줍니다.


print type(X_train)
print type(y_train)


타입은 두 개 모두 ndarray입니다. X_train은 784*50000 2차원 배열, y_train은 길이가 50000인 1차원 배열입니다. 784는 MNIST 데이터가 28*28 =784 픽셀 흑백 손글씨 이미지이기 때문에 나온 숫자이고 이를 일렬로 쭉 늘어놓은 것입니다. 또한 50000은 데이터의 갯수입니다. 


# normalize inputs from 0-255 to 0-1
X_train = X_train / 255
X_test = X_test / 255


흑백 이미지 데이터는 픽셀 하나당 0-255까지의 숫자값을 가지므로 이를 255로 나누면 0-1 사이로 normalize됩니다.


# one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)

# y_test 의 column을 클래스의 갯수 지정 : 10개
num_classes = y_test.shape[1]
num_pixels = X_train.shape[1]


위와 같이 y 값들을 one hot encoding 합니다.

또 아래 MLP 모델을 구축할 때 쓰는 변수들 num_classes, num_pixels를 정의합니다.


# define baseline model
def baseline_model():
    # create model
    model = Sequential()
    model.add(Dense(num_pixels, input_dim=num_pixels, init='normal', activation='relu'))
    model.add(Dense(num_classes, init='normal', activation='softmax'))
    # Compile model
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

def good_model():
    # create model
    model = Sequential()
    model.add(Dense(400, input_dim=num_pixels, init='normal', activation='relu'))
    model.add(Dense(100, init='normal', activation='relu'))
    model.add(Dense(num_classes, init='normal', activation='softmax'))
    # Compile model
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model


위와 같이 두 개의 MLP를 만들었습니다.

baseline_model은 히든 레이어가 한 개인 네트워크이고, good_model은 히든 레이어가 두 개인 네트워크입니다.


  • keras의 경우 input layer는 생략하며 첫 번째 히든 레이어에 "input_dim=인풋 레이어의 노드 수"를 지정하는 식으로 네트워크를 구성합니다.
  • 히든 레이어가 많고, 한 레이어당 노드 수가 적을 수록 overfitting이 적어져 generalization이 잘된다고 알려져있습니다.

데이터를 통해 위 두 개의 네트워크를 훈련하고 테스트해보겠습니다.



3. Training & Test


히든 레이어 한 개짜리 MLP


# build the model
model = baseline_model()
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), nb_epoch=10, batch_size=200, verbose=2)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Baseline Error: %.2f%%" % (100-scores[1]*100))


첫 번째 모델인 baseline_model을 train하고 test하는 코드입니다. 

validation set은 test set으로 대체하였습니다. 

실행시 아래와 같이 10번 epoch을 돌면서, training accuracy, loss와 validation accuracy, loss를 출력합니다. 



error는 validation accuracy를 기준으로하며 (1-0.9232)*100 = 7.68% 입니다.



히든 레이어 두 개짜리 MLP (더 Deep 한 모델)


# build the model
model2 = good_model()
# Fit the model
model2.fit(X_train, y_train, validation_data=(X_test, y_test), nb_epoch=10, batch_size=200, verbose=2)
# Final evaluation of the model
scores = model2.evaluate(X_test, y_test, verbose=0)
print("Baseline Error: %.2f%%" % (100-scores[1]*100))


두 번째 모델인 good_model을 기준으로 training 과 test를 합니다.




위와 같이 Error가 7.54%로 첫 번째 네트워크보다 accuracy가 다소 높은 것을 알 수 있습니다.


4. 결론


MLP로 MNIST 데이터를 training하고 test 해보았습니다. MNIST와 같이 이미지 사이즈가 작고 흑백인 이미지에는 MLP도 꽤 괜찮은 accuracy를 내준다는 것을 알 수 있습니다. 하지만 이미지의 사이즈가 커지고 class의 갯수가 많아질 수록 CNN(Convolutional Neural Network)과 같은 이미지 처리에 최적화된 네트워크를 쓰는 것이 훨씬 효율적일 것입니다. 또한 training할 때 layer와 갯수와 layer당 node수를 적절히 선택하는 것이 중요하며 보통 이 사이즈는 try & error로 구하는 경우가 많습니다. 물론 네트워크를 구성하고 training 해본 경험이 많다면 어느정도의 layer와 node수를 선택해야하는지에 대해 어느정도 직감을 가질 수 있습니다.





반응형
반응형