Brain Haemorrhage Diagnosis

Using Lenet based Deep Learning Model

Data

Using Kaggle dataset :
Head CT - hemorrhage
Balanced Normal vs Hemorrhage Head CT
https://tinyurl.com/dn8jn6jx

This dataset contains 100 normal head CT slices and 100 other scans are for patients with hemorrhage. Each slice comes from a different patient. There is no distinction between kinds of hemorrhage seen in the scans. The images were taken from an internet search and are of differing size and resolution. The main idea of using this dataset is to develop ways to predict imaging findings even in a context of limited data of varying quality.
In[]:=
imageDataDir="/Users/jonathan/Dropbox/Machine Learning/Brain Hemorrhage/Head CT Hemorrhage/CT Scans"
Out[]=
/Users/jonathan/Dropbox/Machine Learning/Brain Hemorrhage/Head CT Hemorrhage/CT Scans
In[]:=
SetDirectory[imageDataDir]
Out[]=
/Users/jonathan/Dropbox/Machine Learning/Brain Hemorrhage/Head CT Hemorrhage/CT Scans
In[]:=
CTimages=Import["*.png"];
In[]:=
Length@CTimages
Out[]=
200

Create the data associations used for neural net training and testing

In[]:=
CTdata=Join[AssociationThread[{"Input","Output"}{#,True}]&/@CTimages[[1;;100]],AssociationThread[{"Input","Output"}{#,False}]&/@CTimages[[101;;]]];
In[]:=
CTdata=Join[Table[Association[CTimages[[i]]True],{i,100}],Table[Association[CTimages[[i]]False],{i,101,200}]];

Split the data into train and test sets

In[]:=
{trainCTdata,testCTdata}=ResourceFunction["TrainTestSplit"][CTdata];
In[]:=
Length@testCTdata
Out[]=
40
In[]:=
testCTdata[[1;;4]]
Out[]=
Input
,OutputTrue,Input
,OutputFalse,Input
,OutputFalse,Input
,OutputTrue

Neural Net

We use the MNIST image classification net as the baseline neural network. The network' s goal is to classify the CT images using true and false to describe whether the patient suffers brain hemorrhage or not. One interesting feature of the net is the Resize layer which changes the image dimensions of each image to 135 by 135. This ensures the images comply with the sensitivity of the neural network to the size of images. Further layers include the convolution layer, ramp, and pooling layer, which all work to narrow down image elements and create categories to classify each image to associate them .
In[]:=
dims={135,135}
Out[]=
{135,135}
In[]:=
lenet=NetChain[{ResizeLayer[dims],ConvolutionLayer[20,5],Ramp,(*Takesoutthethenotusefulfeatures*)PoolingLayer[2,2],(*Downsamples*)ConvolutionLayer[50,5],Ramp,(*Takesoutthethenotusefulfeatures*)PoolingLayer[2,2],(*Downsamples*)FlattenLayer[],500,(*Makesfeaturesintofeaturevector"*)Ramp,2,(*Takesoutthethenotusefulfeatures-Trueorfalse*)SoftmaxLayer[]},(*Turnsthevectorintoprobabilities*)"Output"NetDecoder[{"Class",{True,False}}],(*Tensorintotrueorfalse*)"Input"NetEncoder["Image"](*Turnsimageintonumbers*)]
Out[]=
NetChain
uniniti
aliz
ed
Input
image
array(size: 3×128×128)
1
ResizeLayer
array(size: 3×135×135)
2
ConvolutionLayer
array(size: 20×131×131)
3
Ramp
array(size: 20×131×131)
4
PoolingLayer
array(size: 20×65×65)
5
ConvolutionLayer
array(size: 50×61×61)
6
Ramp
array(size: 50×61×61)
7
PoolingLayer
array(size: 50×30×30)
8
FlattenLayer
vector(size: 45000)
9
LinearLayer
vector(size: 500)
10
Ramp
vector(size: 500)
11
LinearLayer
vector(size: 2)
12
SoftmaxLayer
vector(size: 2)
Output
class


Initial Training

In[]:=
results=NetTrain[lenet,trainCTdata,All,ValidationSetScaled[0.2],MaxTrainingRounds30,TargetDevice"CPU"]
Out[]=
NetTrainResultsObject
NetTrain Results
summary
batches:
120,
rounds:
30,
time:
2.0min
,
examples/s:
32.
data
training examples:
128,
validation examples:
32,
processed examples:
3840,
skipped examples:
0
method
ADAM
optimizer
,
batch size
32,
CPU
round
loss:
1.35×
-3
10
,
error:
0%
validation
loss:
1.84×
-3
10
,
error:
0%
‹
loss
›
​
rounds
loss
training set
validation set


Training the Neural Network with Augmented Layers

Next we implement an ImageAugmentationLayer, which randomly crops images to create new data sets to improve the neural network.

In[]:=
augment=ImageAugmentationLayer[{135,135},"Input"NetEncoder[{"Image",{139,139}}],"Output"NetDecoder["Image"]]
Out[]=
ImageAugmentationLayer
Input:
image
Output:
image

In[]:=
dims2={139,139}
Out[]=
{139,139}
In[]:=
lenet2=NetChain[{ResizeLayer[dims2],ImageAugmentationLayer[{135,135}],ConvolutionLayer[20,5],Ramp,PoolingLayer[2,2],ConvolutionLayer[50,5],Ramp,PoolingLayer[2,2],FlattenLayer[],500,Ramp,2,SoftmaxLayer[]},"Output"NetDecoder[{"Class",{True,False}}],"Input"NetEncoder["Image"]]
Out[]=
NetChain
uniniti
aliz
ed
Input
image
array(size: 3×128×128)
1
ResizeLayer
array(size: 3×139×139)
2
ImageAugmentationLayer
array(size: 3×135×135)
3
ConvolutionLayer
array(size: 20×131×131)
4
Ramp
array(size: 20×131×131)
5
PoolingLayer
array(size: 20×65×65)
6
ConvolutionLayer
array(size: 50×61×61)
7
Ramp
array(size: 50×61×61)
8
PoolingLayer
array(size: 50×30×30)
9
FlattenLayer
vector(size: 45000)
10
LinearLayer
vector(size: 500)
11
Ramp
vector(size: 500)
12
LinearLayer
vector(size: 2)
13
SoftmaxLayer
vector(size: 2)
Output
class

In[]:=
results2=NetTrain[lenet2,trainCTdata,All,ValidationSetScaled[0.2],MaxTrainingRounds30]
Out[]=
NetTrainResultsObject
NetTrain Results
summary
batches:
120,
rounds:
30,
time:
2.3min
,
examples/s:
28.
data
training examples:
128,
validation examples:
32,
processed examples:
3840,
skipped examples:
0
method
ADAM
optimizer
,
batch size
32,
CPU
round
loss:
2.82×
-2
10
,
error:
0.781%
validation
loss:
9.92×
-3
10
,
error:
0%
‹
loss
›
​
rounds
loss
training set
validation set


Test Results

The results show a 90% accuracy rate, with 3 false positives and 1 false negative.

Areas for Further Research and Development

◼
  • Larger dataset
  • ◼
  • Consistent image size and quality
  • ◼
  • Testing different baseline neural nets