AI for medical image analysis
1.Data Exploration 课程代码
在本课程的第一个作业中,您将使用从公共 ChestX-ray8 数据拍摄的胸部 X 射线图像。
在本笔记本中,您将有机会探索此数据集并熟悉将在第一次评分作业中使用的一些技巧
在开始为任何机器学习项目编写代码之前,第一步是探索您的数据。用于分析和操作数据的标准 Python 包是 pandas。
使用接下来的两个代码单元格,您将导入 pandas 和一个名为 numpy 的包用于数值操作,然后使用 pandas 将 csv 文件读入数据帧并打印出前几行数据。
# Import necessary packages
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import os
import seaborn as sns
sns.set()
# Read csv file containing training datadata
train_df = pd.read_csv("nih/train-small.csv")
# Print first 5 rows
print(f'There are {train_df.shape[0]} rows and {train_df.shape[1]} columns in this data frame')
train_df.head()
查看此 csv 文件中的各个列。该文件包含胸部 X 射线图像的名称(“图像”列),填充有 1 和 0 的列标识基于每个 X 射线图像给出的诊断。
数据类型和空值检查
# Look at the data type of each column and whether null values are present
train_df.info()
唯一 ID 检查
“PatientId”具有每个患者的标识号。
关于此类医疗数据集,您想了解的一件事是,您是否正在查看某些患者的重复数据,或者每个图像是否代表不同的人。
print(f"The total patient ids are {train_df['PatientId'].count()}, from those the unique ids are {train_df['PatientId'].value_counts().shape[0]} ")
The total patient ids are 1000, from those the unique ids are 928
# pandas value_counts()功能确认数据出现的频率
count = train_df['PatientId'].value_counts()
count.shape
count
(928,)
如你所见,数据集中唯一患者的数量少于总数,因此必须存在一些重叠。对于有多个记录的患者,您需要确保它们不会同时出现在训练和测试集中,以避免数据泄漏(在本周的讲座中稍后介绍)。
探索数据标签
运行接下来的两个代码单元以创建每个患者状况或疾病的名称列表。
# pandas.keys() 返回pd的列名,而列名里包含不同的疾病
columns = train_df.keys()
columns = list(columns)
print(columns)
# Remove unnecesary elements
columns.remove('Image')
columns.remove('PatientId')
# Get the total classes
print(f"There are {len(columns)} columns of labels for these conditions: {columns}")
There are 14 columns of labels for these conditions: [‘Atelectasis’, ‘Cardiomegaly’, ‘Consolidation’, ‘Edema’, ‘Effusion’, ‘Emphysema’, ‘Fibrosis’, ‘Hernia’, ‘Infiltration’, ‘Mass’, ‘Nodule’, ‘Pleural_Thickening’, ‘Pneumonia’, ‘Pneumothorax’]
运行下一个单元格以打印出每个条件的正标签 (1) 的数量。
# Print out the number of positive labels for each class
for column in columns:
print(f"The class {column} has {train_df[column].sum()} samples")
查看上面每个类中标签的计数。
这看起来像一个平衡的数据集吗?
数据可视化
使用 csv 文件中列出的图像名称,您可以检索与数据框中每一行数据关联的图像。运行下面的单元格以可视化从数据集中随机选择的图像。
# Extract numpy values from Image column in data frame
images = train_df['Image'].values
# Extract 9 random images from it
random_images = [np.random.choice(images) for i in range(9)]
# #numpy.random.choice(a, size=None, replace=True, p=None)
#从a(只要是ndarray都可以,但必须是一维的)中随机抽取数字,并组成指定大小(size)的数组
#replace:True表示可以取相同数字,False表示不可以取相同数字
#数组p:与数组a相对应,表示取数组a中每个元素的概率,默认为选取每个元素的概率相同。
# Location of the image dir
img_dir = 'nih/images-small/'
print('Display Random Images')
# Adjust the size of your images
plt.figure(figsize=(20,10))
# Iterate and plot random images
for i in range(9):
plt.subplot(3, 3, i + 1)
img = plt.imread(os.path.join(img_dir, random_images[i]))
# 重点 plt还可以直接读取图像,返回numpy.array see https://matplotlib.org/api/_as_gen/matplotlib.pyplot.imread.html
plt.imshow(img, cmap='gray')
plt.axis('off')
# Adjust subplot parameters to give specified padding
plt.tight_layout()
调查单个图像
运行下面的单元格以查看数据集中的第一张图像并打印出图像内容的一些详细信息。
# Get the first image that was listed in the train_df dataframe
sample_img = train_df.Image[0]
raw_image = plt.imread(os.path.join(img_dir, sample_img))
plt.imshow(raw_image, cmap='gray')
plt.colorbar()
plt.title('Raw Chest X Ray Image')
print(f"The dimensions of the image are {raw_image.shape[0]} pixels width and {raw_image.shape[1]} pixels height, one single color channel")
print(f"The maximum pixel value is {raw_image.max():.4f} and the minimum is {raw_image.min():.4f}")
print(f"The mean value of the pixels is {raw_image.mean():.4f} and the standard deviation is {raw_image.std():.4f}")
- List item
调查像素值分布
运行下面的单元格以绘制上图中像素值的分布。
补充一下 seaborn的用法 https://blog.csdn.net/qq_34264472/article/details/53814653
# Plot a histogram of the distribution of the pixels
sns.distplot(raw_image.ravel(),
label=f'Pixel Mean {np.mean(raw_image):.4f} & Standard Deviation {np.std(raw_image):.4f}', kde=False)
plt.legend(loc='upper center')
plt.title('Distribution of Pixel Intensities in the Image')
plt.xlabel('Pixel Intensity')
plt.ylabel('# Pixels in Image')
Keras 中的图像预处理
在训练之前,您将首先修改图像以使其更适合训练卷积神经网络。对于此任务,您将使用 Keras ImageDataGenerator 函数执行数据预处理和数据增强。
运行接下来的两个单元格以导入此函数并创建用于预处理的图像生成器。
# Import data generator from keras
from keras.preprocessing.image import ImageDataGenerator
# Normalize images
image_generator = ImageDataGenerator(
samplewise_center=True, #Set each sample mean to 0.
samplewise_std_normalization= True # Divide each input by its standard deviation
)
方差:在上面创建的 image_generator 将调整您的图像数据,使数据的新平均值为0,数据的标准偏差为 1。换句话说,生成器将替换图像中的每个像素值
通过减去平均值并除以标准偏差计算出的新值
运行下一个单元格以使用 image_generator 预处理您的数据。
在这一步中,您还将把图像尺寸缩小到 320x320 像素。
# Flow from directory with specified batch size and target image size
generator = image_generator.flow_from_dataframe(
dataframe=train_df,
directory="nih/images-small/",
x_col="Image", # features
y_col= ['Mass'], # labels
class_mode="raw", # 'Mass' column should be in train_df
batch_size= 1, # images per batch
shuffle=False, # shuffle the rows or not
target_size=(320,320) # width and height of output image
)
运行下一个单元格以绘制预处理图像的示例:
# Plot a processed image
sns.set_style("white")
generated_image, label = generator.__getitem__(0)
plt.imshow(generated_image[0], cmap='gray')
plt.colorbar()
plt.title('Raw Chest X Ray Image')
print(f"The dimensions of the image are {generated_image.shape[1]} pixels width and {generated_image.shape[2]} pixels height")
print(f"The maximum pixel value is {generated_image.max():.4f} and the minimum is {generated_image.min():.4f}")
print(f"The mean value of the pixels is {generated_image.mean():.4f} and the standard deviation is {generated_image.std():.4f}")
运行下面的单元格以查看新的预处理图像与原始图像中像素值分布的比较。
# Include a histogram of the distribution of the pixels
sns.set()
plt.figure(figsize=(10, 7))
# Plot histogram for original iamge
sns.distplot(raw_image.ravel(),
label=f'Original Image: mean {np.mean(raw_image):.4f} - Standard Deviation {np.std(raw_image):.4f} \n '
f'Min pixel value {np.min(raw_image):.4} - Max pixel value {np.max(raw_image):.4}',
color='blue',
kde=False)
# Plot histogram for generated image
sns.distplot(generated_image[0].ravel(),
label=f'Generated Image: mean {np.mean(generated_image[0]):.4f} - Standard Deviation {np.std(generated_image[0]):.4f} \n'
f'Min pixel value {np.min(generated_image[0]):.4} - Max pixel value {np.max(generated_image[0]):.4}',
color='red',
kde=False)
# Place legends
plt.legend()
plt.title('Distribution of Pixel Intensities in the Image')
plt.xlabel('Pixel Intensity')
plt.ylabel('# Pixel')