Maison  >  Article  >  Périphériques technologiques  >  Une brève analyse de l'apprentissage actif des données d'image cellulaire

Une brève analyse de l'apprentissage actif des données d'image cellulaire

王林
王林avant
2023-04-09 10:41:051116parcourir

Définissez les priorités et les pondérations des données grâce à l'impact des étiquettes d'image de cellule sur les performances du modèle.

L'un des obstacles majeurs à de nombreuses tâches d'apprentissage automatique est le manque de données étiquetées. L’étiquetage des données peut prendre beaucoup de temps et coûter cher, si bien qu’il est souvent déraisonnable d’essayer d’utiliser des méthodes d’apprentissage automatique pour résoudre le problème.

Afin de résoudre ce problème, un domaine appelé apprentissage actif a émergé dans le domaine de l'apprentissage automatique. L'apprentissage actif est une méthode d'apprentissage automatique qui fournit un cadre permettant de prioriser les échantillons de données non étiquetés en fonction des données étiquetées que le modèle a déjà vues. Si vous le souhaitez

Les technologies de segmentation et de classification par imagerie cellulaire sont un domaine de recherche en développement rapide. Tout comme dans d’autres domaines de l’apprentissage automatique, l’annotation des données coûte très cher et les exigences de qualité en matière d’annotation des données sont également très élevées. Pour résoudre ce problème, cet article présente un flux de travail d’apprentissage actif de bout en bout pour les tâches de classification d’images de globules rouges et de globules blancs.

Notre objectif est de combiner la biologie et l'apprentissage actif et d'aider les autres à utiliser des méthodes d'apprentissage actif pour résoudre des tâches similaires et plus complexes dans le domaine de la biologie.

Cet article se compose principalement de trois parties :

  • Prétraitement des images cellulaires - nous présenterons ici comment prétraiter les images de cellules sanguines non segmentées.
  • Utilisation de CellProfiler pour extraire les caractéristiques des cellules - montre comment extraire les caractéristiques morphologiques des images photo de cellules biologiques afin de les utiliser comme fonctionnalités pour les modèles d'apprentissage automatique.
  • Utilisation de l'apprentissage actif - montre une expérience comparative simulant l'utilisation de l'apprentissage actif et ne pas utiliser l'apprentissage actif.

Prétraitement des images cellulaires

Nous utiliserons l'ensemble de données d'images de cellules sanguines sous licence MIT (GitHub et Kaggle). Chaque image est étiquetée selon la classification des globules rouges (RBC) et des globules blancs (WBC). Il existe des étiquettes supplémentaires pour ces quatre types de leucocytes (éosinophiles, lymphocytes, monocytes et neutrophiles), mais celles-ci n'ont pas été utilisées dans cette étude.

Voici un exemple d'image brute en taille réelle à partir de l'ensemble de données :

Une brève analyse de l'apprentissage actif des données d'image cellulaire

Création d'un exemple de DF

L'ensemble de données d'origine contient un script export.py qui analyse les commentaires XML dans une table CSV contenant chaque cellule. nom de fichier, étiquette de type de cellule et cadre de délimitation.

Le script original n'incluait pas la colonne cell_id, mais nous voulions classer les cellules individuelles, nous avons donc légèrement modifié le code pour ajouter cette colonne et ajouté une colonne de nom de fichier comprenant image_id et cell_id :

import os, sys, randomimport xml.etree.ElementTree as ETfrom glob import globimport pandas as pdfrom shutil import copyfileannotations = glob('BCCD_Dataset/BCCD/Annotations/*.xml')df = []for file in annotations:#filename = file.split('/')[-1].split('.')[0] + '.jpg'#filename = str(cnt) + '.jpg'filename = file.split('\')[-1]filename =filename.split('.')[0] + '.jpg'row = []parsedXML = ET.parse(file)cell_id = 0for node in parsedXML.getroot().iter('object'):blood_cells = node.find('name').textxmin = int(node.find('bndbox/xmin').text)xmax = int(node.find('bndbox/xmax').text)ymin = int(node.find('bndbox/ymin').text)ymax = int(node.find('bndbox/ymax').text)row = [filename, cell_id, blood_cells, xmin, xmax, ymin, ymax]df.append(row)cell_id += 1data = pd.DataFrame(df, columns=['filename', 'cell_id', 'cell_type', 'xmin', 'xmax', 'ymin', 'ymax'])data['image_id'] = data['filename'].apply(lambda x: int(x[-7:-4]))data[['filename', 'image_id', 'cell_id', 'cell_type', 'xmin', 'xmax', 'ymin', 'ymax']].to_csv('bccd.csv', index=False)

Recadrer

Pour pouvoir gérer les données, la première étape consiste à recadrer l’image en taille réelle en fonction des coordonnées du cadre de délimitation. Cela produit beaucoup d'images de cellules de différentes tailles :

Une brève analyse de l'apprentissage actif des données d'image cellulaire

Une brève analyse de l'apprentissage actif des données d'image cellulaire

Une brève analyse de l'apprentissage actif des données d'image cellulaire

Une brève analyse de l'apprentissage actif des données d'image cellulaire

Le code recadré est le suivant :

import osimport pandas as pdfrom PIL import Imagedef crop_cell(row):"""crop_cell(row)given a pd.Series row of the dataframe, load row['filename'] with PIL,crop it to the box row['xmin'], row['xmax'], row['ymin'], row['ymax']save the cropped image,return cropped filename"""input_dir = 'BCCDJPEGImages'output_dir = 'BCCDcropped'# open imageim = Image.open(f"{input_dir}{row['filename']}")# size of the image in pixelswidth, height = im.size# setting the points for cropped imageleft = row['xmin']bottom = row['ymax']right = row['xmax']top = row['ymin']# cropped imageim1 = im.crop((left, top, right, bottom))cropped_fname = f"BloodImage_{row['image_id']:03d}_{row['cell_id']:02d}.jpg"# shows the image in image viewer# im1.show()# save imagetry:im1.save(f"{output_dir}{cropped_fname}")except:return 'error while saving image'return cropped_fnameif __name__ == "__main__":# load labels csv into Pandas DataFramefilepath = "BCCDdataset2-masterlabels.csv"df = pd.read_csv(filepath)# iterate through cells, crop each cell, and save cropped cell to filedataset_df['cell_filename'] = dataset_df.apply(crop_cell, axis=1)

Ce qui précède représente toutes les opérations de prétraitement que nous avons effectuées. Maintenant, nous continuons à utiliser CellProfiler pour extraire des fonctionnalités.

Extraire les caractéristiques des cellules à l'aide de CellProfiler

CellProfiler est un logiciel d'analyse d'images gratuit et open source qui peut automatiser les mesures quantitatives à partir d'images cellulaires à grande échelle. CellProfiler contient également une interface graphique qui nous permet d'effectuer des opérations visuelles

Téléchargez d'abord CellProfiler. Si CellProfiler ne peut pas être ouvert, vous devrez peut-être installer le package de version Visual C++. Veuillez vous référer au site officiel pour les méthodes d'installation spécifiques.

Ouvrez le logiciel et vous pourrez charger l'image. Si vous souhaitez créer un pipeline, vous pouvez trouver la liste des fonctions disponibles fournies par CellProfiler sur son site officiel. La plupart des fonctions sont divisées en trois groupes principaux : traitement d'image, traitement de cible et mesure.

Les fonctions couramment utilisées sont les suivantes :

Traitement d'image - convertir en image en niveaux de gris :

Une brève analyse de l'apprentissage actif des données d'image cellulaire

Traitement de la cible d'objet - identifier les objets principaux

Une brève analyse de l'apprentissage actif des données d'image cellulaire

测量 - 测量对象强度

Une brève analyse de l'apprentissage actif des données d'image cellulaire

CellProfiler可以将输出为CSV文件或者保存指定数据库中。这里我们将输出保存为CSV文件,然后将其加载到Python进行进一步处理。

说明:CellProfiler还可以将你处理图像的流程保存并进行分享。

主动学习

