Automated Identification of Fall Armyworm (Spodoptera frugiperda) using Computer Vision and Machine Learning

Ivan Hiltpold and Zachary Ladin

03 July 2018


Overview

Machine learning and computer vision have recently become widely accessible to researchers, and can be successfully applied to critical-need areas of research and conservation. In particular, these methods show amazing promise in their applications within precision agriculture, specifically for the automated detection of pest species. This R script, written by Dr. Zach Ladin, shows how we can compile images scraped from the web, label those images, and sort into training and test data sets. Subsequently, these data were used to build a classifier (using a convolutional neural network) for identifying the fall armyworm (Spodoptera frugiperda) and distinguishing it from other pest insect larvae that was implemented in TensorFlow. Early detection of fall armyworm in Africa has reached international concern, as evidenced by current initiatives from the Gates Foundation, USAID, Feed the Future (US Gov’t), and others. In a collaborative effort, Drs. Ladin, Hiltpold, and partners from private industry (i.e., Bioverse Labs, Inc.) have recently begun working on the development of automated pest detection models for precision agriculture-based applications that are currently of high-need internationally, as well as here in Delaware.

Results

Compile first experimental results

exp.1.results<-data.frame(
  Image_Cropped=c("No","No","No","No","No","No","Yes","Yes","Yes","Yes","Yes","Yes"), 
  Model=c("FA_TH_CE_AA", "FA_TH_CE", "FA_TH","FA_AA","FA_CE","FA_Other","FA_TH_CE_AA", "FA_TH_CE", "FA_TH","FA_AA","FA_CE","FA_Other"), 
  Num_Classes=c(4, 3, 2, 2,2,2,4, 3, 2, 2,2,2),Num_Training_images=c(350, 350, 350, 350,NA,NA, 225, 225, 225,225,225,225), 
  Model_Accuracy =c(0.251, 0.357, 0.701, 0.562,NA, NA, 0.253, 0.51, 0.967, 0.774, 0.88, 0.85))

exp.sort<-exp.1.results[order(exp.1.results$Model_Accuracy, decreasing=FALSE),]
exp.sort$Model<-factor(exp.sort$Model, levels=rev(c("FA_Other", "FA_TH", "FA_CE", "FA_AA", "FA_TH_CE", "FA_TH_CE_AA")))

#unique(exp.sort$Model)
library(ggplot2)

plot1<- ggplot(data=exp.sort, aes(x=Model, y=Model_Accuracy))+
  coord_flip()+
  geom_bar(stat="identity",aes(fill=Image_Cropped), alpha=0.7, position = position_dodge())+
  scale_fill_manual(values=c('red','royalblue3'))+
  theme(panel.border=element_rect(color="black",fill="transparent"),
        axis.text.x=element_text(size=14),
        axis.text.y=element_text(size=14),
        plot.title=element_text(size=12))+
  ggtitle("Comparison of classifiers for Fall Armyworm (FA),\nTobacco Hornworm (TH), Corn Earworm (CE),\nAfrican Armyworm(AA), and Other (TH, CE, and AA combind).\nBlue and red bars show if images were cropped\nor not, respectively.")

print(plot1)

Save figure

#setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector")

#dir.create("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector/Results")

#ggsave(plot1, file=paste(getwd(),"Results","FAW_detector_results.png",sep="/"),width=8, height=8)

Build function to download species images from google

getGoogleImages<-function(subject, numImages){
  
  folderName<-gsub(" ","_", as.character(subject))
  
  #make folder name
  myFilepath<-paste("/Users/zach/Dropbox (ZachTeam)/Projects", "Fall_Armyworm", sep="/")
  
  #create new project folder
  dir.create(paste("/Users/zach/Dropbox (ZachTeam)/Projects","Fall_Armyworm",sep="/"))
  
  #create sub folder for detector
  dir.create(paste(myFilepath, paste("Fall_Armyworm", "detector",sep="_"),sep="/"))
  
  #create subfolder for copying scraped images
  dir.create(paste(myFilepath, paste("Fall_Armyworm", "detector",sep="_"),"Images",sep="/"))
  
  
  #set working directrory to where image_downloader.py is sitting
  setwd(paste("/Users/zach/Dropbox (ZachTeam)/Projects","Fall_Armyworm", paste("Fall_Armyworm", "detector",sep="_"),"Image_scraping/Image-Downloader-master",sep="/"))
  
  message("Downloading images now.")
  #Call the python script image_downloader.py and run query in bash using system()
  system(paste("/anaconda/bin/python image_downloader.py --engine Google --max-number ", numImages, ' "', as.character(subject),'"',sep=""))

#set working directory
setwd(paste(myFilepath, paste("Fall_Armyworm", "detector",sep="_"),sep="/"))
dir()
#move files to new folder

# identify the folders
current.folder <- paste(myFilepath, paste("Fall_Armyworm", "detector",sep="_"), "/Image_scraping/Image-Downloader-master/download_images",sep="/")

#make new folder (example FAW)
dir.create(paste(myFilepath, paste("Fall_Armyworm", "detector",sep="_"),"Images", paste(folderName,"images",sep="_"),sep="/"))

#set new folder where files will be copied
new.folder <- paste(myFilepath, paste("Fall_Armyworm", "detector",sep="_"),"Images", paste(folderName,"images",sep="_"),sep="/")

# find the files that you want
list.of.files <- list.files(current.folder, pattern=".*.jpeg",full.names=TRUE)
message("Copying images now.")
# copy the files to the new folder
file.copy(list.of.files, new.folder)

#remove files from download_images
do.call(file.remove, list(list.files(current.folder, full.names = TRUE)))

}

Test function getGoogleImages

#Fall Armyworm
getGoogleImages(subject = "Fall Armyworm", numImages = 10)

#African Armyworm
getGoogleImages(subject="African Armyworm", numImages=550)

#Tobacco Hornworm
getGoogleImages(subject="Tobacco Hornworm", numImages=550)

#Corn Earworm
getGoogleImages(subject="Corn Earworm", numImages=550)

Build function getImagesURL

#set working directory
setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm")

getImagesURL<-function(keywords,website){
  
  typeList<-keywords
  
  for(j in 1:length(typeList)){
    
    
    typeName<-gsub(" ","_",typeList[j])
    
    dir.create(paste(getwd(), "Fall_Armyworm_detector","Images",sep="/"))
    dir.create(paste(getwd(), "Fall_Armyworm_detector","Images",typeName,sep="/"))
    
    #separate typeList object with "+"
    
    searchTerm<-gsub(" ","+",typeList[j])
    
    images <- lapply(paste0(paste(website, searchTerm, sep=""), 1:2),
                     function(url){
                       page <- read_html(url,options="HUGE")
                       nodes <- html_nodes(page, xpath = '//*/img')
                     })
    
    
    
    jpgURLs<-list()
    for(i in 1:length(images)){
      new.images<-images[[i]]
      jpgList<-new.images[grep("/images", new.images)]
      for(k in 1:length(jpgList)){
        test <- jpgList[k] %>% html_attr('src')
        jpgURLs<-c(jpgURLs,test)
      }
    }
    
    
    message("Downloading images now.")
    for(k in 1:length(jpgURLs)){
      test1<-jpgURLs[[k]]
      GET(test1, write_disk(paste(getwd(),"Fall_Armyworm_detector", "Images", typeName, paste(typeName, k, "jpg", sep="."),sep="/")))
    }
  }
}

Test function getImagesURL

getImagesURL(keywords = c("Agrilus planipennis"), website="https://www.ipmimages.org/search/action.cfm?q=")

Double sample size by creating mirror-images of each image

library(imager)
library(raster)

# identify the folders
objectNameList<-c("Fall_Armyworm","Tobacco_Hornworm", "Corn_Earworm", "African_Armyworm")

