RでDeep Learning(2)

環境はWindows10 & R-3.3.3

非常に良い本である。
ただし、自分はPythonに精通していないのでRでDeep Learningを試してみた。

この記事は上記の本に記載されているPythonのコードのほんの一部をRに書き換えただけです。
詳しく知りたい人はぜひ本を読んでみることをお勧めします。
非常に詳しくわかりやすく書かれています。

まずはソフトマックス関数を定義する。

softmax <- function(x){
	m <- max(x)
	exp_x <- exp(x-m)
	sum_exp_x <- sum(exp_x)
	y <- exp_x/sum_exp_x
	return(y)
}

次にニューラルネットワークを実装してみる。

#学習済みの重みパラメータとバイアスの読み込み
init_network <- function(){
	network <- as.list(NULL)
	#学習済みの重みパラメータ
	data_W1 <- read.csv("network_W1.csv",header=F) %>% as.matrix()
	data_W2 <- read.csv("network_W2.csv",header=F) %>% as.matrix()
	data_W3 <- read.csv("network_W3.csv",header=F) %>% as.matrix()
	network <- network %>% c(list(W1=data_W1))
	network <- network %>% c(list(W2=data_W2))
	network <- network %>% c(list(W3=data_W3))
	#バイアス
	data_b1 <- read.csv("network_b1.csv",header=F) %>% as.matrix() %>% as.vector()
	data_b2 <- read.csv("network_b2.csv",header=F) %>% as.matrix() %>% as.vector()
	data_b3 <- read.csv("network_b3.csv",header=F) %>% as.matrix() %>% as.vector()
	network <- network %>% c(list(b1=data_b1))
	network <- network %>% c(list(b2=data_b2))
	network <- network %>% c(list(b3=data_b3))
	return(network)
}

#MNISTテストデータの読み込み
get_data <- function(){
	test_data <- as.list(NULL)
	data_x <- read.csv("x_test.csv",header=F) %>% as.matrix()
	data_t <- read.csv("t_test.csv",header=F) %>% as.matrix()
	test_data <- test_data %>% c(list(x_test=data_x))
	test_data <- test_data %>% c(list(t_test=data_t))
	return(test_data)
}

#分類
predict <- function(network,x){
	W1 <- network$W1
	W2 <- network$W2
	W3 <- network$W3
	b1 <- network$b1
	b2 <- network$b2
	b3 <- network$b3

	a1 <- (x %*% W1) + b1
	z1 <- sigmoid(a1)
	a2 <- (z1 %*% W2) + b2
	z2 <- sigmoid(a2)
	a3 <- (z2 %*% W3) + b3
	y <- softmax(a3)
	return(y)
}

いよいよ実行。

myData <- get_data()
x <- myData$x_test
t <- myData$t_test

x <- x/255

network <- init_network()

accuracy_cnt <- 0
for(i in 1:nrow(x)){
	y <- predict(network,x[i,])
	p <- which.max(y)
	if((p-1)==t[i]) accuracy_cnt <- accuracy_cnt+1
}

accuracy_cnt/nrow(x)
[1] 0.9352

画像の表示。

a <- x[1000,]
b <- matrix(a,nrow=28,byrow=T)
y <- t(b[nrow(b):1,ncol(b):1])[ncol(b):1,]
image(y,axes=FALSE)

バッチ処理するためにpredictを書き換え。

predict <- function(network,x){
	if(x %>% is.vector()){
		batch_size <-1
	}else{
		batch_size <- nrow(x)
	}

	W1 <- network$W1
	W2 <- network$W2
	W3 <- network$W3
	b1 <- matrix(rep(network$b1,batch_size),nrow=batch_size,byrow=T)
	b2 <- matrix(rep(network$b2,batch_size),nrow=batch_size,byrow=T)
	b3 <- matrix(rep(network$b3,batch_size),nrow=batch_size,byrow=T) 

	a1 <- (x %*% W1) + b1
	z1 <- sigmoid(a1)
	a2 <- (z1 %*% W2) + b2
	z2 <- sigmoid(a2)
	a3 <- (z2 %*% W3) + b3
	y <- apply(a3,1,softmax) %>% t()
	return(y)
}

そして実行。

myData <- get_data()
x <- myData$x_test
t <- myData$t_test

x <- x/255

network <- init_network()

batch_size <- 100
accuracy_cnt <- 0

for(i in seq(1,10000,by=batch_size)){
	x_batch <- x[i:(i+batch_size-1),]
	y_batch <- predict(network,x_batch)
	p <- apply(y_batch,1,which.max)
	accuracy_cnt <- accuracy_cnt + sum((p-1)==t[i:(i+batch_size-1)])
}

accuracy_cnt/nrow(x)
[1] 0.9352