Saturday, June 26, 2021

Create Question And Answer NLP Model With Bert

Hello,

Recently I worked on POC for chatbot where I evaluated Question Answering with Bert. Here in this blog we will see how you can create Question, Answering with Bert.

What is Bert?

According to team, who developed Bert

BERT stands for Bidirectional Encoder Representations from Transformers. It is designed to pre-train deep bidirectional representations from unlabelled text by jointly conditioning on both left and right context. As a result, the pre-trained BERT model can be fine-tuned with just one additional output layer to create state-of-the-art models for a wide range of NLP tasks.”

Bert is pertained on massive dataset and large corpus of unlabelled text. That's the hidden power of Bert as it uses knowledge gained from pre-training and apply it to dataset given. 

For this POC we used HuggingFace's transformers. So first you have to install transformers. Using this model you can get advantage of pre trained data and then you can pass your reference text to it and this model will try to find answers from it.

pip install transformers

or 

pip3 install transformers

Because this models are very big and it takes time to load and download. Let's first save it. Create model.py file and add following code.

from transformers import BertForQuestionAnswering

from transformers import BertTokenizer

BertForQuestionAnswering.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad').save_pretrained('./trainedModel')

BertTokenizer.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad').save_pretrained('./trainedModel')

Now execute it with python command. It will create trainedModel directory and save model there with all required files. Now we can load this pertained saved model.

from transformers import BertForQuestionAnswering

from transformers import BertTokenizer

import torch

bertPreTrainedModel = BertForQuestionAnswering.from_pretrained('./trainedModel')

tokenizer = BertTokenizer.from_pretrained('./trainedModel')

encoded = tokenizer.encode('YOUR_QUESTION', 'YOUR_REFERENCE_TEXT')

tokens = tokenizer.convert_ids_to_tokens(encoded)

sepLocation = encoded.index(tokenizer.sep_token_id)

first_seg_len, second_seg_len = sepLocation + 1, len(encoded) - (sepLocation + 1)

seg_embedding = [0] * first_seg_len + [1] * second_seg_len

modelScores = bertPreTrainedModel(torch.tensor([encoded]), token_type_ids=torch.tensor([seg_embedding]))

ans_start_loc, ans_end_loc = torch.argmax(modelScores[0]), torch.argmax(modelScores[len(modelScores)-1])

result = ' '.join(tokens[ans_start_loc:ans_end_loc + 1])

result = result.replace(' ##', '')

Here you will get your answer in result. This way you can develop your model using BERT and transformers.

How to Create Custom Theme for UI using Grommet V2

 Hello,

In this blog we will understand how you can create custom theme for your using Grommet V2 in your React app.

Using Grommet v2, you can leverage the theme capabilities and define a customTheme as a JS object with your desired colors, margin padding etc. Let's see how we can do this. 

First define your custom theme as JS object. As you can see we have defined some existing grommet color like background, brand. Also we have defined our own color like custom-1, custom-2 etc and then used it in button. 

const customTheme = {

  global: {

    colors: {

      background: "#fff",

      brand: "#000",

      "custom-1": "#aaaaaa",

      "custom-2": "#bbbbbb",

      "custom-3": "#444444"

    }

  },

  button: {

    default: {

      background: "brand",

      color: "white"

    },

    primary: {

      background: "custom-1",

      color: "white"

    },

    secondary: {

      background: "custom-3",

      color: "dark-2"

    }

  }

}

For more information on theme customisation and JSON structure you can visit Official Grommet site

Now you can apply this theme to your application as below.

import { Grommet, Box } from 'grommet';

const DemoGrommet = () => (

  <Grommet theme={customTheme}>

     <Box background="custom-1" >

     </Box>

  </Grommet>

);

export default DemoGrommet;

In case you want to keep default values of Grommet theme and want to override only few things with your theme, you can use deepMerge function provided by grommet v2 utils. 

import { deepMerge } from 'grommet/utils';

import { generate } from 'grommet/themes/base';

const mergedTheme = deepMerge(generate(16), customTheme);

Here generate function generates default theme with 16 pixel font size and then it merge it with your custom theme and provide you updated theme.

How to Get Video Thumbnails with Javascript

Hello,

In this blog we will see how you can generate thumbnail of video using JavaScript.  Let's assume you have file upload in your HTML as following.

<input type="file" id="uploadVideo" accept="video/mp4" />

Now let's add an onChange listener for this.

document.querySelector("#uploadVideo").addEventListener('change', function() {
    var inputFile = document.querySelector("#uploadVideo").files[0];
    getVideoThumbnail(inputFile)
});

Now when you upload video it will call this function and you can access this video by using files property. Now we got the file. First step we will do is get blob URL of video so we can access metadata of video. Check below function. 

Here first what we are doing is creating video element and assigning blob URL to it from input file using URL.createObjectURL method.

Then we have added event listener for meta data. This is necessary as we can't get video data till them time meta data is loaded. 

Then we seek video to 0.0 second. You can add your own time here in case if you need. Then we have added seeked listener. By this time we have video data is available. Now we are using canvas to drawImage from video frame data.

Then using toDataURL method we get the base64Data. Here 0.60 is value of quality. If you don't want to compromise quality of image then you can pass 1 here.  

function getVideoThumbnail(inputFile) {
  try {
    let video = document.createElement('video');
    let blobSrc = URL.createObjectURL(inputFile);
    video.setAttribute('src', blobSrc);
    video.addEventListener('error', () => {
        console.log("Error")
    });
    video.addEventListener('loadedmetadata', () => {
        setTimeout(() => {
          video.currentTime = 0.0;
        }, 200);
        video.addEventListener('seeked', () => {
            let canvas = document.createElement('canvas');
            video.pause();
            canvas.width = 400
            canvas.height = 400;
            let ctx = canvas.getContext('2d');
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
            var base64Data = ctx.canvas.toDataURL(
                'image/png',
                0.60
            );
            // SET this data in SRC of image tag or you can add your own logic.
        });
    });
     video.load();
  } catch (err) {
  
  }
}

Hope this helps you.