使用 keras 和 tfjs 构建血细胞分类模型

简介:

AI 真的是一个重大的游戏改变者。 AI的应用是巨大的,并且它在医疗领域的应用范围也是广阔的。 先进的AI工具可以帮助医生和实验室技术人员更准确地诊断疾病,例如尼日利亚的一名医生可以使用这种工具从血液样本中识别出一种他根本不知道的疾病,这有助于他更好地诊断这种疾病并且更快的治疗,这是AI民主化的一个优势,因为AI模型和工具可以在全世界范围内使用,使得尼日利亚的医生可以使用麻省理工学院或世界上任何其他伟大的大学的研究学者正在使用的工具和技术。机器学习的主要问题

器学习当然是当今AI发展的主要因素。 但AI民主化意味着可以建立一个基础设施,它允许任何人在世界各地使用相同的技术建立强大的工具。可能阻止人们人构建AI的两个主要问题就是计算能力和没有可用于训练的数据集。 但这些问题正在以有趣的方式解决,它们如下:

 ●  Kaggle (Home of datasets) : 没有可用的数据集是主要问题之一,但是Kaggle是人们创建数据集并托管以使其他人使用的最佳场所,人们使用这些工具构建了令人有趣的东西。

 ●  Google co-lab : Google co-lab 是机器学习的主要驱动力,允许任何拥有谷歌帐户的人使用GPU。 如果没有这些GPU,任何人都无法训练需要大量计算的ML模型。

血细胞数据集

数据集就像数据科学家的金矿一样,如果数据集可以用于特定问题,它可以减少工程团队所需的大量工作,因为不需要浪费精力来收集和存储数据。 几个月前我想到开发这个系统,Kaggle帮我获得了很多数据集。 这是我在Kaggle上找到的数据集,感谢 Paul Mooney 提供的这个数据集。

Dataset Structure : 该数据集包含了 12,500 张增强的血细胞图片,该数据集包含下列4种不同的类型:

6868f611ff88a81aee6d06921580851b287a385d

每一个分类都包含了3000张图片。下面是每种图片的样本:

21adbb00d5b00db6a45b3d6f687e06ec6e7ad115

我将每张图片的大小都缩减为 (80x80x3) 以便可以更好的训练。

Kaggle 要求在下载数据集之前登录,但我们使用colab,在我们本地机器上不需要下载数据集,而是将代码上传到google colab实例。

使用 Google co-lab

简单来说,Google co-lab提供了一个基于云的python notebook,其虚拟实例与GPU运行时相关联,Google co-lab的GPU运行时由NVIDIA k-80驱动,这是一款功能强大,价格昂贵的GPU。但是co-lab允许我们免费使用GPU而无需支付费用。 实例的最长时间为12小时,12小时后实例将被销毁,新的实例将被创建,因此我们只能运行那些持续时间不超过12小时的计算。 让我们看看我们如何使用colab来训练我们的神经网络。

Kaggle 身份验证:

Kaggle 命令行界面允许您下载数据集并将代码提交给竞赛。 注册kaggle后,您可以下载包含所有凭据的kaggle.json文件,kaggle 命令行界面使用这些凭据进行授权。

 ●  使用命令 !mkdir.kaggle 创建一个新单元和一个名为.kaggle的隐藏文件夹。
 ●  使用pip安装Kaggle CLI :在新单元中- !pip install kaggle
 ●  下载数据集: !kaggle datasets download-d paulthimothymooney/blood-cells
 ●  确保当前的文件夹包含下载的数据集 !ls dataset2-master/images
 ●  可以看到三个文件夹:TEST, TEST_SIMPLE and TRAIN

 ●  TRAIN 文件夹包含了训练图片,将会使用这个文件夹来进行训练。

预处理

我们需要将图像加载为numpy数组并将其提供给我们正在训练的神经网络。 我们将使用Keras构建神经网络,Keras提供了一个内置的ImageDataGenerator,它可以处理大多数的预处理任务。

我们导入了开发模型所需的一些对象:

 
  1. from keras.models import Sequential


  2. from keras.layers import Dense, Conv2D, Dropout, MaxPool2D, Flatten


  3. from keras.preprocessing import image


