使用 TensorFlow 在 Python 中進行皮膚癌檢測


任何疾病,尤其是癌症的早期檢測,對於治療階段都至關重要。朝著這個方向做出的努力之一是利用機器學習演算法,藉助 TensorFlow 等機器學習框架來檢測和診斷皮膚癌。

傳統的癌症檢測方法非常耗時,需要專業的皮膚科醫生。但是,藉助 TensorFlow,不僅可以加快這一過程,還可以使其更準確和高效。此外,那些無法及時獲得醫生和皮膚科醫生幫助的人,也可以暫時使用這種方法。

演算法

步驟 1 − 匯入 numpy、pandas、matplotlib 和 seaborn 等庫,並載入影像資料集並將其儲存為列表。

步驟 2  將此影像列表載入為 pandas 資料框,並提取列表中每個影像的兩個標籤。

步驟 3  為了簡單起見,將標籤轉換為符號 0 和 1,並藉助餅圖比較每個標籤下存在的影像數量。

步驟 4  如果不存在不平衡,則列印每個標籤的一些影像。

步驟 5  將資料集拆分為訓練集和測試集。

步驟 6  建立影像輸入管道。

步驟 7  使用 EfficientNet 架構建立和編譯模型。

步驟 8  至少訓練模型 5 個 epoch。

步驟 9  視覺化訓練損失和驗證損失之間的差異。

示例

在本示例中,我們將使用包含兩種型別影像的皮膚癌資料集,您可以在此處找到它。然後,我們將藉助 TensorFlow 開發一個模型,以便在無需大量訓練的情況下獲得所需的結果。為此,我們還將利用 EfficientNet 架構來獲取預訓練權重。

#import the required libraries 
import numpy as np
import pandas as pd
import seaborn as sb
import matplotlib.pyplot as plt

from glob import glob
from PIL import Image
from sklearn.model_selection import train_test_split

import tensorflow as tf
from tensorflow import keras
from keras import layers
from functools import partial

AUTO = tf.data.experimental.AUTOTUNE
import warnings
warnings.filterwarnings('ignore')

#load the dataset 
images = glob('train/*/*.jpg')
len(images)

#create dataset and extract labels
images = [path.replace('', '/') for path in images]
df = pd.DataFrame({'filepath': images})
df['label'] = df['filepath'].str.split('/', expand=True)[1]
print(df.head())

df['label_bin'] = np.where(df['label'].values == 'malignant', 1, 0)
df.head()

#check if both types of files are same in number 
x = df['label'].value_counts()
plt.pie(x.values,
        labels=x.index,
        autopct='%1.1f%%')
plt.show()

#printing the images of the two categories
for cat in df['label'].unique():
    temp = df[df['label'] == cat]
  
    index_list = temp.index
    fig, ax = plt.subplots(1, 4, figsize=(15, 5))
    fig.suptitle(f'Images for {cat} category . . . .', fontsize=20)
    for i in range(4):
        index = np.random.randint(0, len(index_list))
        index = index_list[index]
        data = df.iloc[index]
  
        image_path = data[0]
  
        img = np.array(Image.open(image_path))
        ax[i].imshow(img)
plt.tight_layout()
plt.show()

#split the dataset into train and test 
features = df['filepath']
target = df['label_bin']
  
X_train, X_val,\
    Y_train, Y_val = train_test_split(features, target,
                                      test_size=0.15,
                                      random_state=10)
  
X_train.shape, X_val.shape

def decode_image(filepath, label=None):
  
    img = tf.io.read_file(filepath)
    img = tf.image.decode_jpeg(img)
    img = tf.image.resize(img, [224, 224])
    img = tf.cast(img, tf.float32) / 255.0
  
    if label == None:
        return img
  
    return img, label

#create pipelines for image input 
train_ds = (
    tf.data.Dataset
    .from_tensor_slices((X_train, Y_train))
    .map(decode_image, num_parallel_calls=AUTO)
    
    .batch(32)
    .prefetch(AUTO)
)
  
val_ds = (
    tf.data.Dataset
    .from_tensor_slices((X_val, Y_val))
    .map(decode_image, num_parallel_calls=AUTO)
    .batch(32)
    .prefetch(AUTO)
)

#building the model architecture using Keras API
from tensorflow.keras.applications.efficientnet import EfficientNetB7
  
pre_trained_model = EfficientNetB7(
    input_shape=(224, 224, 3),
    weights='imagenet',
    include_top=False
)
  
for layer in pre_trained_model.layers:
    layer.trainable = False
    
from tensorflow.keras import Model
  
inputs = layers.Input(shape=(224, 224, 3))
x = layers.Flatten()(inputs)
  
x = layers.Dense(256, activation='relu')(x)
x = layers.BatchNormalization()(x)
x = layers.Dense(256, activation='relu')(x)
x = layers.Dropout(0.3)(x)
x = layers.BatchNormalization()(x)
outputs = layers.Dense(1, activation='sigmoid')(x)
  
model = Model(inputs, outputs)
model.compile(
    loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
    optimizer='adam',
    metrics=['AUC']
)

#train the model for 5 epochs
history = model.fit(train_ds,
                    validation_data=val_ds,
                    epochs=5,
                    verbose=1)

#checking the loss 
hist_df = pd.DataFrame(history.history)
hist_df.head()

#plotting line graph 
hist_df['loss'].plot()
hist_df['val_loss'].plot()
plt.title('Loss v/s Validation Loss')
plt.legend()
plt.show()
hist_df['auc'].plot()
hist_df['val_auc'].plot()
plt.title('AUC v/s Validation AUC')
plt.legend()
plt.show()

我們首先載入儲存在本地系統中的影像,然後建立一個數據框來儲存所有檔案路徑和載入的標籤。儲存的標籤轉換為二進位制格式,其中惡性表示 1,其他標籤表示 0。

程式碼的後面部分繪製了一個餅圖,視覺化標籤類的分佈並計算每個類的出現次數。

然後,我們從每個類別中隨機選擇 4 張影像,並使用 Matplotlib 在 1x4 網格中列印它們。decode_image() 函式讀取影像檔案,對其進行解碼並調整影像大小。然後使用 fit() 方法訓練模型並執行訓練。然後,fit() 方法返回的歷史物件用於提取訓練損失和驗證損失。然後將這些值儲存在資料框中。

使用 Python 中的 Matplotlib 庫繪製損失和驗證損失值。

輸出

               filepath   label
0   train/benign/100.jpg  benign
1  train/benign/1000.jpg  benign
2  train/benign/1001.jpg  benign
3  train/benign/1002.jpg  benign
4  train/benign/1004.jpg  benign

Epoch 1/5

71/71 [==============================] - 28s 356ms/step - loss: 0.5760 - auc: 0.7948 - val_loss: 1.8715 - val_auc: 0.7951

Epoch 2/5

71/71 [==============================] - 25s 348ms/step - loss: 0.4722 - auc: 0.8587 - val_loss: 0.8500 - val_auc: 0.8602

Epoch 3/5

71/71 [==============================] - 24s 336ms/step - loss: 0.4316 - auc: 0.8818 - val_loss: 0.7553 - val_auc: 0.8746

Epoch 4/5

71/71 [==============================] - 24s 331ms/step - loss: 0.4324 - auc: 0.8800 - val_loss: 0.9261 - val_auc: 0.8645

Epoch 5/5

71/71 [==============================] - 24s 344ms/step - loss: 0.4126 - auc: 0.8907 - val_loss: 0.8017 - val_auc: 0.8795

結論

儘管 TensorFlow 在皮膚癌檢測模型中表現足夠出色,但它也存在一些缺點,例如需要使用高計算能力或大量記憶體。因此,嘗試 PyTorch、Keras 和 MXNet 等其他框架,以探索機器學習領域中皮膚癌檢測的更多可能性,也並非壞主意。

更新於: 2023年7月21日

764 次檢視

開啟您的 職業生涯

透過完成課程獲得認證

開始學習
廣告