#Create mirror images of all saved images and save them in folder (double the sample size)
for(i in 1:length(objectNameList)){
  setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector")
  
  current.folder <- paste(getwd(),"Images", paste(objectNameList[i],"images",sep="_"), sep="/")
  
  # find the files that you want
  list.of.files <- list.files(current.folder,full.names=TRUE)

  #create mirror images and save 
  for(j in 1:length(list.of.files)){
    
    #get dimensions of original image
    new.jpeg<-readJPEG(list.of.files[j])
    org.w<-ncol(new.jpeg)
    org.h<-nrow(new.jpeg)
    
    temp<-load.image(list.of.files[j])
    
    #create mirror of image
    temp.mirror<-mirror(temp,"x")
    dim(temp.mirror)
    
    #save image
    jpeg(filename=paste(current.folder,paste("mirror_image",j,"jpeg",sep="."),sep="/"),width=org.w, height=org.h)
    
    #plot.new()
    par(mar=c(0,0,0,0), oma=c(0,0,0,0), mai=c(0,0,0,0))
    plot(temp.mirror, bg=FALSE, bty ="n",axes=F, frame=F, xaxt='n', yaxt='n', ann=FALSE, yaxt='n',ncol=org.h,nrow=org.w)
    
    plot.window(xlim=extent(c(0,org.h,0,org.w))[1:2], ylim=extent(c(0,org.h,0,org.h))[3:4], xaxs="i",yaxs="i")
    
    dev.off()
    graphics.off()
  }
  
}

Rename all files in Images and subfolders to standardize the file extension.

# identify the folders
objectNameList<-c("Fall_Armyworm","Tobacco_Hornworm", "Corn_Earworm","African_Armyworm")


for(i in 1:length(objectNameList)){
  setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector")
  
  current.folder <- paste(getwd(),"Images", paste(objectNameList[i],"images",sep="_"), sep="/")
  
    # find the files that you want
  list.of.files <- list.files(current.folder,full.names=TRUE)
  
  #generate new list of files
  new.list.of.files<-gsub("jpg","jpeg",list.of.files)
  #set wd to current.folder
  setwd(current.folder)
  
  file.rename(from=list.of.files, to=new.list.of.files)
  
}

Set up training and test data for CNN

#set working directory
setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector")

#make new folders to store images
dir.create(paste(getwd(),"CNN",sep="/"))
dir.create(paste(getwd(),"CNN","dataset",sep="/"))
dir.create(paste(getwd(),"CNN","dataset","test_set",sep="/"))
dir.create(paste(getwd(),"CNN","dataset","training_set",sep="/"))

##################################################################################################
#Make binomial classifier (FA or NOT FA)

#combine classes' pictures into one 'other'Other' folder (add  of each into Other)
setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector")

#create new Other folder
dir.create("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector/Images/Other")

objectNameList<-c("Tobacco_Hornworm", "Corn_Earworm", "African_Armyworm")

for(i in 1:length(objectNameList)){
  
  setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector")
  # identify the folders
  current.folder <- paste("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector","Images", paste(objectNameList[i],"images",sep="_"), sep="/")
  #set new folder where files will be copied
  new.folder <- "/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector/Images/Other_images"
  numFiles<-100
  # find the files that you want
  list.of.files <- list.files(current.folder,full.names=TRUE)[1:numFiles]
  length(list.of.files)
  # copy the files to the new folder
  file.copy(list.of.files, new.folder)
  #new.list.of.files<-list.files(new.folder)
  setwd(new.folder)
  file.rename(from=list.of.files, to=paste(new.folder, paste( objectNameList[i], 1:length(list.of.files),"jpeg", sep="."),sep="/"))
  
}

Rename Other folder to category (assign random numbers to mix sorted order)

setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector")

folder<-paste("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector","Images", "Other_images",sep="/")
setwd(folder)
files <- list.files(folder)
randSeq<-sample(seq(1, length(files)),replace=FALSE)

file.rename(from=files, to= paste("Other", randSeq ,"jpeg", sep="."))

#now copy files into CNN group folders ()

# identify the folders
objectNameList<-c("Fall_Armyworm","Tobacco_Hornworm", "Corn_Earworm", "African_Armyworm")

objectNameList<-c("Other")