我们现在已经有了训练需要的搜有数据,现在可以开始试验使用主动学习策略是否可以通过更少的数据标记获得更高的准确性。 我们的假设是:使用主动学习可以通过大量减少在细胞分类任务上训练机器学习模型所需的标记数据量来节省宝贵的时间和精力。

主动学习框架

在深入研究实验之前,我们希望对modAL进行快速介绍: modAL是Python的活跃学习框架。 它提供了Sklearn API,因此可以非常容易的将其集成到代码中。 该框架可以轻松地使用不同的主动学习策略。 他们的文档也很清晰,所以建议从它开始你的一个主动学习项目。

主动学习与随机学习

为了验证假设,我们将进行一项实验,将添加新标签数据的随机子抽样策略与主动学习策略进行比较。开始用一些相同的标记样本训练2个Logistic回归估计器。然后将在一个模型中使用随机策略,在第二个模型中使用主动学习策略。

我们首先为实验准备数据,加载由Cell Profiler言创建的特征。 这里过滤了无色血细胞的血小板,只保留红和白细胞(将问题简化,并减少数据量) 。所以现在我们正在尝试解决二进制分类问题 - RBC与WBC。使用Sklearn Label的label encoder进行编码,并拆分数据集进行训练和测试。

# imports for the whole experimentimport numpy as npfrom matplotlib import pyplot as pltfrom modAL import ActiveLearnerimport pandas as pdfrom modAL.uncertainty import uncertainty_samplingfrom sklearn import preprocessingfrom sklearn.metrics import , average_precision_scorefrom sklearn.linear_model import LogisticRegression# upload the cell profiler features for each celldata = pd.read_csv('Zaretski_Image_All.csv')# filter plateletsdata = data[data['cell_type'] != 'Platelets']# define the labeltarget = 'cell_type'label_encoder = preprocessing.LabelEncoder()y = label_encoder.fit_transform(data[target])# take the learning features onlyX = data.iloc[:, 5:]# create training and testing setsX_train, X_test, y_train, y_test = train_test_split(X.to_numpy(), y, test_size=0.33, random_state=42)

下一步就是创建模型

<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">dummy_learner</span> <span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">=</span> <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">LogisticRegression</span>()<br><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">active_learner</span> <span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">=</span> <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">ActiveLearner</span>(<br><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">estimator</span><span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">=</span><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">LogisticRegression</span>(),<br><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">query_strategy</span><span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">=</span><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">uncertainty_sampling</span>()<br>)

dummy_learner是使用随机策略的模型,而active_learner是使用主动学习策略的模型。为了实例化一个主动学习模型,我们使用modAL包中的ActiveLearner对象。在“estimator”字段中,可以插入任何sklearnAPI兼容的模型。在query_strategy '字段中可以选择特定的主动学习策略。这里使用“uncertainty_sampling()”。这方面更多的信息请查看modAL文档。

将训练数据分成两组。第一个是训练数据,我们知道它的标签,会用它来训练模型。第二个是验证数据,虽然标签也是已知的,但是我们假装不知道它的标签,并通过模型预测的标签和实际标签进行比较来评估模型的性能。然后我们将训练的数据样本数设置成5。

# the training size that we will start withbase_size = 5# the 'base' data that will be the training set for our modelX_train_base_dummy = X_train[:base_size]X_train_base_active = X_train[:base_size]y_train_base_dummy = y_train[:base_size]y_train_base_active = y_train[:base_size]# the 'new' data that will simulate unlabeled data that we pick a sample from and label itX_train_new_dummy = X_train[base_size:]X_train_new_active = X_train[base_size:]y_train_new_dummy = y_train[base_size:]y_train_new_active = y_train[base_size:]

我们训练298个epoch,在每个epoch中,将训练这俩个模型和选择下一个样本,并根据每个模型的策略选择是否将样本加入到我们的“基础”数据中,并在每个epoch中测试其准确性。因为分类是不平衡的,所以使用平均精度评分来衡量模型的性能。

