Skip to content

Instantly share code, notes, and snippets.

@mrecos
Last active January 11, 2018 18:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrecos/40e96527b14bdbf43492405b5a166ff2 to your computer and use it in GitHub Desktop.
Save mrecos/40e96527b14bdbf43492405b5a166ff2 to your computer and use it in GitHub Desktop.
R stats code for building NN and looping over hidden layer node density for animated gif output. NN code attributed to David Selby; http://selbydavid.com/2018/01/09/neural-network/
########################################################################
### Bespoke Neural Network R code attributed to: David Selby
### From blog post: http://selbydavid.com/2018/01/09/neural-network/
### Adapted here for making animated GIF of node density
### output gifs compiled at gifmaker.me for final output
### output tweeted here:
### https://twitter.com/Md_Harris/status/951257342418608128
########################################################################
two_spirals <- function(N = 200,
radians = 3*pi,
theta0 = pi/2,
labels = 0:1) {
N1 <- floor(N / 2)
N2 <- N - N1
theta <- theta0 + runif(N1) * radians
spiral1 <- cbind(-theta * cos(theta) + runif(N1),
theta * sin(theta) + runif(N1))
spiral2 <- cbind(theta * cos(theta) + runif(N2),
-theta * sin(theta) + runif(N2))
points <- rbind(spiral1, spiral2)
classes <- c(rep(0, N1), rep(1, N2))
data.frame(x1 = points[, 1],
x2 = points[, 2],
class = factor(classes, labels = labels))
}
feedforward <- function(x, w1, w2) {
z1 <- cbind(1, x) %*% w1
h <- sigmoid(z1)
z2 <- cbind(1, h) %*% w2
list(output = sigmoid(z2), h = h)
}
sigmoid <- function(x) 1 / (1 + exp(-x))
backpropagate <- function(x, y, y_hat, w1, w2, h, learn_rate) {
dw2 <- t(cbind(1, h)) %*% (y_hat - y)
dh <- (y_hat - y) %*% t(w2[-1, , drop = FALSE])
dw1 <- t(cbind(1, x)) %*% (h * (1 - h) * dh)
w1 <- w1 - learn_rate * dw1
w2 <- w2 - learn_rate * dw2
list(w1 = w1, w2 = w2)
}
train <- function(x, y, hidden = 5, learn_rate = 1e-2, iterations = 1e4) {
d <- ncol(x) + 1
w1 <- matrix(rnorm(d * hidden), d, hidden)
w2 <- as.matrix(rnorm(hidden + 1))
for (i in 1:iterations) {
ff <- feedforward(x, w1, w2)
bp <- backpropagate(x, y,
y_hat = ff$output,
w1, w2,
h = ff$h,
learn_rate = learn_rate)
w1 <- bp$w1; w2 <- bp$w2
}
list(output = ff$output, w1 = w1, w2 = w2)
}
library(ggplot2)
library("emoGG")
theme_set(theme_classic())
set.seed(42)
hotdogs <- two_spirals(labels = c('not The Beach', 'The Beach'))
ggplot(hotdogs) +
aes(x1, x2, colour = class) +
geom_point() +
labs(x = expression(x[1]),
y = expression(x[2]))
grid <- expand.grid(x1 = seq(min(hotdogs$x1) - 1,
max(hotdogs$x1) + 1,
by = .1),
x2 = seq(min(hotdogs$x2) - 1,
max(hotdogs$x2) + 1,
by = .1))
grid$class <- factor((predict(logreg, newdata = grid) > 0) * 1,
labels = c('not The Beach', 'The Beach'))
x <- data.matrix(hotdogs[, c('x1', 'x2')])
y <- hotdogs$class == 'The Beach'
nodes <- c(1,2,5,10,15,20,24,26,28,30,32,34,36,38)
for(i in seq_along(nodes)){
message(paste0(i, " of ", length(nodes), ". Nodes = ", nodes[i]))
nnet_i <- train(x, y, hidden = nodes[i], iterations = 1e5)
ff_grid_i <- feedforward(x = data.matrix(grid[, c('x1', 'x2')]),
w1 = nnet_i$w1,
w2 = nnet_i$w2)
grid$class <- factor((ff_grid_i$output > .5) * 1,
labels = levels(hotdogs$class))
g <- ggplot() +
geom_raster(data = grid, aes(x1, x2, fill = as.factor(class))) +
scale_fill_manual(values = c("lightskyblue1", "tan"), name = "Beach?") +
geom_emoji(data = hotdogs[hotdogs$class == "not The Beach", ], emoji = "1f41f",
aes(x1, x2)) +
geom_emoji(data = hotdogs[hotdogs$class == "The Beach", ], emoji = "1f334",
aes(x1, x2)) +
coord_equal() +
theme_void() +
theme(plot.title = element_text(hjust = 0.5, vjust=-60),
text=element_text(size=10, family="Trebuchet MS"),
legend.position = c(1.1, 0.5)
ggsave(g, file = file.path("path....", paste0(i,".png")), width = 6.5, height = 5)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment