Galle, LK--:--5/6 sites live

DL Project 1 Breast Cancer Classification with NN

ඔයාගෙ පළවෙනි neural network එක — කලින් Logistic Regression එකෙන්ම විසඳපු ම classification problem එකම, දැන් ගොඩක් සංකීර්ණ patterns ඉගෙන ගන්න පුළුවන් model එකකින් විසඳනවා.

Your first neural network — the same classification problem you already solved with Logistic Regression, now solved by a model that can learn much more complex patterns.

21 May 20269 min readSelf Guide · Stage 17#Shipping Models to the World#DL 1. Breast Cancer Classification#Machine learning

Lesson 61 of 64 · Part 5 · Shipping Models to the World · DL 1. Breast Cancer Classification · bilingual notes (English + සිංහල)

Why this matters. Your first neural network — the same classification problem you already solved with Logistic Regression, now solved by a model that can learn much more complex patterns.

සිංහලෙන්: ඔයාගෙ පළවෙනි neural network එක — කලින් Logistic Regression එකෙන්ම විසඳපු ම classification problem එකම, දැන් ගොඩක් සංකීර්ණ patterns ඉගෙන ගන්න පුළුවන් model එකකින් විසඳනවා.

What you'll use this for. Comparing this neural network's accuracy directly against your earlier Logistic Regression result on the same data is the clearest way to feel what "deep learning" actually adds.

සිංහලෙන්: එකම data එකට, කලින් Logistic Regression result එකට, මේ neural network එකේ accuracy එක direct ව compare කරන එකයි, "deep learning" එකෙන් ඇත්තටම එකතු කරන්නෙ මොකද්ද කියලා දැනගන්න පැහැදිලිම විදිහ.

Key principles

  • A neural network is layers of simple maths stacked together, not magic. Each neuron does something almost identical to Logistic Regression's weighted sum + activation — the "deep" part is simply stacking many of these together.
    Neural network එකක් කියන්නෙ, magic එකක් නෙවෙයි, සරල maths layers එකට එකතු කරපු එකක්

Walkthrough

Breast Cancer Classification with a simple Neural Network (NN)

Previous videos:

Importing the Dependencies

ExamplePython
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sklearn.datasets
from sklearn.model_selection import train_test_split

Data Collection & Processing

ExamplePython
# loading the data from sklearn
breast_cancer_dataset = sklearn.datasets.load_breast_cancer()
ExamplePython
print(breast_cancer_dataset)

Output