在随机策略中选择下一个样本,只需将下一个样本添加到虚拟数据集的“新”组中,这是因为数据集已经是打乱的的,因此不需要在进行这个操作。对于主动学习,将使用名为“query”的ActiveLearner方法,该方法获取“新”组的未标记数据,并返回他建议添加到训练“基础”组的样本索引。被选择的样本都将从组中删除,因此样本只能被选择一次。

# arrays to accumulate the scores of each simulation along the epochsdummy_scores = []active_scores = []# number of desired epochsrange_epoch = 298# running the experimentfor i in range(range_epoch):# train the models on the 'base' datasetactive_learner.fit(X_train_base_active, y_train_base_active)dummy_learner.fit(X_train_base_dummy, y_train_base_dummy)# evaluate the modelsdummy_pred = dummy_learner.predict(X_test)active_pred = active_learner.predict(X_test)# accumulate the scoresdummy_scores.append(average_precision_score(dummy_pred, y_test))active_scores.append(average_precision_score(active_pred, y_test))# pick the next sample in the random strategy and randomly# add it to the 'base' dataset of the dummy learner and remove it from the 'new' datasetX_train_base_dummy = np.append(X_train_base_dummy, [X_train_new_dummy[0, :]], axis=0)y_train_base_dummy = np.concatenate([y_train_base_dummy, np.array([y_train_new_dummy[0]])], axis=0)X_train_new_dummy = X_train_new_dummy[1:]y_train_new_dummy = y_train_new_dummy[1:]# pick next sample in the active strategyquery_idx, query_sample = active_learner.query(X_train_new_active)# add the index to the 'base' dataset of the active learner and remove it from the 'new' datasetX_train_base_active = np.append(X_train_base_active, X_train_new_active[query_idx], axis=0)y_train_base_active = np.concatenate([y_train_base_active, y_train_new_active[query_idx]], axis=0)X_train_new_active = np.concatenate([X_train_new_active[:query_idx[0]], X_train_new_active[query_idx[0] + 1:]], axis=0)y_train_new_active = np.concatenate([y_train_new_active[:query_idx[0]], y_train_new_active[query_idx[0] + 1:]], axis=0)

结果如下:

plt.plot(list(range(range_epoch)), active_scores, label='Active Learning')plt.plot(list(range(range_epoch)), dummy_scores, label='Dummy')plt.xlabel('number of added samples')plt.ylabel('average precision score')plt.legend(loc='lower right')plt.savefig("models robustness vs dummy.png", bbox_inches='tight')plt.show()

Une brève analyse de l'apprentissage actif des données d'image cellulaire

策略之间的差异还是很大的,可以看到主动学习只使用25个样本就可以达到平均精度0.9得分! 而使用随机的策略则需要175个样本才能达到相同的精度!

De plus, le score du modèle avec stratégie d'apprentissage actif est proche de 0,99, tandis que le score du modèle aléatoire s'arrête aux alentours de 0,95 ! Si nous utilisons toutes les données, alors leurs scores finaux sont les mêmes, mais le but de notre étude est de s'entraîner sur une petite quantité de données étiquetées, donc seuls 300 échantillons aléatoires de l'ensemble de données sont utilisés.

Résumé

Cet article démontre les avantages de l'utilisation de l'apprentissage actif pour les tâches d'imagerie cellulaire. L'apprentissage actif est un ensemble de méthodes d'apprentissage automatique qui priorisent les solutions pour les exemples de données non étiquetées en fonction de l'impact de leurs étiquettes sur les performances du modèle. Étant donné que l’étiquetage des données est une tâche impliquant de nombreuses ressources (argent et temps), il est nécessaire de juger quels échantillons étiqueter afin de maximiser les performances du modèle.

L'imagerie cellulaire a apporté de grandes contributions aux domaines de la biologie, de la médecine et de la pharmacologie. Dans le passé, l’analyse d’images cellulaires nécessitait un capital humain professionnel précieux, mais l’émergence de technologies telles que l’apprentissage actif offre une très bonne solution pour des domaines tels que la médecine qui nécessitent de grandes quantités d’ensembles de données annotées par l’homme.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer