皮肤癌分类–基于Keras的卷积神经网络实现分类
数据集中的病理图片包含3个类别
melanoma(黑素瘤)nevus(痣) seborrheickeratosis(脂溢性角化病)
from sklearn import datasets
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from keras.preprocessing import image as image2
from tqdm import tqdm
from PIL import ImageFile
plt.style.use('default')
from matplotlib import image
def plot_image(filename_list):
fig,axes=plt.subplots(nrows=3,ncols=3)
fig.set_size_inches(10,9)
random_9_nums=np.random.choice(len(filename_list),9)
random_9_imgs=filename_list[random_9_nums]
print(random_9_imgs)
imgname_list=[]
for imgpath in random_9_imgs:
imgname=imgpath[len(datasets_path)+1:]
imgname=imgname[:imgname.find('/')]
imgname_list.append(imgname)
index=0
for row_index in range(3):
for col_index in range(3):
img=image.imread(random_9_imgs[index])
ax=axes[row_index,col_index]
ax.imshow(img)
ax.set_xlabel(imgname_list[index])
index+=1
plt.show()
print("查看病理图片的大小:")
for i, img_path in enumerate(random_9_imgs):
print_img_shape(i, img_path)
def get_data(path):
data=datasets.load_files(path)
return data
def print_img_shape(i,filepath):
shape=image.imread(filepath).shape
print("第{}张的shape是{}".format(i+1,shape))
def path_to_tensor(img_path):
img=image2.load_img(img_path,target_size=(224,224,3))
x=image2.img_to_array(img)
return np.expand_dims(x,axis=0)
def paths_to_tensor(img_paths):
list_of_tensors=[path_to_tensor(img_path) for img_path in tqdm(img_paths)]
return np.vstack(list_of_tensors)
def draw_predicted_figure(img_path,x,y):
fig,ax=plt.subplots()
fig.set_size_inches(5,5)
fig_title="\n".join(["{}: {:.2f}%\n".format(n,y[i]) for i,n in enumerate(x)])
ax.test(1.01,0.7,
fig_title,
horizontalalignment='left',
verticalalignment='bottom',
transform=ax.transAxes)
img=image.imread(img_path)
ax.imshow(img)
if __name__ == '__main__':
work_path=os.getcwd()
datasets_path=os.path.join(work_path,'datasets','dataset','dataset')
data=get_data(datasets_path)
filename_list=data['filenames']
target_list=data['target']
target_name_list=data['target_names']
print(filename_list.shape)
print(filename_list[:20])
print(target_list)
print(target_name_list)
plot_image(filename_list)
'''
基于Keras的卷积神经网络实现分类
'''
x_train,x_test,y_train,y_test=train_test_split(filename_list,target_list,test_size=0.2)
half_test_count=int(len(x_test)/2)
x_valid=x_test[:half_test_count]
y_valid=y_test[:half_test_count]
x_test=x_test[half_test_count:]
y_test=y_test[half_test_count:]
print("X_train.shape={},y_train.shape={}.".format(x_train.shape,y_train.shape))
print("X_valid.shape={},y_valid.shape={}.".format(x_valid.shape, y_valid.shape))
print("X_test.shape={},y_test.shape={}.".format(x_test.shape, y_test.shape))
ImageFile.LOAD_TRUNCATED_IMAGES=True
train_tensors=paths_to_tensor(x_train).astype(np.float32)/255
valid_tensors=paths_to_tensor(x_valid).astype(np.float32)/255
test_tensors = paths_to_tensor(x_test).astype(np.float32) / 255
'''创建CNN模型'''
from keras.layers import Conv2D,MaxPooling2D,GlobalAveragePooling2D
from keras.layers import Dropout,Dense
from keras.models import Sequential
from keras.callbacks import ModelCheckpoint
input_shape=train_tensors[0].shape
num_classes=len(target_name_list)
model=Sequential()
model.add(Conv2D(filters=16,kernel_size=(1,1),strides=(1,1),padding='same',activation='relu',input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(1,1)))
model.add(Dropout(0.5))
model.add(Conv2D(filters=32,kernel_size=(1,1),strides=(1,1),padding='same',activation='relu'))
model.add(MaxPooling2D(pool_size=(1,1)))
model.add(Dropout(0.2))
model.add(GlobalAveragePooling2D())
model.add(Dropout(0.5))
model.add(Dense(num_classes,activation='softmax'))
model.summary()
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
checkpointer=ModelCheckpoint(filepath='saved_model/skin_cancer.best_weighs.hdf5')
epochs=10
model.fit(train_tensors,
y_train,
validation_data=(valid_tensors,y_valid),
epochs=epochs,
batch_size=20,
callbacks=[checkpointer],
verbose=1)
model.load_weights("saved_model/skin_cancer.best_weighs.hdf5")
score=model.evaluate(test_tensors,y_test,verbose=1)
print("Test {}:{:.2f}.Test {}: {:.2f}.".format(model.metrics_names[0],score[0]*100,model.metrics_names[1],score[1]*100))
from keras.models import load_model
model=load_model("saved_model/skin_cancer.best_weighs.hdf5")
test_img_path="nevus_ISIC_0007332.jpg"
image_tensor=path_to_tensor(test_img_path)
image_tensor=image_tensor.astype(np.float32)/255
predicted_result=model.predict(image_tensor)
print(predicted_result)
draw_predicted_figure(test_img_path,target_name_list,predicted_result[0])