library(nnet)
library(caret)
## Loading required package: lattice
## Loading required package: ggplot2

Ex.1

Use the nnet package to analyze the iris data set. Use 80% of the 150 samples as the training data and the rest for validation. Discuss the results.

Solution

# iris dataset
data(iris)

set.seed(111)

partition <- sample(nrow(iris), nrow(iris)*0.80)
train <- iris[partition,]
test <- iris[-partition,]

# apply model
iris_nnet <- nnet(Species ~ ., size=2, data = train)
## # weights:  19
## initial  value 143.031042 
## iter  10 value 55.654176
## iter  20 value 24.628118
## iter  30 value 3.135566
## iter  40 value 0.026453
## final  value 0.000087 
## converged
# model summary
summary(iris_nnet)
## a 4-2-3 network with 19 weights
## options were - softmax modelling 
##   b->h1  i1->h1  i2->h1  i3->h1  i4->h1 
##   -1.44   -0.50   -1.29    0.88    2.93 
##   b->h2  i1->h2  i2->h2  i3->h2  i4->h2 
##   -1.04   -2.67   -1.44   -2.14   -1.26 
##   b->o1  h1->o1  h2->o1 
##  177.15 -468.68    2.70 
##   b->o2  h1->o2  h2->o2 
##  119.57  -44.96   -1.50 
##   b->o3  h1->o3  h2->o3 
## -297.87  513.30    0.38
# confusionMatrix
confusionMatrix(as.factor(predict(iris_nnet, test, type = 'class')), test$Species)
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         11          0         0
##   versicolor      0          6         2
##   virginica       0          1        10
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9             
##                  95% CI : (0.7347, 0.9789)
##     No Information Rate : 0.4             
##     P-Value [Acc > NIR] : 1.698e-08       
##                                           
##                   Kappa : 0.8477          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.8571           0.8333
## Specificity                 1.0000            0.9130           0.9444
## Pos Pred Value              1.0000            0.7500           0.9091
## Neg Pred Value              1.0000            0.9545           0.8947
## Prevalence                  0.3667            0.2333           0.4000
## Detection Rate              0.3667            0.2000           0.3333
## Detection Prevalence        0.3667            0.2667           0.3667
## Balanced Accuracy           1.0000            0.8851           0.8889

We can see here using nnet package we see 90% accuracy in prediction. There are 19 weights used with final value as 0.000087.

Ex.2

As a mini project, install the keras package and learn how to use it. Then, carry out various tasks that may be useful to your project and studies.

Solution

We will first install the keras package using tensorflow.

#install.packages("devtools")
#devtools::install_github("rstudio/keras")
#install_tensorflow()
library(keras)
library(tensorflow)
## 
## Attaching package: 'tensorflow'
## The following object is masked from 'package:caret':
## 
##     train

We will use here MNIST dataset from keras recognizing handwritten digits. MNIST dataset includes 28 x 28 grayscale images of handwritten digits. This dataset includes images labels as well to recognize the digit.

mnist <- dataset_mnist()
## Loaded Tensorflow version 2.7.0
# train and test data
img_training <- mnist$train$x
label_training <- mnist$train$y
img_testing <- mnist$test$x
label_testing <- mnist$test$y

Seeing the dimension of training and testing images, there are 60K images for training and 10k images for testing.

dim(img_training)
## [1] 60000    28    28
dim(img_testing)
## [1] 10000    28    28

Here is an example of 17th image from training set.

# 17th image
digit <- img_training[17, 1:28, 1:28]
# set the parameter- "s" for square plotting region
par(pty="s")
image(t(digit), col=gray.colors(256))

As we seen above, the x data is a three dim array (images, width, height) that would be reshaped in single dimension (28x28 into a single object of length 784). Next we will convert grayscale values from integers (between 0 and 255) into floating values between 0 and 1. Next is y data that is integer values between 0 and 9 and it will be one hot encoded for training.

# reshaping
img_training <- array_reshape(img_training, c(nrow(img_training), 784))
img_testing <- array_reshape(img_testing, c(nrow(img_testing), 784))
# reacaling
img_training <- img_training / 255
img_testing <- img_testing / 255

# one-hot encoded
label_training <- to_categorical(label_training, 10)
label_testing <- to_categorical(label_testing, 10)

Next we will create the sequential model and add layers into it. We have 3 layers here by providing input shape on the first one. we have used activation functions in first 2 layers as relu followed by softmax in final one.

model <- keras_model_sequential()
model %>% 
  layer_dense(units = 256, activation = "relu", input_shape = c(784)) %>% 
  layer_dense(units = 128, activation = "relu") %>% 
  layer_dense(units = 10, activation = "softmax")

summary(model)
## Model: "sequential"
## ________________________________________________________________________________
##  Layer (type)                       Output Shape                    Param #     
## ================================================================================
##  dense_2 (Dense)                    (None, 256)                     200960      
##                                                                                 
##  dense_1 (Dense)                    (None, 128)                     32896       
##                                                                                 
##  dense (Dense)                      (None, 10)                      1290        
##                                                                                 
## ================================================================================
## Total params: 235,146
## Trainable params: 235,146
## Non-trainable params: 0
## ________________________________________________________________________________

Next we will compile the model.

# compile
model %>% compile(loss="categorical_crossentropy", optimizer=optimizer_rmsprop(), metrics=c("accuracy"))

Next we will use fit() function to train the model with 25 epochs and batches of 128 images.

set.seed(609)

hist <- model %>% fit(
  img_training, 
  label_training, 
  epochs=25,
  batch_size=128,
  validation_split=0.2
)
plot(hist)
## `geom_smooth()` using formula 'y ~ x'

Here is loss and accuracy of model trained above.

# eval loss and accuracy
model %>% evaluate(img_testing, label_testing)
##      loss  accuracy 
## 0.1570612 0.9797000

Now we will do final predictions from trained model.

# predicted classes
predictions <- model %>% predict(img_testing)
head(predictions)
##              [,1]         [,2]         [,3]         [,4]         [,5]
## [1,] 1.574847e-24 3.962364e-26 3.866009e-22 6.451014e-14 2.442747e-38
## [2,] 6.157889e-37 3.802350e-18 1.000000e+00 2.023680e-30 0.000000e+00
## [3,] 2.293792e-18 1.000000e+00 8.394346e-10 1.312174e-18 9.173065e-13
## [4,] 1.000000e+00 5.766372e-18 1.914671e-11 3.442802e-16 2.559265e-15
## [5,] 1.155850e-15 2.575838e-22 2.955199e-20 1.114598e-22 1.000000e+00
## [6,] 4.478823e-20 1.000000e+00 2.342136e-14 2.130457e-22 1.178627e-12
##              [,6]         [,7]         [,8]         [,9]        [,10]
## [1,] 6.117188e-25 0.000000e+00 1.000000e+00 9.778809e-27 4.819179e-18
## [2,] 1.188160e-36 8.256279e-36 3.787849e-38 1.662353e-26 0.000000e+00
## [3,] 7.565895e-16 7.558402e-14 1.683266e-09 2.542041e-09 5.940394e-17
## [4,] 3.648093e-23 2.088033e-13 7.842533e-13 9.809761e-24 3.881137e-16
## [5,] 1.360480e-24 4.402056e-21 4.679302e-13 2.265037e-18 2.934038e-08
## [6,] 5.101568e-21 2.466076e-18 1.958639e-09 1.427250e-11 1.210071e-19

During this study we have learned how to create keras sequential model, split the mnist dataset in train and test, reshape the data, fit the data into model and then do predictions. I see keras as a very good tool to used in future projects.