keras.preprocessing 提供处理各种类型数据集所需的方法和对象。 从图像模块我们创建一个具有所有必需配置的ImageDataGenerator。

 
  1. generator = image.ImageDataGenerator(


  2. rescale = 1./255,


  3. featurewise_center=False, # set input mean to 0 over the dataset


  4. samplewise_center=False, # set each sample mean to 0


  5. featurewise_std_normalization=False, # divide inputs by std of the dataset


  6. samplewise_std_normalization=False, # divide each input by its std


  7. zca_whitening=False, # apply ZCA whitening


  8. rotation_range=10, # randomly rotate images in the range (degrees, 0 to 180)


  9. width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)


  10. height_shift_range=0.1, # randomly shift images vertically (fraction of total height)


  11. horizontal_flip=True, # randomly flip images


  12. vertical_flip=False)


如上一节所述,训练数据存在于`dataset2-master/images/TRAIN 目录中,我们给 ImageDataGenerator 提供这条路径,以便我们所有的配置和扩充都应用于训练图像。

 
  1. dataset = generator.flow_from_directory(


  2. shuffle = True,


  3. batch_size = 32,


  4. target_size = (80, 80),


  5. directory = 'dataset2-master/images/TRAIN'


  6. )


这就是预处理,你可以通过降低或增加图像增强的效果调整这些参数来更好地训练,总有一个改进的地方。

CNN 简介

CNN(卷积神经网络)是一种神经网络,它包含一组卷积层和一个连接到它的前馈网络。 卷积操作不是一个新的操作,它多年来一直用于图像处理。 卷积操作的主要作用是从图像中提取边缘,换句话说,它们可用于提取图像的重要特征,如果滤波器值已知,则对于任何图像任何人都无法得出最佳滤波器值,因为我们使用卷积和神经网络,梯度下降将自动优化滤波器值以提取图像的重要特征。 Andrew Ng的课程deeplearning.ai可以帮助您更好地理解这些网络的工作。 它超出了本文的范围。

网络

此任务必须使用CNN,因为简单的前馈网络无法学习数据集的独特特征。 我们使用的CNN的架构如下所示:

243c69f3edd96e0271e2ac471079334b7b149085

创建的model()函数如下所示:

 
  1. def model():


  2. model = Sequential()


  3. model.add(Conv2D(80, (3,3), strides = (1, 1), activation = 'relu'))


  4. model.add(Conv2D(64, (3,3), strides = (1, 1), activation = 'relu', input_shape = (80, 80, 3)))


  5. model.add(MaxPool2D(pool_size = (2,2)))


  6. model.add(Conv2D(64, (3,3), strides = (1,1), activation = 'relu'))


  7. model.add(Dropout(0.25))


  8. model.add(Flatten())



  9. model.add(Dense(128, activation = 'relu'))


  10. model.add(Dropout(0.5))


  11. model.add(Dense(4, activation = 'softmax'))



  12. model.compile(loss = 'categorical_crossentropy', optimizer = 'adadelta', metrics = ['accuracy'])



  13. return model


最后训练模型:

 
  1. nn = model()


  2. nn.fit_generator(dataset, steps_per_epoch = None, epochs = 30, verbose = 1)


  3. nn.save('Model.h5')


这个模型训练了30个epoch并得到了92.67%的准确率,这是一个很好的准确率,您可以添加更多层或超调整参数以提高准确率。

部署模型

一旦训练完成,我们需要将模型部署到生产中,以便每个人都可以使用它。有多种策略可用于部署机器学习系统。 我想在客户端机器上运行整个程序,所以开始构建一个可以这样做的Web应用程序。

先决条件:

我们需要以下要求来构建客户端应用程序,该应用程序具有以下架构:

79c7485de3f75bb10995841fbca3cb845c08c816

安装node和npm并设置环境,按相同顺序安装以下依赖项:

 
  1. npm install -g create-react-app


  2. create-react-app app_name


  3. cd app_name


  4. npm install --save @tensorflow/tfjs


  5. //on server side:


  6. mkdir server


  7. cd server


  8. npm init


  9. //fill up the details, make sure package.json is created


  10. npm install express --save


 ●  模型服务器:这是一个express.js REST终端,客户端可以通过发送REST GET请求来请求模型文件。 (在服务器端)
 
  1. let express = require('express')


  2. let cors = require('cors')


  3. let path = require('path')



  4. var app = express()



  5. let static_path = path.join(__dirname, 'ModelData/model_data')



  6. app.use(cors())


  7. app.use(express.static(static_path))


 ●  模型仓库:我们需要创建一个与tfjs兼容的模型,tensorflow提供了一个名为tensorflowjs的工具,它是一个包含实用程序的python工具包,我们可以使用以下命令来安装它: pip install tensorflowjs

完成后,我们可以使用tensorflowjs_converter并使用以下命令将模型转换为tfjs格式:

 
  1. $tensorflowjs_converter --input_format keras \


  2. Model.h5 \


  3. ModelData/model_data


  4. // Model.h5 is the downloaded model after training, last argument is the target folder, where we need to store the model files.


转换后,它将创建一组称为分片的文件,通过基于图层分割模型获得分片,每个分片包含特定图层的权重。 使用分片非常有用,因为每个分片可以存储在不同的地方,并且可以在需要时下载,因此我们可以为机器外学习模型构建分布式存储。 model.json 是包含每个分片信息的文件。 如果我们更改了分片的目录,我们可以修改此文件。 在API调用中,我们只将model.json 文件发送到客户端,tfjs将自动获取每个分片以在客户端机器上组装模型,如浏览器。

最后一部分:在客户端开发接口引擎

在本节中,我不会过多强调UI设计,相反我将强调接口部分,即如何使用tfjs运行接口。 转到react app目录。

 ●  创建一个模型容器类:首先为我们的模型创建了一个包装类。 此类的实例表示可以进行接口的模型。 这个模型类的代码是可以理解的:
 ●  接口函数:定义了一个可以获取模型对象和输入图像源的函数,输入源可以是HTML img,也可以是URL或图像字节流。

代码如下所示:

 
  1. var tensorflow = require('@tensorflow/tfjs')



  2. class ModelContainer {


  3. constructor(nn){


  4. this.nn = nn


  5. }


  6. setWeights(weights){


  7. //use json weights file


  8. }


  9. async loadFromURL(url){


  10. console.log(url)


  11. this.nn = await tensorflow.loadModel(url)


  12. console.log(this.nn)


  13. }


  14. removeNetwork(){


  15. this.nn = null


  16. }



  17. swapToNewObject(){


  18. let new_nn = this.nn


  19. this.nn = null


  20. return new_nn


  21. }



  22. obtainMemorySafe(){


  23. return this.swapToNewObject()


  24. }



  25. obtain(){


  26. return this.nn


  27. }


  28. }



  29. function runInference(modelContainer, imageData){


  30. //perform a sawp, i.e obtain network object from container


  31. imageData.style.width = "80px";


  32. imageData.style.height = "80px";


  33. let nn = modelContainer.obtainMemorySafe()


  34. let pixels = tensorflow.fromPixels(imageData)


  35. pixels = pixels.reshape([1, 80, 80, 3])


  36. pixels.dtype = 'float32'


  37. pixels = tensorflow.div(pixels, 255)


  38. let predictions = nn.predict(pixels)


  39. modelContainer.nn = nn


  40. nn = null


  41. return predictions.dataSync()


  42. }



  43. function afterPrediction(predictions){


  44. //as of now


  45. console.log(predictions)


  46. }



  47. export {ModelContainer, runInference, afterPrediction}


 ●  初始化模型对象:我们现在可以创建模型对象以便用在接口中。
 
  1. let modelCache = new ModelContainer(null);


  2. modelCache.loadFromURL('http://192.168.0.105:5443/model_metadata')


 ●  运行接口:一旦我们有了一个模型对象,我们就可以随时进行接口。根据我设计的用户界面,只要用户点击预测按钮,就会执行接口。 运行预测的React组件部分如下所示:
 
  1. <div style = {{margin : '40px 40px 40px 40px', textAlign : 'center'}}>


  2. <button className = "button is-rounded is-danger" onClick = {


  3. () => {


  4. let result = runInference(modelCache, document.getElementById('image_container'))


  5. this.setState({


  6. scores : this.computeScore(result),


  7. show_result : true


  8. })


  9. }


  10. }>Predict</button>


  11. </div>



  12. //and computeScore function :


  13. computeScore(predictions) {


  14. let sum = 0;


  15. for(var i = 0; i < predictions.length; i++) sum+=predictions[i]



  16. //cumpute proportions


  17. let proportions = []


  18. for(var i = 0; i < predictions.length; i++){


  19. let prop = (predictions[i] * 100)/sum


  20. proportions.push(prop)


  21. }



  22. return {


  23. EOSINOPHIL : proportions[0],


  24. LYMPHOCYTE : proportions[1],


  25. MONOCYTE : proportions[2],


  26. NEUTROPHIL : proportions[3]


  27. }


  28. }


  29. }

总结

这个项目对我来说真的很棒,我学会了如何使用谷歌colab在云上训练ML模型,还学会了如何在生产机器上部署ML模型。

这是一个开源项目,可以随时进行更改:

REPO URL : react-client

Cloud Notebook (训练模型): training.ipynb

如果您有兴趣,可以在github上star这个项目。


原文发布时间为:2018-09-19

本文作者:小韩

本文来自云栖社区合作伙伴“磐创AI”,了解相关信息可以关注“磐创AI”。

相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
2月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【PyTorch实战演练】AlexNet网络模型构建并使用Cifar10数据集进行批量训练(附代码)
【PyTorch实战演练】AlexNet网络模型构建并使用Cifar10数据集进行批量训练(附代码)
70 0
|
7月前
|
机器学习/深度学习 数据采集 算法框架/工具
实战:用激活函数、Keras框架解决分类问题
实战:用激活函数、Keras框架解决分类问题
|
5月前
|
机器学习/深度学习 数据可视化 TensorFlow
用TensorBoard可视化tensorflow神经网络模型结构与训练过程的方法
用TensorBoard可视化tensorflow神经网络模型结构与训练过程的方法
136 0
|
5月前
|
机器学习/深度学习 自然语言处理 PyTorch
PyTorch搭建RNN联合嵌入模型(LSTM GRU)实现视觉问答(VQA)实战(超详细 附数据集和源码)
PyTorch搭建RNN联合嵌入模型(LSTM GRU)实现视觉问答(VQA)实战(超详细 附数据集和源码)
75 1
|
12月前
|
机器学习/深度学习 自然语言处理 算法
【Pytorch神经网络实战案例】31 TextCNN模型分析IMDB数据集评论的积极与消极
【Pytorch神经网络实战案例】31 TextCNN模型分析IMDB数据集评论的积极与消极
475 0
|
12月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【Pytorch神经网络实战案例】02 CIFAR-10数据集:Pytorch使用GPU训练CNN模版-方法②
【Pytorch神经网络实战案例】02 CIFAR-10数据集:Pytorch使用GPU训练CNN模版-方法②
230 0
|
机器学习/深度学习 PyTorch 算法框架/工具
什么是LSTM模型,什么是BILSTM模型,给出 pytorch案例
LSTM模型是一种循环神经网络模型,它在处理序列数据时能够有效地解决梯度消失和梯度爆炸的问题。LSTM模型引入了门机制(如遗忘门、输入门和输出门),以便在序列中选择性地保存或遗忘信息。这些门可以根据输入数据自适应地学习。 BILSTM模型是一种双向LSTM模型,它包含两个LSTM模型,一个正向模型和一个反向模型。正向模型按照时间顺序读取输入序列,而反向模型按照相反的顺序读取输入序列。这使得BILSTM模型能够同时考虑过去和未来的上下文信息,因此通常比单向LSTM模型表现更好。
662 0
|
机器学习/深度学习 TensorFlow 算法框架/工具
TensorFlow进行不同模型和数据集之间的迁移学习和模型微调
TensorFlow进行不同模型和数据集之间的迁移学习和模型微调
192 0
TensorFlow进行不同模型和数据集之间的迁移学习和模型微调
|
机器学习/深度学习 并行计算 数据可视化
构建Alextenet 解决 Cifar100分类问题(1024)
构建Alextenet 解决 Cifar100分类问题(1024)
133 0
构建Alextenet 解决 Cifar100分类问题(1024)