Skip to content

Latest commit

 

History

History
308 lines (252 loc) · 9.09 KB

ANN.org

File metadata and controls

308 lines (252 loc) · 9.09 KB

Artificial Neural Nets

Setup

R Setup

Libraries and Functions

   library(sigmoid)
   getLabels <- function(lbldb, nget=0) {
	magic  <- readBin(lbldb, what="integer", n=1, endian="big", size=4)
	if(magic != 2049)
	    return(NULL)
	n.lbls    <- readBin(lbldb, what="integer", n=1,    endian="big", size=4)
	if(nget==0)
	    nget=n.lbls

	labels <- readBin(lbldb, what="integer", n=nget, endian="big",  size=1)

	close(lbldb)
	return(labels)
   }

   getImages <- function(imgdb, nget=0, progress=FALSE) {
	magic  <- readBin(imgdb, what="integer", n=1, endian="big", size=4)
	## if(magic != 2049)
	##     return(NULL)

	n.imgs <- readBin(imgdb, what="integer", n=1, endian="big", size=4)
	if(nget==0)
	    nget <- n.imgs # trunc(sqrt(n.imgs))

	n.rows <- readBin(imgdb, what="integer", n=1, endian="big", size=4)
	n.cols <- readBin(imgdb, what="integer", n=1, endian="big", size=4)

	print(gettextf("Getting %d %dx%d Images", nget, n.rows, n.cols))

	images <- c()
	for(i in 1:nget) {
	    .img   <- matrix(readBin(imgdb, what="integer", n=n.rows*n.cols, endian="big", size=1), nrow=n.rows, ncol=n.cols)
	    images <-  c(images, list(.img))
	    if(progress && i %% trunc(sqrt(nget)) == 0) 
		print(gettextf("%2.2f%%", round((100*i)/nget, digits=2)))
	}
	close(imgdb)
	return(images)
   }

Data Setup

Data (import)

## Works
tr.labels <- as.vector(getLabels(gzfile("datasets/training/labels", "rb"), nget=256))
tr.images <- getImages(gzfile("datasets/training/images", # data's filename
				"rb"), # read it as binary
			 ## Get 256 of the entries
			 nget=256, progress=TRUE)
tr.im.matrix <- do.call("rbind", # create rows out of the input data
			  lapply(tr.images, as.vector)) # transform each image
							# matrix into a vector

tr.df <- cbind(as.factor(tr.labels), tr.im.matrix) # now create a data frame

oldpar <- par(mar=rep(0,4))
image(tr.images[[8]], useRaster=TRUE, col=seq(2^8)) 
par(oldpar)
Label Frequency
LabelsFreq
030
135
225
330
424
517
624
726
819
926

Data (Links)

IDsize (b)Link
training set images9912422http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
training set labels28881http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
test set images1648877http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
test set labels4542http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz

Implementation: Multilayer Perceptron with Backprop

Features
  • builds arbitrarily layered ANN model
  • has weights (rnorm), biases(rnorm), and layer nodes
  • has member function for layer extraction
    • returns class “layer” with 3 member lists for the given layers data
TODO
predict function
feedforward (recursive chain of feedforwardstep?)
train function
backprop (step then recursive chain?)
summary functions
layer and model
print functions
layer, model
plot functions
model, inputs, outputs (eg plot the input rows of tr.df, and output of predict

Model Class

summary.model.ann.classifier <- function(model) {
    print(paste("Number of Layers: ", model$nlayers))
    print(paste("Respective Lengths: ", toString(model$lengths)))
}

summary.layers <- function(layers) {
    lapply(lapply(X=layers, str),print)
}

model.gen.annc <- function(length.input,
			     length.hidden,
			     length.output,                          
			     out.classes=as.factor(1:length.output),
			     input=NULL,
			     debug=TRUE) {    
    model <- list()
    class(model) <- "model.ann.classifier"

    .lengths <- c(length.input,
		   length.hidden,
		   length.output)
    ## print(lengths)
    n.layers <- length(.lengths)


    ## print(paste("Input Length:",     length.input))
    if(debug) print(paste("Number of Layers:", n.layers))
    if(debug) print(paste("Layer Lengths:",    toString(.lengths)))
    ## print(paste("Output Length:",    length.output))

    model$nlayers <- n.layers
    model$lengths <- .lengths

    .nodes <- mapply(matrix,
		       data=0,
		       ncol=1,
		       nrow=.lengths)
    model$nodes <- .nodes

    .biases <- numeric()
    .biases <- lapply(.lengths, rnorm)
    model$biases <- .biases

    # .weights <- 
     ## <- mapply(matrix,
     ##                   ncol=1,
     ##                   nrow=.lengths,
     ##                   data=lapply(.lengths,rnorm))

    ## TODO: this needs to be converted to mapply or the function needs to be
    ## fixed, rn it errors
    .weights <- lapply(1:(length(model$nodes)-1),
			 function(k)
			     matrix(rnorm(lengths[k+1]*lengths[k])),
			 nrow=lengths[],
			 ncol=lengths[]
			 )
  
    model$weights <- .weights

    ## model$biases <- lapply(1:(length(model$nodes)-1),
    ##                        function(k)
    ##                            matrix(rnorm(lengths[k+1]),
    ##                                   nrow=lengths[k+1]))

    model$input <- if(length(input))
			 as.matrix(input)
		     else
			 .nodes[[1]]

    model$nodes[[1]] <- model$input

    ## model$get_layer <- function(k) { ## 1 -> k=nlayers->output=nodes[[n]]
    ##     ret <- list()
    ##     class(ret) <- "layer"
    ##     ret$nodes  <- model$nodes[k]
    ##     ret$weights<- ifelse(k==1, 0, model$weights[k-1])
    ##     ret$biases <- ifelse(k==1, 0, model$biases[k-1])        
    ##     return(ret)
    ## }
    layers <- list()
    update_layers <- function() {
	  layers <- list()
	  layers[[1]] <- list(Nodes=model$nodes[[1]],
			      Weights=model$weights[[1]],
			      Biases=model$biases[[1]])
	  for(i in 2:(model$nlayers-1)) {
	      layers[[i]] <- list(Weights=model$weights[[i]],
				  Biases=model$biases[[i]],
				  Nodes=model$nodes[[i+1]])
	  }            
	  model$layers <- layers
	  return(layers)
    }

    ## IMPORTANT: we need to profile this and the update function, think about
    ## how best to implement this/model$layers so that it stays updated, 
    model$get_layer <- function(k) {
	  update_layers()
	  if(k!=1)
	      return(layers[k-1])
	  else
	      return(list(Weights=0,
			  Biases=0,
			  Nodes=model$nodes[[k]]))
    }


    model$predict <- function(input) {        
	  forwardstep <- function(k) {
	      if(k==model$nlayers)
		  return(model$weights[[k]])
	      return(model$weights[[k]]%*%model$nodes[[k]]+model$biases[[k]]) ## W1.N1+B1, 
	  }        
	  model$nodes[[2]] <- forwardstep(1)
	  model$nodes[[3]] <- forwardstep(2)        
	  return(0)            
    }

    model$train <- function(train.df, train.labels) {

    }

    ## 
    feedforward <- function(input) {
	  output <- list()
	  return(output)
    }

    stopifnot(length(model$weights)==(model$nlayers-1))
    return(model)
}

model.genstd <- function()
    return(model.gen.annc(2,2,1, input=rbinom(n=2, size=1, prob=0.5)))


forwardstep <- function(model, k) {
    if(k==1)
	  model$nodes[[k]] <- model$weights[[k-1]]%*%model$input
    else
	  model$nodes[[k]] <- model$weights[[k-1]]%*%model$nodes[[k-1]]
    return(model)
}

predict.model.ann.classifier <- function(model, input) {

}


## basic layout, 4 layers of 5x1
model <- model.gen.annc(2,2,1, input=rbinom(n=2, size=1, prob=0.5))
names(model)
print(model$get_layer(1))
[1] "Number of Layers: 3"
[1] "Layer Lengths: 2, 2, 1"
[1] "nlayers"   "lengths"   "nodes"     "weights"   "biases"    "input"    
[7] "get_layer"
[1] "Number of Layers:  3"
[1] "Respective Lengths:  2, 2, 1"
TRUE

Analysis

 

Conclusion

Sources

Biblio

These I read in the process of completing this project. In places where specific citations could be made, I have places them and linked here.

backprop

https://github.com/mnielsen/neural-networks-and-deep-learning/blob/master/src/network.py