# Sentiment Analysis using Python

Deep learning is the first choice when you want to train neural networks for high-end Machine Level projects. It is the subset of machine learning where the neural networks learn by observing intricate structures in the data that they experience, this includes statistics and predictive modelling. Deep learning model comprises computational models consisting of multiple neural layers that build up the networks at multiple layers of abstraction to represent the data.
In this blog, we are going to learn how can we build a model for predicting human sentiments. We will train models on hundreds of images available online. So lets get started.

## File Structure

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1663431769340/KXw80NroG.png align="left")

Download this [data folder](https://github.com/laksh-2193/SentimentsAnalysis/tree/master/data) that have images for training and put it in the main project.

Make sure you download this [haarcascade_frontalface_default.xml](https://github.com/laksh-2193/SentimentsAnalysis/blob/master/haarcascade_frontalface_default.xml) file that will help in detecting face.

These files will be generated as our code compiles, so don't worry about them

1. Code.ipynb (Not required)
2. model.h5
3. sentimentAnalyser.h5


## Lets Code
Create a python file [main.py](https://github.com/laksh-2193/SentimentsAnalysis/blob/master/main.py) and install the following libraries :
1. OpenCV
2. Numpy
3. Keras

Import all the required libraries 
```
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.layers import Conv2D,MaxPool2D
import os
```

Declare the location for test and training data folders
```
train_data_dir = 'data/train'
validation_data_dir = 'data/test'
```

Since all the images are coloured, we need to scale them with respect to the 255 RGB value. In addition to that, we are adding some more parameters like rotation, fixing a dimension for a better training dataset
```
train_datagen = ImageDataGenerator(rescale=1./255,rotation_range=30,shear_range=0.3,zoom_range=0.3, horizontal_flip=True,fill_mode='nearest')
validation_datagen = ImageDataGenerator(rescale=1./255)
```

Now we are creating two objects different for training and testing datasets. It takes the image directory e.g. `train_datagen` as input, converts to `grayscale`, fixes the dimension `(48,48)`, since we are categorising image into angry, disgust, fear etc. so we our operation on all these classes are going to be `categorical`. We will `shuffle` images for better training
```
train_genrator = train_datagen.flow_from_directory(
    train_data_dir,
    color_mode='grayscale',
    target_size=(48,48),
    batch_size=32,
    class_mode='categorical',
    shuffle=True
)

validation_genrator = validation_datagen.flow_from_directory(
    validation_data_dir,
    color_mode='grayscale',
    target_size=(48, 48),
    batch_size=32,
    class_mode='categorical',
    shuffle=True
)
```

Now we will declare the list of labels in which we will classify images
```
class_labels = ['Angry','Disgust','Fear','Happy','Neutral','Sad','Surprise']
```

Creating a neural network of 5 layers. The last layer will result in the probability of all 7 classification classes and the max probability will be the final sentiment. Since we want a linear neural network i.e. a stack of layers we will use `Sequential()` model. [`Convo2D`](https://keras.io/api/layers/convolution_layers/convolution2d/) produces a matrix based on `kernal_size` and [`relu`](https://keras.io/api/layers/activations/#relu-function) `activation` function. [`MaxPool2D`](https://www.tensorflow.org/api_docs/python/tf/keras/layers/MaxPool2D) finds the feature with maximum value for each matrix referenced as `pool_size` . Finally `Dropout` is the number of layer that nullifies the node of current layer before doing to next.
```
model = Sequential()
model.add(Conv2D(32,kernel_size=(3,3),activation='relu',input_shape=(48,48,1)))

model.add(Conv2D(64,kernel_size=(3,3),activation='relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.1))

model.add(Conv2D(128,kernel_size=(3,3),activation='relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.1))

model.add(Conv2D(256,kernel_size=(3,3),activation='relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.1))

model.add(Flatten())
model.add(Dense(512,activation='relu'))
model.add(Dropout(0.2))

model.add(Dense(7,activation='softmax'))
```

Here `Dense` layer classifies images based on output from convolutional layers. `Flatten` reshapes the layer into a single matrix.

Finally we will compile the model with certain parameters and see the summary for how it worked
```
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])
print(model.summary())
```

Now we are going to train the images on our neural network and save the mode as `sentimentanalyser.h5`
```
num_train_images=0
for root, dirs, files in os.walk(train_path):
    num_train_images+=len(files)

num_test_images=0
for root, dirs, files in os.walk(test_path):
    num_test_images+=len(files)


epochs=100
history = model.fit(train_genrator, steps_per_epoch=num_train_images//32,
                    epochs=epochs,
                    validation_data=validation_genrator,
                    validation_steps=num_test_images//32)

model.save('sentimentanalyser.h5')
```
This step will take time, based on the number of `epochs`, it is the number of cycles for training the images.

So yay! you have finally created a CNN for detection of sentiments. Find the full code below.

%[https://github.com/laksh-2193/SentimentsAnalysis]