#Training data (225 images)
for(i in 1:length(objectNameList)){
  setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector")
  
  #create new folder
  dir.create(paste(getwd(),"CNN","dataset","training_set",objectNameList[i], sep="/"))
  
  current.folder <- paste(getwd(),"Images", paste(objectNameList[i],"images",sep="_"), sep="/")
  #set new folder where files will be copied
  new.folder <- paste(getwd(),"CNN","dataset","training_set", objectNameList[i], sep="/")
  numFiles<-225
  # find the files that you want
  list.of.files <- list.files(current.folder,full.names=TRUE)[1:numFiles]
  # copy the files to the new folder
  file.copy(list.of.files, new.folder)
  #rename files in ascending order
  setwd(new.folder)
  files <- list.files(new.folder, full.names=TRUE)
  file.rename(from=files, to=paste(objectNameList[i], 1:length(files),"jpeg", sep="."))
}


#Test data (75 images)
for(i in 1:length(objectNameList)){
  setwd("/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector")
  
  #create new folder
  dir.create(paste(getwd(),"CNN","dataset","test_set",objectNameList[i], sep="/"))
  
  current.folder <- paste(getwd(),"Images", paste(objectNameList[i],"images",sep="_"), sep="/")
  #set new folder where files will be copied
  new.folder <- paste(getwd(),"CNN","dataset","test_set",objectNameList[i], sep="/")
  numFiles<-225+75
  # find the files that you want
  list.of.files <- list.files(current.folder,full.names=TRUE)[226:numFiles]
  # copy the files to the new folder
  file.copy(list.of.files, new.folder)
  #rename files in ascending order
  setwd(new.folder)
  files <- list.files(new.folder,full.names=TRUE)
  file.rename(from=files, to=paste(objectNameList[i], 226:numFiles,"jpeg", sep="."))
  
}

Now run Tensor flow from python script (cnn_FAW.py)

setwd('/Users/zach/Dropbox (ZachTeam)/Projects/Fall_Armyworm/Fall_Armyworm_detector/CNN')

system("/anaconda/bin/python cnn_faw.py")

Results from machine learning models

#Experiment with no cropping images to extent of caterpillars

#after inital run (4 classes w/both armyworms)
# Found 1400 images belonging to 4 classes.
# Found 200 images belonging to 4 classes.
# Epoch 1/10
# 1000/1000 [==============================] - 711s - loss: -7.9459 - acc: 0.2499 - val_loss: -7.9935 - val_acc: 0.2500
# Epoch 2/10
# 1000/1000 [==============================] - 721s - loss: -7.9788 - acc: 0.2499 - val_loss: -7.9378 - val_acc: 0.2493
# Epoch 3/10
# 1000/1000 [==============================] - 710s - loss: -7.9714 - acc: 0.2504 - val_loss: -7.9656 - val_acc: 0.2507
# Epoch 4/10
# 1000/1000 [==============================] - 768s - loss: -7.9632 - acc: 0.2497 - val_loss: -8.0491 - val_acc: 0.2497
# Epoch 5/10
# 1000/1000 [==============================] - 752s - loss: -7.9724 - acc: 0.2501 - val_loss: -7.9993 - val_acc: 0.2500
# Epoch 6/10
# 1000/1000 [==============================] - 749s - loss: -7.9753 - acc: 0.2496 - val_loss: -7.9211 - val_acc: 0.2500
# Epoch 7/10
# 1000/1000 [==============================] - 765s - loss: -7.9604 - acc: 0.2501 - val_loss: -8.0269 - val_acc: 0.2503
# Epoch 8/10
# 1000/1000 [==============================] - 738s - loss: -7.9641 - acc: 0.2500 - val_loss: -7.8988 - val_acc: 0.2497
# Epoch 9/10
# 1000/1000 [==============================] - 756s - loss: -7.9812 - acc: 0.2503 - val_loss: -8.0213 - val_acc: 0.2493
# Epoch 10/10
# 1000/1000 [==============================] - 745s - loss: -7.9704 - acc: 0.2499 - val_loss: -7.9600 - val_acc: 0.2500


#Run with 3 categories (FAW, Hornworm, and earworm, still very poor)
# Found 1050 images belonging to 3 classes.
# Found 150 images belonging to 3 classes.
# Epoch 1/10
# 100/100 [==============================] - 114s - loss: -1.7512 - acc: 0.3511 - val_loss: -1.4011 - val_acc: 0.3400
# Epoch 2/10
# 100/100 [==============================] - 106s - loss: -3.2300 - acc: 0.4287 - val_loss: -1.6998 - val_acc: 0.3550
# Epoch 3/10
# 100/100 [==============================] - 99s - loss: -3.5161 - acc: 0.4506 - val_loss: -2.1452 - val_acc: 0.3567
# Epoch 4/10
# 100/100 [==============================] - 98s - loss: -3.5151 - acc: 0.4693 - val_loss: -1.6191 - val_acc: 0.3337
# Epoch 5/10
# 100/100 [==============================] - 97s - loss: -3.6940 - acc: 0.4744 - val_loss: -1.8452 - val_acc: 0.3323
# Epoch 6/10
# 100/100 [==============================] - 96s - loss: -3.8326 - acc: 0.4867 - val_loss: -2.2927 - val_acc: 0.3333
# Epoch 7/10
# 100/100 [==============================] - 96s - loss: -4.0205 - acc: 0.5106 - val_loss: -2.1816 - val_acc: 0.3520
# Epoch 8/10
# 100/100 [==============================] - 99s - loss: -4.1505 - acc: 0.5096 - val_loss: -2.1966 - val_acc: 0.3360
# Epoch 9/10
# 100/100 [==============================] - 98s - loss: -4.0236 - acc: 0.4966 - val_loss: -1.8774 - val_acc: 0.3333
# Epoch 10/10
# 100/100 [==============================] - 95s - loss: -4.0412 - acc: 0.5220 - val_loss: -2.1833 - val_acc: 0.3413

#Run 2 categories (FAW vs. Tobacco Hornworm)
# Found 700 images belonging to 2 classes.
# Found 100 images belonging to 2 classes.
# Epoch 1/10
# 100/100 [==============================] - 108s - loss: 0.4291 - acc: 0.7936 - val_loss: 1.0765 - val_acc: 0.7000
# Epoch 2/10
# 100/100 [==============================] - 95s - loss: 0.2746 - acc: 0.8867 - val_loss: 1.2379 - val_acc: 0.7012
# Epoch 3/10
# 100/100 [==============================] - 94s - loss: 0.2149 - acc: 0.9120 - val_loss: 2.2587 - val_acc: 0.6696
# Epoch 4/10
# 100/100 [==============================] - 94s - loss: 0.1674 - acc: 0.9338 - val_loss: 2.3793 - val_acc: 0.6812
# Epoch 5/10
# 100/100 [==============================] - 94s - loss: 0.1306 - acc: 0.9502 - val_loss: 3.4082 - val_acc: 0.6700
# Epoch 6/10
# 100/100 [==============================] - 95s - loss: 0.1007 - acc: 0.9642 - val_loss: 3.6705 - val_acc: 0.6596
# Epoch 7/10
# 100/100 [==============================] - 95s - loss: 0.0795 - acc: 0.9718 - val_loss: 4.0860 - val_acc: 0.6584
# Epoch 8/10
# 100/100 [==============================] - 95s - loss: 0.0768 - acc: 0.9707 - val_loss: 4.4710 - val_acc: 0.6600
# Epoch 9/10
# 100/100 [==============================] - 97s - loss: 0.0466 - acc: 0.9858 - val_loss: 4.2385 - val_acc: 0.6600
# Epoch 10/10
# 100/100 [==============================] - 96s - loss: 0.0486 - acc: 0.9833 - val_loss: 3.9720 - val_acc: 0.6720


#Run 2 categories (FAW vs. African armyworm)
# Found 700 images belonging to 2 classes.
# Found 100 images belonging to 2 classes.
# Epoch 1/10
# 100/100 [==============================] - 72s - loss: 0.6970 - acc: 0.5074 - val_loss: 0.6997 - val_acc: 0.5300
# Epoch 2/10
# 100/100 [==============================] - 68s - loss: 0.6867 - acc: 0.5466 - val_loss: 0.6891 - val_acc: 0.5616
# Epoch 3/10
# 100/100 [==============================] - 67s - loss: 0.6850 - acc: 0.5395 - val_loss: 0.6878 - val_acc: 0.5292
# Epoch 4/10
# 100/100 [==============================] - 71s - loss: 0.6797 - acc: 0.5620 - val_loss: 0.6865 - val_acc: 0.5296
# Epoch 5/10
# 100/100 [==============================] - 70s - loss: 0.6674 - acc: 0.5781 - val_loss: 0.6798 - val_acc: 0.5700
# Epoch 6/10
# 100/100 [==============================] - 68s - loss: 0.6637 - acc: 0.5820 - val_loss: 0.6839 - val_acc: 0.5396
# Epoch 7/10
# 100/100 [==============================] - 68s - loss: 0.6574 - acc: 0.5862 - val_loss: 0.6907 - val_acc: 0.5204
# Epoch 8/10
# 100/100 [==============================] - 66s - loss: 0.6509 - acc: 0.6013 - val_loss: 0.7030 - val_acc: 0.5112
# Epoch 9/10
# 100/100 [==============================] - 65s - loss: 0.6454 - acc: 0.6081 - val_loss: 0.7151 - val_acc: 0.5400
# Epoch 10/10
# 100/100 [==============================] - 65s - loss: 0.6376 - acc: 0.6220 - val_loss: 0.7151 - val_acc: 0.4924

##################################################################################################
##################################################################################################

#Experiment all images were cropped so that 

#Full (FA, TH, CE, and  AA, 4 classes)
# Found 900 images belonging to 4 classes.
# Found 300 images belonging to 4 classes.
# Epoch 1/10
# 100/100 [==============================] - 43s - loss: -7.6707 - acc: 0.2497 - val_loss: -7.9712 - val_acc: 0.2500
# Epoch 2/10
# 100/100 [==============================] - 41s - loss: -7.8662 - acc: 0.2571 - val_loss: -7.9659 - val_acc: 0.2500
# Epoch 3/10
# 100/100 [==============================] - 41s - loss: -8.3229 - acc: 0.2494 - val_loss: -7.9818 - val_acc: 0.2473
# Epoch 4/10
# 100/100 [==============================] - 39s - loss: -7.7434 - acc: 0.2578 - val_loss: -8.0190 - val_acc: 0.2527
# Epoch 5/10
# 100/100 [==============================] - 41s - loss: -7.7434 - acc: 0.2426 - val_loss: -7.8490 - val_acc: 0.2463
# Epoch 6/10
# 100/100 [==============================] - 39s - loss: -7.8092 - acc: 0.2587 - val_loss: -8.0190 - val_acc: 0.2510
# Epoch 7/10
# 100/100 [==============================] - 40s - loss: -8.1036 - acc: 0.2435 - val_loss: -7.9499 - val_acc: 0.2497
# Epoch 8/10
# 100/100 [==============================] - 39s - loss: -8.1545 - acc: 0.2500 - val_loss: -7.9340 - val_acc: 0.2527
# Epoch 9/10
# 100/100 [==============================] - 40s - loss: -8.0107 - acc: 0.2481 - val_loss: -7.9871 - val_acc: 0.2477
# Epoch 10/10
# 100/100 [==============================] - 41s - loss: -7.8722 - acc: 0.2513 - val_loss: -7.9393 - val_acc: 0.2497

#FA, TH, and CE (3 classes)
# Found 675 images belonging to 3 classes.
# Found 225 images belonging to 3 classes.
# Epoch 1/10
# 100/100 [==============================] - 45s - loss: -2.4853 - acc: 0.4059 - val_loss: -3.4484 - val_acc: 0.4491
# Epoch 2/10
# 100/100 [==============================] - 42s - loss: -3.6755 - acc: 0.4507 - val_loss: -3.7545 - val_acc: 0.4580
# Epoch 3/10
# 100/100 [==============================] - 42s - loss: -4.0944 - acc: 0.4797 - val_loss: -3.8215 - val_acc: 0.4353
# Epoch 4/10
# 100/100 [==============================] - 42s - loss: -4.0974 - acc: 0.4778 - val_loss: -3.6936 - val_acc: 0.4262
# Epoch 5/10
# 100/100 [==============================] - 42s - loss: -4.1936 - acc: 0.5058 - val_loss: -3.4773 - val_acc: 0.4887
# Epoch 6/10
# 100/100 [==============================] - 42s - loss: -4.0872 - acc: 0.5107 - val_loss: -3.2292 - val_acc: 0.4618
# Epoch 7/10
# 100/100 [==============================] - 42s - loss: -4.4899 - acc: 0.5306 - val_loss: -4.0785 - val_acc: 0.4423
# Epoch 8/10
# 100/100 [==============================] - 43s - loss: -4.7211 - acc: 0.5462 - val_loss: -4.3031 - val_acc: 0.4947
# Epoch 9/10
# 100/100 [==============================] - 42s - loss: -4.6141 - acc: 0.5477 - val_loss: -3.9787 - val_acc: 0.4752
# Epoch 10/10
# 100/100 [==============================] - 41s - loss: -4.8115 - acc: 0.5729 - val_loss: -4.2051 - val_acc: 0.5102



#FA vs. TH
# Found 450 images belonging to 2 classes.
# Found 150 images belonging to 2 classes.
# Epoch 1/10
# 100/100 [==============================] - 50s - loss: 0.5900 - acc: 0.6762 - val_loss: 0.3609 - val_acc: 0.8267
# Epoch 2/10
# 100/100 [==============================] - 46s - loss: 0.2438 - acc: 0.9087 - val_loss: 0.2120 - val_acc: 0.9200
# Epoch 3/10
# 100/100 [==============================] - 46s - loss: 0.1747 - acc: 0.9307 - val_loss: 0.1738 - val_acc: 0.9257
# Epoch 4/10
# 100/100 [==============================] - 45s - loss: 0.1256 - acc: 0.9488 - val_loss: 0.1494 - val_acc: 0.9600
# Epoch 5/10
# 100/100 [==============================] - 45s - loss: 0.0784 - acc: 0.9765 - val_loss: 0.1267 - val_acc: 0.9397
# Epoch 6/10
# 100/100 [==============================] - 45s - loss: 0.0396 - acc: 0.9912 - val_loss: 0.1225 - val_acc: 0.9533
# Epoch 7/10
# 100/100 [==============================] - 46s - loss: 0.0927 - acc: 0.9641 - val_loss: 0.1782 - val_acc: 0.9413
# Epoch 8/10
# 100/100 [==============================] - 49s - loss: 0.0306 - acc: 0.9925 - val_loss: 0.1397 - val_acc: 0.9597
# Epoch 9/10
# 100/100 [==============================] - 49s - loss: 0.0226 - acc: 0.9941 - val_loss: 0.0985 - val_acc: 0.9663
# Epoch 10/10
# 100/100 [==============================] - 48s - loss: 0.0165 - acc: 0.9969 - val_loss: 0.0925 - val_acc: 0.9670

#FA vs. AA
# Found 450 images belonging to 2 classes.
# Found 150 images belonging to 2 classes.
# Epoch 1/10
# 100/100 [==============================] - 27s - loss: 0.6984 - acc: 0.5188 - val_loss: 0.6862 - val_acc: 0.5533
# Epoch 2/10
# 100/100 [==============================] - 26s - loss: 0.6757 - acc: 0.5478 - val_loss: 0.6692 - val_acc: 0.6353
# Epoch 3/10
# 100/100 [==============================] - 26s - loss: 0.6547 - acc: 0.5851 - val_loss: 0.6614 - val_acc: 0.6137
# Epoch 4/10
# 100/100 [==============================] - 25s - loss: 0.6236 - acc: 0.6301 - val_loss: 0.6534 - val_acc: 0.6170
# Epoch 5/10
# 100/100 [==============================] - 26s - loss: 0.5741 - acc: 0.7115 - val_loss: 0.6525 - val_acc: 0.6733
# Epoch 6/10
# 100/100 [==============================] - 25s - loss: 0.5205 - acc: 0.7425 - val_loss: 0.6508 - val_acc: 0.7067
# Epoch 7/10
# 100/100 [==============================] - 24s - loss: 0.4869 - acc: 0.7631 - val_loss: 0.6549 - val_acc: 0.7193
# Epoch 8/10
# 100/100 [==============================] - 25s - loss: 0.4375 - acc: 0.8134 - val_loss: 0.5918 - val_acc: 0.7350
# Epoch 9/10
# 100/100 [==============================] - 25s - loss: 0.3788 - acc: 0.8393 - val_loss: 0.5484 - val_acc: 0.7740
# Epoch 10/10
# 100/100 [==============================] - 25s - loss: 0.3376 - acc: 0.8606 - val_loss: 0.5543 - val_acc: 0.7533


#FA vs. CE
# Found 450 images belonging to 2 classes.
# Found 150 images belonging to 2 classes.
# Epoch 1/10
# 100/100 [==============================] - 32s - loss: 0.6197 - acc: 0.6704 - val_loss: 0.5651 - val_acc: 0.7000
# Epoch 2/10
# 100/100 [==============================] - 30s - loss: 0.5116 - acc: 0.7571 - val_loss: 0.5422 - val_acc: 0.7197
# Epoch 3/10
# 100/100 [==============================] - 31s - loss: 0.4730 - acc: 0.7862 - val_loss: 0.5752 - val_acc: 0.6880
# Epoch 4/10
# 100/100 [==============================] - 32s - loss: 0.3670 - acc: 0.8375 - val_loss: 0.5692 - val_acc: 0.7130
# Epoch 5/10
# 100/100 [==============================] - 31s - loss: 0.3399 - acc: 0.8498 - val_loss: 0.4521 - val_acc: 0.7870
# Epoch 6/10
# 100/100 [==============================] - 31s - loss: 0.2262 - acc: 0.9106 - val_loss: 0.4305 - val_acc: 0.8200
# Epoch 7/10
# 100/100 [==============================] - 31s - loss: 0.1707 - acc: 0.9297 - val_loss: 0.3973 - val_acc: 0.8213
# Epoch 8/10
# 100/100 [==============================] - 31s - loss: 0.0900 - acc: 0.9740 - val_loss: 0.3337 - val_acc: 0.8803
# Epoch 9/10
# 100/100 [==============================] - 32s - loss: 0.0800 - acc: 0.9706 - val_loss: 0.3497 - val_acc: 0.8797
# Epoch 10/10
# 100/100 [==============================] - 32s - loss: 0.1176 - acc: 0.9525 - val_loss: 0.4441 - val_acc: 0.7930

#FA vs. Other (TH, CE, and AA)
# Found 428 images belonging to 2 classes.
# Found 150 images belonging to 2 classes.
# Epoch 1/10
# 100/100 [==============================] - 32s - loss: 0.6439 - acc: 0.6013 - val_loss: 0.6151 - val_acc: 0.6067
# Epoch 2/10
# 100/100 [==============================] - 29s - loss: 0.5369 - acc: 0.7241 - val_loss: 0.5494 - val_acc: 0.7330
# Epoch 3/10
# 100/100 [==============================] - 29s - loss: 0.4850 - acc: 0.7637 - val_loss: 0.5380 - val_acc: 0.7280
# Epoch 4/10
# 100/100 [==============================] - 30s - loss: 0.4116 - acc: 0.8130 - val_loss: 0.4816 - val_acc: 0.7870
# Epoch 5/10
# 100/100 [==============================] - 33s - loss: 0.3216 - acc: 0.8648 - val_loss: 0.4588 - val_acc: 0.8197
# Epoch 6/10
# 100/100 [==============================] - 31s - loss: 0.3007 - acc: 0.8759 - val_loss: 0.4689 - val_acc: 0.7867
# Epoch 7/10
# 100/100 [==============================] - 29s - loss: 0.2522 - acc: 0.8973 - val_loss: 0.4533 - val_acc: 0.8473
# Epoch 8/10
# 100/100 [==============================] - 29s - loss: 0.2088 - acc: 0.9102 - val_loss: 0.5104 - val_acc: 0.8410
# Epoch 9/10
# 100/100 [==============================] - 29s - loss: 0.1886 - acc: 0.9248 - val_loss: 0.5535 - val_acc: 0.8530
# Epoch 10/10
# 100/100 [==============================] - 29s - loss: 0.1493 - acc: 0.9454 - val_loss: 0.6859 - val_acc: 0.7870

##################################################################################################

#End script