This is a binary image classification Nerual Net made with the Keras API. There are a bunch of ways to do this like with the Generator functions but this what felt most natural to me at the time of writing this.
I pulled 10 photos of cats and humans from google and saved them as .jpg. Although this is a super small data set, the goal is to use 16 photos as a training set to predict the outcome of the 4 photos in the test set.
library(reticulate)
library(tidyverse)
## -- Attaching packages -------------------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.2 v purrr 0.3.4
## v tibble 3.0.3 v dplyr 1.0.1
## v tidyr 1.1.1 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.5.0
## -- Conflicts ----------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(tensorflow)
library(keras)
library(magick)
## Linking to ImageMagick 6.9.9.14
## Enabled features: cairo, freetype, fftw, ghostscript, lcms, pango, rsvg, webp
## Disabled features: fontconfig, x11
use_condaenv("r-reticulate", required = TRUE)
cat = image_read("C:\\Users\\spenc\\Desktop\\nn_pics2\\training\\01.jpg")
human = image_read("C:\\Users\\spenc\\Desktop\\nn_pics2\\training\\09.jpg")
plot(cat)
plot(human)
trainpics = list.files("C:\\Users\\spenc\\Desktop\\nn_pics2\\training",
full.names = TRUE)
#Instead of using loops, the apply functions work great here
loadpics = function(filenames) {
a = lapply(filenames, image_load, grayscale = TRUE) #grayscale the image
b = lapply(a, image_to_array) #turns it into an array
c = lapply(b,image_array_resize, height = 100, width = 100) #resize
d = normalize(c, axis = 1) #normalize to make small numbers
return(d)}
trainx =loadpics(trainpics) #loads training files
testpics = list.files("C:\\Users\\spenc\\Desktop\\nn_pics2\\test",
full.names = TRUE)
testx = loadpics(testpics) # load test files
trainy = c(0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1)
testy = c(0,0,1,1)
trainlabel = to_categorical(trainy)
testlabel = to_categorical(testy)
model1 = keras_model_sequential()
model1 %>%
layer_flatten() %>%
layer_dense(units = 128, activation = 'relu') %>%
layer_dense(units = 128, activation = 'relu')%>%
layer_dense(units = 2, activation = 'softmax')
# For the last layer, you could also try a sigmoid activation with 1 unit.
model1 %>%
compile (optimizer = 'adam',loss = 'binary_crossentropy',
metrics = c('accuracy'))
#If you had more than 2 categories, then you would want to use categorical_crossentropy for the loss function
fit1 = model1 %>%
fit(x = trainx, y = trainlabel, epochs = 15, batch_size=32 ,
validation_split = .1, callbacks = callback_tensorboard("logs/run_a"))
#the callback just lets me view the model in tensorboard
#an epoch is how many times the model trains
plot(fit1)
## `geom_smooth()` using formula 'y ~ x'
# Evaluate Training Data
model1 %>%
evaluate(trainx,trainlabel)
## loss accuracy
## 0.1146009 1.0000000
# Evaluate Test Data
model1 %>%
evaluate(testx,testlabel)
## loss accuracy
## 0.9901535 0.7500000
predictedclasses1 = model1 %>%
predict_classes(testx)
table(Prediction = predictedclasses1, Actual = testy)
## Actual
## Prediction 0 1
## 0 1 0
## 1 1 2
#tensorboard("logs/run_a") - If you want to check your runs in Tensorboard
#save_model_tf(model1, "model1") - save the model