Output
{'data': array([[1.799e+01, 1.038e+01, 1.228e+02, ..., 2.654e-01, 4.601e-01,
        1.189e-01],
       [2.057e+01, 1.777e+01, 1.329e+02, ..., 1.860e-01, 2.750e-01,
        8.902e-02],
       [1.969e+01, 2.125e+01, 1.300e+02, ..., 2.430e-01, 3.613e-01,
        8.758e-02],
       ...,
       [1.660e+01, 2.808e+01, 1.083e+02, ..., 1.418e-01, 2.218e-01,
        7.820e-02],
       [2.060e+01, 2.933e+01, 1.401e+02, ..., 2.650e-01, 4.087e-01,
        1.240e-01],
       [7.760e+00, 2.454e+01, 4.792e+01, ..., 0.000e+00, 2.871e-01,
        7.039e-02]]), 'target': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
       0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0,
       1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0,
       1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1,
       1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0,
… (29 more lines)
ExamplePython
# loading the data to a data frame
data_frame = pd.DataFrame(breast_cancer_dataset.data, columns = breast_cancer_dataset.feature_names)
ExamplePython
# print the first 5 rows of the dataframe
data_frame.head()
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavity…
017.9910.38122.801001.00.118400.277600.3001…
120.5717.77132.901326.00.084740.078640.0869…
219.6921.25130.001203.00.109600.159900.1974…
311.4220.3877.58386.10.142500.283900.2414…
420.2914.34135.101297.00.100300.132800.1980…
ExamplePython
# adding the 'target' column to the data frame
data_frame['label'] = breast_cancer_dataset.target
ExamplePython
# print last 5 rows of the dataframe
data_frame.tail()
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavity…
56421.5622.39142.001479.00.111000.115900.24390…
56520.1328.25131.201261.00.097800.103400.14400…
56616.6028.08108.30858.10.084550.102300.09251…
56720.6029.33140.101265.00.117800.277000.35140…
5687.7624.5447.92181.00.052630.043620.00000…
ExamplePython
# number of rows and columns in the dataset
data_frame.shape

Output

Output
(569, 31)
ExamplePython
# getting some information about the data
data_frame.info()

Output

Output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 569 entries, 0 to 568
Data columns (total 31 columns):
 #   Column                   Non-Null Count  Dtype  
---  ------                   --------------  -----  
 0   mean radius              569 non-null    float64
 1   mean texture             569 non-null    float64
 2   mean perimeter           569 non-null    float64
 3   mean area                569 non-null    float64
 4   mean smoothness          569 non-null    float64
 5   mean compactness         569 non-null    float64
 6   mean concavity           569 non-null    float64
 7   mean concave points      569 non-null    float64
 8   mean symmetry            569 non-null    float64
 9   mean fractal dimension   569 non-null    float64
 10  radius error             569 non-null    float64
 11  texture error            569 non-null    float64
 12  perimeter error          569 non-null    float64
… (20 more lines)
ExamplePython
# checking for missing values
data_frame.isnull().sum()

Output

Output
mean radius                0
mean texture               0
mean perimeter             0
mean area                  0
mean smoothness            0
mean compactness           0
mean concavity             0
mean concave points        0
mean symmetry              0
mean fractal dimension     0
radius error               0
texture error              0
perimeter error            0
area error                 0
smoothness error           0
compactness error          0
concavity error            0
concave points error       0
… (14 more lines)
ExamplePython
# statistical measures about the data
data_frame.describe()
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavity…
count569.000000569.000000569.000000569.000000569.000000569.000000569.000000…
mean14.12729219.28964991.969033654.8891040.0963600.1043410.088799…
std3.5240494.30103624.298981351.9141290.0140640.0528130.079720…
min6.9810009.71000043.790000143.5000000.0526300.0193800.000000…
25%11.70000016.17000075.170000420.3000000.0863700.0649200.029560…
50%13.37000018.84000086.240000551.1000000.0958700.0926300.061540…

… 2 more rows

ExamplePython
# checking the distribution of Target Varibale
data_frame['label'].value_counts()

Output

Output
1    357
0    212
Name: label, dtype: int64

1 --> Benign

0 --> Malignant

ExamplePython
data_frame.groupby('label').mean()
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavity…
label…
017.46283021.604906115.365377978.3764150.1028980.1451880.160775…
112.14652417.91476278.075406462.7901960.0924780.0800850.046058…

Separating the features and target

ExamplePython
X = data_frame.drop(columns='label', axis=1)
Y = data_frame['label']
ExamplePython
print(X)

Output

Output
     mean radius  mean texture  mean perimeter  mean area  mean smoothness  \
0          17.99         10.38          122.80     1001.0          0.11840   
1          20.57         17.77          132.90     1326.0          0.08474   
2          19.69         21.25          130.00     1203.0          0.10960   
3          11.42         20.38           77.58      386.1          0.14250   
4          20.29         14.34          135.10     1297.0          0.10030   
..           ...           ...             ...        ...              ...   
564        21.56         22.39          142.00     1479.0          0.11100   
565        20.13         28.25          131.20     1261.0          0.09780   
566        16.60         28.08          108.30      858.1          0.08455   
567        20.60         29.33          140.10     1265.0          0.11780   
568         7.76         24.54           47.92      181.0          0.05263   

     mean compactness  mean concavity  mean concave points  mean symmetry  \
0             0.27760         0.30010              0.14710         0.2419   
1             0.07864         0.08690              0.07017         0.1812   
2             0.15990         0.19740              0.12790         0.2069   
3             0.28390         0.24140              0.10520         0.2597   
… (61 more lines)
ExamplePython
print(Y)

Output

Output
0      0
1      0
2      0
3      0
4      0
      ..
564    0
565    0
566    0
567    0
568    1
Name: label, Length: 569, dtype: int64

Splitting the data into training data & Testing data

ExamplePython
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=2)
ExamplePython
print(X.shape, X_train.shape, X_test.shape)

Output

Output
(569, 30) (455, 30) (114, 30)

Standardize the data

ExamplePython
from sklearn.preprocessing import StandardScaler
ExamplePython
scaler = StandardScaler()

X_train_std = scaler.fit_transform(X_train)

X_test_std = scaler.transform(X_test)

Building the Neural Network

download.png

ExamplePython
# importing tensorflow and Keras
import tensorflow as tf 
tf.random.set_seed(3)
from tensorflow import keras
ExamplePython
# setting up the layers of Neural Network

model = keras.Sequential([
                          keras.layers.Flatten(input_shape=(30,)),
                          keras.layers.Dense(20, activation='relu'),
                          keras.layers.Dense(2, activation='sigmoid')
])
ExamplePython
# compiling the Neural Network

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
ExamplePython
# training the Meural Network

history = model.fit(X_train_std, Y_train, validation_split=0.1, epochs=10)

Output

Output
Epoch 1/10
13/13 [==============================] - 1s 14ms/step - loss: 0.7669 - accuracy: 0.4474 - val_loss: 0.5547 - val_accuracy: 0.7174
Epoch 2/10
13/13 [==============================] - 0s 3ms/step - loss: 0.5273 - accuracy: 0.7824 - val_loss: 0.3855 - val_accuracy: 0.9348
Epoch 3/10
13/13 [==============================] - 0s 4ms/step - loss: 0.3908 - accuracy: 0.8949 - val_loss: 0.2902 - val_accuracy: 0.9565
Epoch 4/10
13/13 [==============================] - 0s 3ms/step - loss: 0.3127 - accuracy: 0.9169 - val_loss: 0.2331 - val_accuracy: 0.9565
Epoch 5/10
13/13 [==============================] - 0s 4ms/step - loss: 0.2630 - accuracy: 0.9340 - val_loss: 0.1975 - val_accuracy: 0.9565
Epoch 6/10
13/13 [==============================] - 0s 4ms/step - loss: 0.2302 - accuracy: 0.9364 - val_loss: 0.1726 - val_accuracy: 0.9783
Epoch 7/10
13/13 [==============================] - 0s 4ms/step - loss: 0.2047 - accuracy: 0.9413 - val_loss: 0.1544 - val_accuracy: 0.9783
Epoch 8/10
13/13 [==============================] - 0s 3ms/step - loss: 0.1853 - accuracy: 0.9413 - val_loss: 0.1409 - val_accuracy: 0.9565
Epoch 9/10
13/13 [==============================] - 0s 4ms/step - loss: 0.1697 - accuracy: 0.9462 - val_loss: 0.1298 - val_accuracy: 0.9565
… (2 more lines)

Visualizing accuracy and loss

ExamplePython
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])

plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')

plt.legend(['training data', 'validation data'], loc = 'lower right')

Output

Output
<matplotlib.legend.Legend at 0x7fcf3ff52450>

DL Project 1 Breast Cancer Classification with NN — figure 1

ExamplePython
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])

plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')

plt.legend(['training data', 'validation data'], loc = 'upper right')

Output

Output
<matplotlib.legend.Legend at 0x7fcf409fbcd0>

DL Project 1 Breast Cancer Classification with NN — figure 2

Accuracy of the model on test data

ExamplePython
loss, accuracy = model.evaluate(X_test_std, Y_test)
print(accuracy)

Output

Output
4/4 [==============================] - 0s 5ms/step - loss: 0.1693 - accuracy: 0.9386
0.9385964870452881
ExamplePython
print(X_test_std.shape)
print(X_test_std[0])

Output

Output
(114, 30)
[-0.04462793 -1.41612656 -0.05903514 -0.16234067  2.0202457  -0.11323672
  0.18500609  0.47102419  0.63336386  0.26335737  0.53209124  2.62763999
  0.62351167  0.11405261  1.01246781  0.41126289  0.63848593  2.88971815
 -0.41675911  0.74270853 -0.32983699 -1.67435595 -0.36854552 -0.38767294
  0.32655007 -0.74858917 -0.54689089 -0.18278004 -1.23064515 -0.6268286 ]
ExamplePython
Y_pred = model.predict(X_test_std)
ExamplePython
print(Y_pred.shape)
print(Y_pred[0])

Output

Output
(114, 2)
[0.24822891 0.537705  ]
ExamplePython
print(X_test_std)

Output

Output
[[-0.04462793 -1.41612656 -0.05903514 ... -0.18278004 -1.23064515
  -0.6268286 ]
 [ 0.24583601 -0.06219797  0.21802678 ...  0.54129749  0.11047691
   0.0483572 ]
 [-1.26115925 -0.29051645 -1.26499659 ... -1.35138617  0.269338
  -0.28231213]
 ...
 [ 0.72709489  0.45836817  0.75277276 ...  1.46701686  1.19909344
   0.65319961]
 [ 0.25437907  1.33054477  0.15659489 ... -1.29043534 -2.22561725
  -1.59557344]
 [ 0.84100232 -0.06676434  0.8929529  ...  2.15137705  0.35629355
   0.37459546]]
ExamplePython
print(Y_pred)

Output

Output
[[2.48228908e-01 5.37705004e-01]
 [5.04756272e-01 5.95336974e-01]
 [3.67398351e-01 9.86996770e-01]
 [9.29620504e-01 2.29299068e-04]
 [5.93764186e-01 4.93302941e-01]
 [8.53436947e-01 1.02660358e-02]
 [2.81091124e-01 6.12119973e-01]
 [4.79383349e-01 9.91485417e-01]
 [4.34603453e-01 9.51259434e-01]
 [6.34022474e-01 9.53936636e-01]
 [4.83262986e-01 6.63963675e-01]
 [3.86232853e-01 9.23828781e-01]
 [2.77723640e-01 7.82129407e-01]
 [3.78485560e-01 8.21216226e-01]
 [4.91592646e-01 9.53726530e-01]
 [7.36154735e-01 1.57864958e-01]
 [4.71651524e-01 9.74555612e-01]
 [2.54375935e-01 8.85443091e-01]
… (96 more lines)

model.predict() gives the prediction probability of each class for that data point

ExamplePython
#  argmax function

my_list = [0.25, 0.56]

index_of_max_value = np.argmax(my_list)
print(my_list)
print(index_of_max_value)

Output

Output
[0.25, 0.56]
1
ExamplePython
# converting the prediction probability to class labels

Y_pred_labels = [np.argmax(i) for i in Y_pred]
print(Y_pred_labels)

Output

Output
[1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 

Building the predictive system

ExamplePython
input_data = (11.76,21.6,74.72,427.9,0.08637,0.04966,0.01657,0.01115,0.1495,0.05888,0.4062,1.21,2.635,28.47,0.005857,0.009758,0.01168,0.007445,0.02406,0.001769,12.98,25.72,82.98,516.5,0.1085,0.08615,0.05523,0.03715,0.2433,0.06563)

# change the input_data to a numpy array
input_data_as_numpy_array = np.asarray(input_data)

# reshape the numpy array as we are predicting for one data point
input_data_reshaped = input_data_as_numpy_array.reshape(1,-1)

# standardizing the input data
input_data_std = scaler.transform(input_data_reshaped)

prediction = model.predict(input_data_std)
print(prediction)

prediction_label = [np.argmax(prediction)]
print(prediction_label)

if(prediction_label[0] == 0):
  print('The tumor is Malignant')

else:
  print('The tumor is Benign')

Output

Output
[[0.42537233 0.9805447 ]]
[1]
The tumor is Benign

Output

Output
/usr/local/lib/python3.7/dist-packages/sklearn/base.py:451: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names
  "X does not have valid feature names, but"

Keep going: ← Lesson 60 · Lesson 62 → · Track it in the Self Guide