基于VGGNet乳腺超声图像数据集分析

本人的第一次发文,还在努力学习中,可能有不正确的地方,请各位大神轻喷。

 

数据集介绍:

乳腺癌是全世界妇女中最常见的死亡原因之一。早期检测有助于减少早期死亡的数量。该数据回顾了使用超声扫描的乳腺癌医疗图像。乳房超声数据集被分为三类:正常、良性和恶性图像。乳房超声图像与机器学习相结合,可以在乳腺癌的分类、检测和分割方面产生巨大效果。

本数据集收集的数据包括年龄在25至75岁之间的妇女的乳房超声图像。这个数据是在2018年收集的。患者的数量是600名女性患者。该数据集由780张图像组成,平均图像大小为500*500像素。这些图像是PNG格式的。肿瘤图像(mask)与原始图像(image)一起呈现。这些图像被分为三类,即正常normal(无肿瘤)、良性benign和恶性malignant。

如果你使用这个数据集,请引用:
Al-Dhabyani W, Gomaa M, Khaled H, Fahmy A. Dataset of breast ultrasound images. Data in Brief. 2020 Feb;28:104863. DOI: 10.1016/j.dib.2019.104863.

数据集来源:kaggle

         

        对于机器学习来说,我们需要把不同类型图像给分开以更有利于划分训练集和测试机,本例中需要将image和mask划分并分别把这两种类型图像放置到两个文件夹中以便一一对应。

数据集初始状态

image和mask混合在一起

        此部分需要先将正常,良性和恶性所对应的图片细分到六个文件夹里即正常image/正常mask,良性image/良性mask,恶性image/恶性mask。

        本人的做法是先将每个文件夹中以mask.png结尾的文件筛选出来并移动到指定目录:

src = r"./images"#原混合图片文件夹路径
dst = r"./masks"#创建放对应mask图片文件夹路径def moveimages(src,dst):   #定义移动函数new_path=dstfor derName, subfolders, filenames in os.walk(src):print(derName)print(subfolders)print(filenames)for i in range(len(filenames)):if filenames[i].endswith('_mask.png'):file_path=derName+'/'+filenames[i]newpath=new_path+'/'+filenames[i]shutil.copy(file_path,newpath)os.remove(file_path)elif filenames[i].endswith('_mask_1.png'or'_mask_3.png'or'_mask_2.png'):file_path=derName+'/'+filenames[i]os.remove(file_path)
#处理良性样本
moveimages(src+'\\benign',dst+'\\benign')
#处理恶性样本
moveimages(src+'\\malignant',dst+'\\malignant')
#处理正常样本
moveimages(src+'\\normal',dst+'\\normal')#删除图片文件多余字符,仅保留数字+后缀,如(01).png
#Windows系统下使用powertoys对文件进行批量更名

        数据初步处理完成,将分好的原图像image和掩码mask分别汇总起来并且要做到一一对应,这样才能让模型学习image和mask的关系。例如良性01号图要和良性01号mask图对应。

from glob import glob
bNames = glob(r'../input/donewelldataset/images/benign/*')
mNames = glob(r'../input/donewelldataset/images/malignant/*')
nNames = glob(r'../input/donewelldataset/images/normal/*')
clabels = [0]*len(bNames) + [1]*len(mNames) + [2]*len(nNames)
imgNames = bNames + mNames + nNames
bmskNames = glob(r'../input/donewelldataset/masks/benign/*')
nmskNames = glob(r'../input/donewelldataset/masks/normal/*')
mmskNames = glob(r'../input/donewelldataset/masks/malignant/*')
mskNames = bmskNames + mmskNames + nmskNames
maskNames = sorted(mskNames)
imgNames = sorted(imgNames)
label_order = ['benign','malignant','normal']#图像汇总
imgNames

输出结果:

#掩码汇总 
maskNames

输出结果:

 

 

        那么怎么才能知道是否一一对应了呢?我们可以试着随机生成一个2*5的图像,并且以第一排展示原图image,第二排展示掩码mask。如果多生成几张并且都能够对应,那么八九不离十正确了。

import random
from PIL import Image
import cv2
import numpy as np
from matplotlib import pyplot as pltplt.figure(figsize=(12,7))
for i in range(0,5):#random.seed(1232)a = random.randint(0,780)print(a,mskNames[a],imgNames[a])   ax=plt.subplot(2,5,i+1)img=Image.open(imgNames[a])plt.imshow(img)plt.axis('off')plt.title('image')ax=plt.subplot(2,5,i+6)msk=Image.open(maskNames[a])plt.imshow(msk)plt.axis('off')plt.title('mask')plt.show()

 

 

模型的选择与构建:

图像分类相关模型:AlexNet、VGGNet、GoogleNet、ResNet、MobileNet、vit等 CNN:卷积神经网络

VGGNet 是牛津大学计算机视觉组(Visual Geometry Group)和谷歌 DeepMind 一起研究出来的深度卷积神经网络, 因而冠名为 VGG。VGG是一种被广泛使用的卷积神经网络结构,其在在2014年的 ImageNet 大规模视觉识别挑战(ILSVRC -2014)中获得了亚军, 不是VGG不够强,而是对手太强,因为当年获得冠军的是GoogleNet

构建模型,开启机器学习:

#导入实验所需要用到的包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import glob, osimport tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, activations, optimizers, losses, metrics, initializers
from tensorflow.keras.preprocessing import image, image_dataset_from_directory
from tensorflow.keras.applications import MobileNetV3Small, MobileNet, InceptionV3
from tensorflow.keras.applications.mobilenet_v3 import preprocess_input, decode_predictionsseed = 36
tf.random.set_seed(seed) #设置图级随机seed
np.random.seed(seed) #np.random.random()可以按顺序产⽣⼀组固定的数组,如果使⽤相同的seed()值,则每次⽣成的随机数都相同,如果不设置这个值,那么每次⽣成的随机数不同dir_path = '/kaggle/input/breast-ultrasound-images-dataset/Dataset_BUSI_with_GT/'
IMAGE_SHAPE = (224, 224)#处理数据集#开始读文件
directories = os.listdir(dir_path) # 用os库读文件夹files = [] # 保存图像文件
labels = [] # 保存图像名# 逐层开始读
for folder in directories:fileList = glob.glob(dir_path + '/'+ folder + '/*')labels.extend([folder for l in fileList])files.extend(fileList)
print(len(files), len(labels))#看看是不是一样

 

正如我们所看到的,我们在所有的数据集中有1578张图像,但有一些掩码图像不适合与原始图像一起训练,所以我们将从数据集中移除所有的掩码图像。

准备开始移除,条件:如果文件名中不含mask。

个人小笔记:和上节课数据预处理方法有所区别,当时使用的是如果文件以mask.png结尾则移除出images文件夹。此处使用if not 的逻辑条件,更佳!避免了_mask_1.png、_mask_2.png无法被endswith识别到的情况

# 创建两个列表,只保存非mask的图像,并为每个列表添加标签。
selected_files = []
selected_labels = []for file, label in zip(files, labels):if 'mask' not in file:selected_files.append(file)selected_labels.append(label)
print(len(selected_files), len(selected_labels)) #看看还有多少

搞定,超声图像和其掩码mask被分开,mask被分到了selected_files中

准备图像

#开始创建方法处理文件以便能满足高效神经网络运行训练
def prepare_image(file):img = image.load_img(file, target_size=IMAGE_SHAPE) #从对应路径加载图片img_array = image.img_to_array(img)#img_to_array就是将图片转化成数组,转换前后类型都是一样的,唯一区别是转换前元素类型是整型,转换后元素类型是浮点型(和keras)等机器学习框架相适应的图像类型。return tf.keras.applications.efficientnet.preprocess_input (img_array)
#用字典将图像和其标签(名字)组合在一起
images = {'image': [], 'target': []
}print('冲冲冲冲冲,开始处理')#走过程,提示用户开始处理图像for i, (file, label) in enumerate(zip(selected_files, selected_labels)): #enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。images['image'].append(prepare_image(file)) #字典的key:image中放入value,并且是用前面方法处理好的图片文件images['target'].append(label) #同理,字典的key:label中放入valueprint('哈哈,结束啦!') #结束啦!!!!

 准备划分数据集(训练集,测试集)

作用:

  • 将图像转换为numpy数组,以便更好地进行计算
  • 对标签进行编码,将分类名称转换为数字
# 图片转化为数组
images['image'] = np.array(images['image'])
images['target'] = np.array(images['target'])# 对标签数据进行解码
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()images['target'] = le.fit_transform(images['target'])classes = le.classes_ # 获取标签数据target的类别
print(f'标签数据(target)有: {classes}')#LabelEncoder是用来对分类型特征值进行编码,即对不连续的数值或文本进行编码。其中包含以下常用方法:#fit(y) :fit可看做一本空字典,y可看作要塞到字典中的词。
#fit_transform(y):相当于先进行fit再进行transform,即把y塞到字典中去以后再进行transform得到索引值。
#inverse_transform(y):根据索引值y获得原始数据。
#transform(y) :将y转变成索引值。

 

开始分割数据集去train和test了 

from sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(images['image'], images['target'], test_size=.10)#test_size:用于指定验证集所占的比例x_train.shape, x_test.shape, y_train.shape, y_test.shape #老生常谈,对sklearn机器学习所需进行训练集和测试集的划分并展示划分数据结果

分别对应x训练集,x测试集,y训练集,y测试机。

建立模型

  • 创建VGG16模型
  • #include_top=False:禁用顶部(Top) 3层『完全连阶层』(fully-connected layers)。即只利用VGG16萃取特征
  • #weights:使用的权重,分两种
  1. imagenet:即使用ImageNet的预先训练的资料,约100万张图片,判断1000类别的日常事物,例如动物、交通工具...等,我们通常选这一项。
  2. None:随机起始值

 

from keras.applications.vgg16 import VGG16
base_model = VGG16(include_top=False,weights='../input/vgg16-weights/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5', #手动导入预训练模型(外网下载)input_shape=(*IMAGE_SHAPE, 3),classes=3)# 冻结模型
base_model.trainable = False# 在模型的顶部添加我自己的层
x = base_model.output# 1st conv block 卷积层
x = layers.Conv2D(256, 3, padding='same')(x)
x = layers.BatchNormalization()(x)
x = layers.Activation('relu')(x)
x = layers.GlobalAveragePooling2D(keepdims = True)(x)# 2nd conv block
x = layers.Conv2D(128, 3, padding='same')(x)
x = layers.BatchNormalization()(x)
x = layers.Activation('relu')(x)
x = layers.GlobalAveragePooling2D(keepdims = True)(x)# 1st FC layer Fully Connected layer全连接层
x = layers.Flatten()(x) 
x = layers.Dense(64)(x)
x = layers.BatchNormalization()(x)
x = layers.Activation('relu')(x)# 2nd FC layer
x = layers.Dense(32, activation = 'relu')(x)
x = layers.BatchNormalization()(x)
x = layers.Activation('relu')(x)
x = layers.Dropout(.2)(x)x = layers.Dense(3, 'softmax')(x)incept_model = keras.models.Model(inputs = base_model.input, outputs = x)# compile the model
incept_model.compile(optimizer=optimizers.RMSprop(.001), loss = losses.sparse_categorical_crossentropy, metrics= [metrics.SparseCategoricalAccuracy()])incept_model.summary()

输出结果:

 

太多了就只截取头尾 

 模型评估

incept_model.evaluate(x=x_test, y = y_test, batch_size=32, verbose=1)

 结果是这个样子

模型预测 训练完了就得是骡子是马拉出来看看了

# 用于预测模型,并将原始图像与真实值和预测值的标题可视化。
def predict_image(img_path, label):img1 = prepare_image(img_path) # 准备数据res = incept_model.predict(np.expand_dims(img1, axis = 0)) # predict the imagepred = classes[np.argmax(res)]# Visualize the imageimg = image.load_img(img_path)plt.imshow(np.array(img))plt.title(f'True: {label}\nPredicted: {pred}')
predict_image(dir_path + 'benign/benign (20).png', 'benign') #随便选一张图

         看得出来预测值和我们所知道的真实值还是很接近的!nice!不过样本量和计算能力有限,还需要进行更多数据和更多计算能力的训练吧,也不能保证百分之百正确!!!

一些模型评估

#数组模型评估
incept_model.evaluate(np.array(x_test),np.array(y_test))predicted = []
for item in incept_model.predict(x_test):predicted.append(np.argmax(item))for item in predicted:print(item,)from sklearn.metrics import confusion_matrix
import seaborn as sns
conf = confusion_matrix(y_test,predicted)
print(conf)

热力图

#预测与实际结果热力图
info = ['benign'   ,  # 0'normal'   ,  # 1'malignant',  # 2
]
plt.figure(figsize = (10,10))
ax = sns.heatmap(conf, cmap=plt.cm.Greens, annot=True, square=True, xticklabels = info, yticklabels = info)
ax.set_ylabel('Actual', fontsize=40)
ax.set_xlabel('Predicted', fontsize=40)

import seaborn as sns
sns.heatmap(conf)

 

        到此为止啦!感受科技的美丽,感受计算机的魅力,能够用机器学习的方式进行阅片判断。希望随着科技的发展变得越来越好!感谢各位大神的贡献,让机器学习,深度学习变得越来越超乎人们的想象。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/41935.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python写一个自动发送直播弹幕的工具,非常好用

昨晚回家,表弟在看LOL直播,看得我气不打一处来,差点就想锤他。 身为程序员的表弟,看直播发弹幕居然还在手动发,当时我就用Python写了一个自动发送弹幕的脚本送给他用。 好了话不多说,我们直接开搞&#xf…

今日作业博客

今天做了一道题目感觉挺不错的,题目是去除重复整数并重新排序。 开始我的想法是先创建一个数组代表一段序列,然后写两个函数,一个去重,一个进行冒泡排序,结果发现实在是过于复杂,所以万般无奈之下只好瞄了一…

通过分析周榜前100名专家的博客文章 手把手教你写出爆款文章

引言 或许你也在用博客来记录自己的学习历程,与别人分享技术。可是有时候你会感觉为什么我的文章也是用心烹饪的,感觉自己文章跟大佬的文章相比质量并不差啊,可是从访问量、点赞数、收藏数、评论数、粉丝数等多个纬度来看都跟大佬差别那么大…

成为顶级博主的秘诀是什么?《乘风者周刊》专访“处女座程序猿”牛亚运

「渡己是一种能力,渡人是一种格局。」 这是“处女座程序猿”牛亚运为自己立下的座右铭。 如今的牛亚运,在国内外十多个平台累计粉丝近100万,全网博客文章浏览量早已超过3000多万,囊括了阿里云乘风者计划专家博主等多个平台顶级博…

2021年度总结 -- 万粉博主的写作荣誉分享,写博客是一种心灵的修行

一、CSDN 的写作经历与荣誉 仅以此文作为 2021 年终总结,顺便跟大家分享一些我的心得经验,希望你我和 CSDN 都越来越好。翻开 2021 CSDN 年度回忆录,有种难以言喻的感觉,有过兴奋、有过开心、有过遗憾,更多的是有过收…

软件测试来喽~这看这博主写的多是一件美事呀

目录 开篇 软件测试模型 V模型 W 模型 X模型 H模型 测试方法 白盒测试 黑盒测试 灰盒测试 黑盒测试方法种类 等价类划分 等价类测试的分类 边界值方法 边界值分析测试方法 决策表方法 决策表的测试方法 开篇 哈喽!大家好,这篇我们来看看…

努力打卡 每天学习 不浪费每一天 Day76

白天学数据结构刷题 晚上学Javaweb 备考蓝桥杯 <1> Scanner 可能会超时 改用StreamTokenizer StreamTokenizer scannew StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); Window <script>//弹窗/*window.alert("123");alert(…

知识星球喊你来交作业了

各位小伙伴,晚上好,忙碌的一周,不知不觉又周末了,提前祝大家周末愉快! 入驻知识星球已经快两周的时间,已有63位朋友加入进来 有些朋友看了看星球,哇,付费的,然后就望而却步,但我们从来不是为了收费而收费的,因为之前的一系列微信群举措并没有多大效果,不希望微信群…

应老师要求发布作业博客

冒泡排序—— 原理&#xff1a;通过外层for循环 i 遍历一遍数组&#xff0c;内层循环 j 实现比较次数&#xff0c;if 判断来使数与后面的数进行比较和交换位置&#xff0c;比较次数逐渐减少&#xff0c;用数组长度来减去外层循环 i 实现比较次数减少的作用&#xff0c;最后输出…

卡塔尔世界杯终局之战,阿根廷VS法国,是老将加冕还是新王登基?

【世界杯】阿根廷VS法国 不知不觉&#xff0c;世界杯已经走到最后的尾声&#xff0c;此前经历的28天&#xff0c;63场比赛皆是铺垫&#xff0c;卢赛尔体育场将会迎来2022卡塔尔世界杯最终的决赛&#xff0c;究竟是梅西球王加冕还是法国卫冕世界杯冠军&#xff0c;今晚23&#x…

Apple Developer:Verify your identity and review the updated license agreement.

第一步&#xff1a; 确保你的iOS系统是最新的、或者iPad OS系统是最新的&#xff0c;打开iOS、iPad OS 的App Store&#xff0c;搜索Apple Developer&#xff0c;下载最新版本&#xff0c;或者更新为最新版本&#xff01; 第二步&#xff1a; 打开Apple Developer&#xff0…

【小程序云开发】不用后端也能构建完整的微信小程序

文章目录 人工智能福利文章什么是微信小程序云函数云数据库HTTP 云函数定时触发云函数总结写在最后 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人…

Input搜索框与搜索图标对齐解决方法

出现的情况 有些网站需要在搜索框旁写一个紧挨着的放大镜图标框。这时候可能就牵涉到对齐问题。 例如小米商城搜索框&#xff1a; 可以简单写一下这两个框&#xff1a; <div class"header-search"><input class"first" type"text" pl…

全力备战,迎接客户联络深度智能化的“质变时刻”

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 自2022年6月30日在香港联交所主板上市以来&#xff0c;天润融通不断加大在AI方面的研发投入&#xff0c;并确立了以“AI原生”思维重构客户联络系统和流程的产品发展目标。过去的一年中&#xff0c;天润融通推出了多项创新的…

重磅发布!百分点科技正式发布数据科学基础平台DeepMatrix

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 3月30日&#xff0c;由百分点科技主办的“2023数据科学峰会”在北京金隅智造工场科技秀场成功召开。此次大会以“数据进阶”为主题&#xff0c;邀请权威专家学者以科学视角和全球视野解读数据科学、数字政府建设及数字化业务…

2022全球社交电商趋势策略报告

导读&#xff1a; 《报告》显示,后疫情时代,口碑营销和熟人种草已成为社交购物的主要趋势;消费者对购物体验要求提升,AR(增强现实)技术将颠覆传统购物体验。店匠科技与 Snapchat 将基于此趋势,围绕独立站 SaaS、社交电商营销一站式解决方案,助力品牌企业探索建立合适的社交电商…

AI首次挑战DevOps全流程 - AI加持的黑马冠军团队有多厉害?丨IDCF

一. 报名初衷 IDCF 黑客马拉松活动第40场活动&#xff0c;加入了AI元素以后&#xff0c;各个环节明显提效&#xff0c;输出质量更高。IDCF的AI黑马挑战赛&#xff0c;一个汇集了众多DevOps爱好者、开发者的平台&#xff0c;希望能在这个沙龙中探求前沿技术、广交志同道合的朋友…

chatgpt赋能python:Python实现输入法-让你的输入更方便

Python实现输入法-让你的输入更方便 介绍 输入法是我们日常使用电脑必不可少的工具之一&#xff0c;能够帮助我们更快捷、便利地输入文字。而Python作为目前非常流行的编程语言之一&#xff0c;也可以实现输入法的功能。 Python实现输入法可以带来很多好处&#xff0c;比如&…