rgb颜色代码(cmyk在线配色生成器)

本文共7500字,建议阅读15+分钟。我们将讨论不同的特征工程方法如何帮助提高卷积神经网络的分类性能。不是所有的彩色图像都应该是彩色的,或者换句话说,不是所有用

本文共7500字,建议阅读15+分钟。

我们将讨论不同的特征工程方法如何帮助提高卷积神经网络的分类性能。

不是所有的彩色图像都应该是彩色的,或者换句话说,不是所有用RGB(红、绿、蓝)编码的图像都应该使用这些颜色!在本文中,我们将讨论不同的特征工程方法(扩展原始颜色值)如何帮助提高卷积神经网络的分类性能。

有许多方法可以改变和调整RGB图像的颜色编码(例如,将RGB转换为HSV、LAB或XYZ值;Scikit-image提供了许多很棒的例程来执行这种操作),但本文并不是关于这一点,而是更多地关于数据试图捕捉什么以及如何利用它。

数据集

为了更好地突出本文的目的,让我们看一下下面的三个数据集(每个图像显示了该数据集中的100个单独的图像):

rgb颜色代码(cmyk在线配色生成器)插图

这三个数据集是MedMNIST数据集的一部分——图像取自相应的论文。

这些数据集的共同点是来自给定数据集的单个图像具有其特定的颜色范围。虽然粉红色或红色色调会有波动,但对于大多数这些图像来说,图像之间的对比度差异比实际RGB颜色值所代表的差异更重要。

这为我们提供了一个独特的工程机会。不使用原始的RGB颜色值,我们可以研究数据集对特定颜色的适应性空是否会帮助和改善我们的最终结果指标。

为了研究这个话题,我们使用了MedMNIST的增强血细胞数据集(见原文)。该数据集包含来自10种不同血细胞类型的大约17,000幅图像。我们来看看这个数据集中的一些图片吧!

# Download dataset!wget https://zenodo.org/record/5208230/files/bloodmnist.npz# Load packagesimport numpy as npfrom glob import globimport matplotlib.pyplot as pltfrom tqdm.notebook import tqdmimport pandas as pdimport seaborn as snssns.set_context("talk")%config InlineBackend.figure_format = 'retina'# Load data setdata = np.load("bloodmnist.npz")X_tr = data["train_images"].astype("float32") / 255X_va = data["val_images"].astype("float32") / 255X_te = data["test_images"].astype("float32") / 255y_tr = data["train_labels"]y_va = data["val_labels"]y_te = data["test_labels"]labels = ["basophils", "eosinophils", "erythroblasts", "granulocytes_immature", "lymphocytes", "monocytes", "neutrophils", "platelets"]labels_tr = np.array([labels[j] for j in y_tr.ravel()])labels_va = np.array([labels[j] for j in y_va.ravel()])labels_te = np.array([labels[j] for j in y_te.ravel()])

rgb颜色代码(cmyk在线配色生成器)插图(1)#下载数据集!wget https://zenodo.org/record/5208230/files/bloodmnist.npz#加载包import numpy as NP from glob import glob import matplotlib . py plot as PLT from tqdm . notebook import tqd import pandas as PD import seaborn as SNS ns . set _ context(& # 34;说话& # 34;)% config inline backend . figure _ format = & # 39;视网膜& # 39;# Load data setdata = NP . Load(& # 34;bloodmnist.npz & # 34)X _ tr = data[& # 34;训练图像& # 34;].astype(& # 34;浮动32 & # 34;)/255 x _ va = data[& # 34;val _ images & # 34].astype(& # 34;浮动32 & # 34;)/255 x _ te = data[& # 34;测试图像& # 34;].astype(& # 34;浮动32 & # 34;)/255y _ tr = data[& # 34;火车标签& # 34;]y _ va = data[& # 34;val _ labels & # 34]y _ te = data[& # 34;测试标签& # 34;]labels =[& # 34;嗜碱性粒细胞& # 34;, "嗜酸性粒细胞& # 34;, "成红细胞& # 34;, "粒细胞_未成熟& # 34;, "淋巴细胞& # 34;, "单核细胞& # 34;, "中性粒细胞& # 34;, "血小板& # 34;]labels _ tr = NP . array([labels[j]for j in y _ tr . ravel()])labels _ va = NP . array([labels[j]for j in y _ va . ravel()])labels _ te = NP . array([labels[j]for j in y _ te . ravel()])

这些图像取自原始论文,描述了符合数据集的十种血细胞。

def plot_dataset(X): """Helper function to visualize first few images of a dataset.""" fig, axes = plt.subplots(12, 12, figsize=(15.5, 16)) for i, ax in enumerate(axes.flatten()): if X.shape[-1] == 1: ax.imshow(np.squeeze(X[i]), cmap="gray") else: ax.imshow(X[i]) ax.axis("off") ax.set_aspect("equal") plt.subplots_adjust(wspace=0, hspace=0) plt.show()# Plot datasetplot_dataset(X_tr)

rgb颜色代码(cmyk在线配色生成器)插图(2)def plot _ dataset(X):& # 34;""帮助器函数,用于可视化数据集的前几幅图像。"""fig,axes = plt.subplots(12,12,figsize=(15.5,16)) for i,ax in enumerate(axes . flatten()):if X . shape[-1]= = 1:ax . im show(NP . squeeze(X[I]),cmap = & # 34格雷& # 34;)else:ax . im show(X[I])ax . axis(& # 34;关& # 34;)ax . set _ aspect(& # 34;等于& # 34;)plt.subplots_adjust(wspace=0,hspace = 0)PLT . show()# Plot dataset Plot _ dataset(X _ tr)

我们可以看到如下:背景色和主目标色在大多数情况下是相同的(但也不总是如此)!为了更好的理解为什么这能给我们提供颜色值特征工程的机会,我们先来看看这些图像所占据的RGB颜色空。

# Extract a few RGB color valuesX_colors = X_tr.reshape(-1, 3)[::100]# Plot color values in 3D spacefig = plt.figure(figsize=(16, 5))# Loop through 3 different viewsfor i, view in enumerate([[-45, 10], [40, 80], [60, 10]]): ax = fig.add_subplot(1, 3, i + 1, projection="3d") ax.scatter(X_colors[:, 0], X_colors[:, 1], X_colors[:, 2], facecolors=X_colors, s=2) ax.set_xlabel("R") ax.set_ylabel("G") ax.set_zlabel("B") ax.xaxis.set_ticklabels([]) ax.yaxis.set_ticklabels([]) ax.zaxis.set_ticklabels([]) ax.view_init(azim=view[0], elev=view[1], vertical_axis="z") ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_zlim(0, 1)plt.suptitle("Colors in RGB space", fontsize=20)plt.show()

rgb颜色代码(cmyk在线配色生成器)插图(3)#提取几个RGB颜色值X _ colors = X _ tr . shape(-1,3)[::100]#在3D空间中绘制颜色值fig = plt.figure(figsize=(16,5))#在3个不同的视图中循环for i,view in enumerate([[-45,10],[40,80],[60,10]):ax = fig . add _ subplot(1,3,i + 1,projection = & # 343d & # 34)ax.scatter(X_colors[:,0],X_colors[:,1],X_colors[:,2],facecolors=X_colors,s = 2)ax . set _ xlabel(& # 34;R & # 34)ax . set _ y label(& # 34;G & # 34)ax . set _ zlabel(& # 34;B&第34名;)ax . xaxis . set _ tick labels([])ax . ya xis . set _ tick labels([])ax . zaxis . set _ tick labels([])ax . view _ init(azim = view[0],elev=view[1],vertical _ axis = & # 34z & # 34)ax.set_xlim(0,1) ax.set_ylim(0,1) ax.set_zlim(0,1)PLT . sup title(& # 34;RGB空间中的颜色& # 34;,fontsize=20)plt.show()

这是原始数据集的同一RGB颜色空上的三个不同视图。这个数据集只覆盖了整个立方体的一小部分,即全部16 & # 39;777'26种可能的颜色值。这为我们提供了三个独特的机会:

我们可以通过将 RGB 颜色转换为灰度图像来降低图像复杂性。我们可以重新对齐和拉伸颜色值,以便 RGB 值更好地填充 RGB 颜色空间。我们可以重新调整颜色值的方向,使三个立方体轴延伸到最大方差的方向。这最好通过 PCA 方法完成。

实际上,还有许多其他方法来操作颜色值,但是对于本文,我们将使用上面提到的三种方法。

数据集扩充

1.灰度变换

首先,让我们将RGB图像转换成灰度图像(即从3D到1D数据集)。灰度图像不仅是RGB的简单平均,而且是稍微不平衡的加权。在本文中,使用scikit-image的rgb2gray用于执行此转换。此外,我们将拉伸灰度值以完全覆盖图像的0到255个值的范围。

#安装scikit-image(如果尚未安装)!pip install-U scikit-image from skim age . color import RGB 2 gray #创建灰度图像X_tr_gray = rgb2gray(X_tr)[...,None]X_va_gray = rgb2gray(X_va)[...,None]X_te_gray = rgb2gray(X_te)[...,None]#将颜色范围拉伸到训练最小值,maxgmin _ tr = X _ tr _ gray . min()X _ tr _ gray-= gmin _ trX _ va _ gray-= gmin _ trX _ te _ gray-= gmin _ trgmax _ tr = X _ tr _ gray . max()X _ tr _ gray/= gmax _ trX _ va _ gray/= gmax _ trX _ te _ gray/= gmax _ trX _ va _ gray = NP . clip(X _ va _ gray,0,1) x axis=-1)#提取几个灰度颜色值X _ grays = X _ tr _ show . shape(-1,3)[::100]#在3D空间中绘制颜色值fig = plt.figure(figsize=(16,5))#遍历3个不同的视图for i,view in enumerate([[-45,10],[40,80],[60,10]):ax = fig . add _ subplot(1,3,i + 1,projection = & # 34 3d & # 34)ax.scatter(X_grays[:,0],X_grays[:,1],X_grays[:,2],facecolors=X_grays,s = 2)ax . set _ xlabel(& # 34;R & # 34)ax . set _ y label(& # 34;G & # 34)ax . set _ zlabel(& # 34;B&第34名;)ax . xaxis . set _ tick labels([])ax . ya xis . set _ tick labels([])ax . zaxis . set _ tick labels([])ax . view _ init(azim = view[0],elev=view[1],vertical _ axis = & # 34z & # 34)ax.set_xlim(0,1) ax.set_ylim(0,1) ax.set_zlim(0,1)PLT . sup title(& # 34;灰度空间中的颜色& # 34;,fontsize=20)plt.show()

rgb颜色代码(cmyk在线配色生成器)插图(4)

灰度值正好在立方体的对角线上。让我们将3D数据集缩减为一维。现在让我们看看灰度格式的细胞图像是什么样的。

# Plot dataset Plot _ dataset(X _ tr _ gray)

rgb颜色代码(cmyk在线配色生成器)插图(5)

2.颜色调整和拉伸

在第一个RGB立方体图中,我们看到这个数据集的颜色值只占整个立方体的一部分。当将这个点云与第二个RGB立方体中的黑白对角线进行对比时,我们可以看到,原来的颜色是离轴的,有轻微的弯曲。

为了更好地说明我们的意思,这里尝试找到支持这个点云的等距“云形心”(或形心)。

#获取RGB颜色值X _ colors = X _ tr . shape(-1,3)#获取所有颜色值到黑色的距离(0,0,0)dist _ origin = NP . linalg . norm(X _ colors,axis=-1)#查找0.1%最小entry PERC _ sorted = NP . arg sort(NP . ABS(dist _ origin-NP . percentile(dist _ origin,0.1))#查找最低0.1% RGBscentroid_low的形心= np.mean(X_colors) 即每个段的RGB平均值centroids = NP . array([NP . median(X _ colors[order _ idx][s],axis = 0)for s in tqdm(splits)]#只保留间隔足够大的质心new _ centers =[centroids[0]]for I in range(len(centroids)):if NP . linalg . norm(new _ centers[-1]-centroids[I])& gt; 0.03:new _ centers . append(centers[I])new _ centers = NP . array(new _ centers)找到这些中心后,在RGB颜色立方体中可视化。为了便于比较,应在图表中添加灰色对角线。

# Plot centroids in 3D spacefig = plt.figure(figsize=(16, 5))# Loop through 3 different viewsfor i, view in enumerate([[-45, 10], [40, 80], [60, 10]]): ax = fig.add_subplot(1, 3, i + 1, projection="3d") ax.scatter(X_grays[:, 0], X_grays[:, 1], X_grays[:, 2], facecolors=X_grays, s=10) ax.scatter( new_centers[:, 0], new_centers[:, 1], new_centers[:, 2], facecolors=new_centers, s=10) ax.set_xlabel("R") ax.set_ylabel("G") ax.set_zlabel("B") ax.xaxis.set_ticklabels([]) ax.yaxis.set_ticklabels([]) ax.zaxis.set_ticklabels([]) ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_zlim(0, 1) ax.view_init(azim=view[0], elev=view[1], vertical_axis="z")plt.suptitle("Color centroids in RGB space", fontsize=20)plt.show()

rgb颜色代码(cmyk在线配色生成器)插图(6)#在3D空间中绘制质心fig = plt.figure(figsize=(16,5))#在3个不同的视图中循环for i,view in enumerate([[-45,10],[40,80],[60,10]):ax = fig . add _ subplot(1,3,i + 1,projection = & # 343d & # 34)ax.scatter(X_grays[:,0],X_grays[:,1],X_grays[:,2],facecolors=X_grays,s=10) ax.scatter( new_centers[:,0],new_centers[:,1],new_centers[:,2],facecolors=new_centers,s = 10)ax . set _ xlabel(& # 34;R & # 34)ax . set _ y label(& # 34;G & # 34)ax . set _ zlabel(& # 34;B&第34名;)ax . xaxis . set _ tick labels([])ax . ya xis . set _ tick labels([])ax . zaxis . set _ tick labels([])ax . set _ xlim(0,1) ax.set_ylim(0,1) ax.set_zlim(0,1) ax.view_init(azim=view[0],elev=view[1],vertical _ axis = & # 34z & # 34)PLT . sup title(& # 34;RGB空间中的颜色质心& # 34;,fontsize=20)plt.show()

那么我们如何利用这两条信息(云形心和灰度对角线)来重新排列和拉伸我们的原始数据集呢?一种有效的方法如下:

对于原始数据集中的每个颜色值,我们计算到最近的云质心的距离向量。然后将此距离向量添加到灰度对角线(即重新对齐质心)。拉伸和剪切颜色值,以确保 99.9% 的所有值都在所需的颜色范围内。

#创建灰度对角形心(与云形心数量相等)steps = np.linspace(0.2,0.8,len(new_centers))#重新对齐并拉伸images X _ tr _ Stretch = NP . array([X-new _ centers[NP . Lina LG . norm(X-new _ centers,axis = 1)))+steps[NP . Lina LG . norm(NP . Lina LG . norm(X-new _ centers,axis=1))]对于tqdm中的X(X _ tr axis = 0)X _ tr _ stretch-= xmin _ trX _ va _ stretch-= xmin _ trX _ te _ stretch-= xmin _ trX max _ tr = NP . percentile(X _ tr _ stretch,99.95,axis = 0)X _ tr _ stretch/= xmax _ trX _ va _ stretch/= xmax _ trX _ te _ stretch/= xmax _ trX _ tr _ stretch = NP . clip(X _ tr _ stretch,0,1) x _ va _ stretch = np .

# Plot color values in 3D spacefig = plt.figure(figsize=(16, 5))stretch_colors = X_tr_stretch[::100]# Loop through 3 different viewsfor i, view in enumerate([[-45, 10], [40, 80], [60, 10]]): ax = fig.add_subplot(1, 3, i + 1, projection="3d") ax.scatter( stretch_colors[:, 0], stretch_colors[:, 1], stretch_colors[:, 2], facecolors=stretch_colors, s=2) ax.set_xlabel("R") ax.set_ylabel("G") ax.set_zlabel("B") ax.xaxis.set_ticklabels([]) ax.yaxis.set_ticklabels([]) ax.zaxis.set_ticklabels([]) ax.view_init(azim=view[0], elev=view[1], vertical_axis="z") ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_zlim(0, 1)plt.suptitle("Colors in realigned and stretched space", fontsize=20)plt.show()

rgb颜色代码(cmyk在线配色生成器)插图(7)#在3D空间中绘制颜色值fig = plt.figure(figsize=(16,5))stretch _ colors = X _ tr _ stretch[::100]#在3个不同的视图中循环for i,view in enumerate([-45,10],[40,80],[60,10]):ax = fig . add _ subplot(1,3,i + 1,projection = & # 343d & # 34)ax.scatter( stretch_colors[:,0],stretch_colors[:,1],stretch_colors[:,2],facecolors=stretch_colors,s = 2)ax . set _ xlabel(& # 34;R & # 34)ax . set _ y label(& # 34;G & # 34)ax . set _ zlabel(& # 34;B&第34名;)ax . xaxis . set _ tick labels([])ax . ya xis . set _ tick labels([])ax . zaxis . set _ tick labels([])ax . view _ init(azim = view[0],elev=view[1],vertical _ axis = & # 34z & # 34)ax.set_xlim(0,1) ax.set_ylim(0,1) ax.set_zlim(0,1)PLT . sup title(& # 34;重新排列和拉伸空间中的颜色& # 34;,fontsize=20)plt.show()

这看起来已经很好了。点云更好地与立方体的对角线对齐,看起来点云向各个方向延伸了一点。在这种新的颜色编码中,细胞图像是什么样的?

# Convert data back into image spaceX_tr_stretch = X_tr_stretch.reshape(X_tr.shape)X_va_stretch = X_va_stretch.reshape(X_va.shape)X_te_stretch = X_te_stretch.reshape(X_te.shape)# Plot datasetplot_dataset(X_tr_stretch)

rgb颜色代码(cmyk在线配色生成器)插图(8)#将数据转换回图像spaceX _ tr _ stretch = X _ tr _ stretch . shape(X _ tr . shape)X _ va _ stretch = X _ va _ stretch . shape(X _ va . shape)X _ te _ stretch = X _ te _ stretch . shape(X _ te . shape)# Plot dataset Plot _ dataset(X _ tr _ stretch)

3.PCA转换

最后,让我们使用PCA方法将原始RGB颜色值转换为新的3D 空房间。这三个新轴都尽可能地解释了不同之处。对于这种方法,本文将使用原始的RGB颜色值,但您也可以使用刚刚重新排列和拉伸的值。

那么这个新的PCA color 空室中原来的RGB颜色值是多少呢?

# Train PCA decomposition on original RGB valuesfrom sklearn.decomposition import PCApca = PCA()pca.fit(X_tr.reshape(-1, 3))# Transform all data sets into new PCA spaceX_tr_pca = pca.transform(X_tr.reshape(-1, 3))X_va_pca = pca.transform(X_va.reshape(-1, 3))X_te_pca = pca.transform(X_te.reshape(-1, 3))# Stretch and clip dataxmin_tr = np.percentile(X_tr_pca, 0.05, axis=0)X_tr_pca -= xmin_trX_va_pca -= xmin_trX_te_pca -= xmin_trxmax_tr = np.percentile(X_tr_pca, 99.95, axis=0)X_tr_pca /= xmax_trX_va_pca /= xmax_trX_te_pca /= xmax_trX_tr_pca = np.clip(X_tr_pca, 0, 1)X_va_pca = np.clip(X_va_pca, 0, 1)X_te_pca = np.clip(X_te_pca, 0, 1)# Flip first componentX_tr_pca[:, 0] = 1 - X_tr_pca[:, 0]X_va_pca[:, 0] = 1 - X_va_pca[:, 0]X_te_pca[:, 0] = 1 - X_te_pca[:, 0]# Extract a few RGB color valuesX_colors = X_tr_pca[::100].reshape(-1, 3)# Plot color values in 3D spacefig = plt.figure(figsize=(16, 5))# Loop through 3 different viewsfor i, view in enumerate([[-45, 10], [40, 80], [60, 10]]): ax = fig.add_subplot(1, 3, i + 1, projection="3d") ax.scatter(X_colors[:, 0], X_colors[:, 1], X_colors[:, 2], facecolors=X_colors, s=2) ax.set_xlabel("PC1") ax.set_ylabel("PC2") ax.set_zlabel("PC3") ax.xaxis.set_ticklabels([]) ax.yaxis.set_ticklabels([]) ax.zaxis.set_ticklabels([]) ax.view_init(azim=view[0], elev=view[1], vertical_axis="z") ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_zlim(0, 1)plt.suptitle("Colors in PCA space", fontsize=20)plt.show()

rgb颜色代码(cmyk在线配色生成器)插图(9)#根据sklearn.decomposition中的原始RGB值训练PCA分解import PCA = PCA()PCA . fit(X _ tr . shape(-1,3))#将所有数据集转换为新的PCA spaceX _ tr _ PCA = PCA . Transform(X _ tr . shape(-1,3))X _ va _ PCA = PCA . Transform(X _ va . shape(-1,3))X _ te _ PCA = PCA . Transform(X _ te . shape(-1,3))# Stretch and clip data xmin _ tr = NPreshape(-1,3)#在3D空间中绘制颜色值fig = plt.figure(figsize=(16,5))#在3个不同的视图中循环for i,view in enumerate([[-45,10],[40,80],[60,10]):ax = fig . add _ subplot(1,3,i + 1,projection = & # 343d & # 34)ax.scatter(X_colors[:,0],X_colors[:,1],X_colors[:,2],facecolors=X_colors,s = 2)ax . set _ xlabel(& # 34;PC1 & # 34)ax . set _ y label(& # 34;PC2 & # 34)ax . set _ zlabel(& # 34;PC3 & # 34;)ax . xaxis . set _ tick labels([])ax . ya xis . set _ tick labels([])ax . zaxis . set _ tick labels([])ax . view _ init(azim = view[0],elev=view[1],vertical _ axis = & # 34z & # 34)ax.set_xlim(0,1) ax.set_ylim(0,1) ax.set_zlim(0,1)PLT . sup title(& # 34;PCA空间中的颜色& # 34;,fontsize=20)plt.show()

拉伸效果很好!但是图像呢?让我们看一看。

#将数据转换回图像spaceX _ tr _ PCA = X _ tr _ PCA . shape(X _ tr . shape)X _ va _ PCA = X _ va _ PCA . shape(X _ va . shape)X _ te _ PCA = X _ te _ PCA . shape(X _ te . shape)# Plot dataset Plot _ dataset(X _ tr _ PCA)

rgb颜色代码(cmyk在线配色生成器)插图(10)

这看起来也很有趣。每个部分的颜色都不一样,比如背景、细胞核、细胞核周围的东西颜色都不一样。但是,PCA转换也带来了图像中的一个伪影——图像中间的十字状颜色边界。不清楚这是从哪里来的,但我认为这是由于MedMNIST通过对原始数据集进行下采样而引入的数据集操作。

特征的相关性

在继续我们的下一部分研究(即测试这些颜色运算是否可以帮助卷积神经网络对10个目标类进行分类)之前,让我们快速看看这些新的颜色值是如何相互关联的。

# Combine all images in one big dataframeX_tr_all = np.vstack([X_tr.T, X_tr_gray.T, X_tr_stretch.T, X_tr_pca.T]).TX_va_all = np.vstack([X_va.T, X_va_gray.T, X_va_stretch.T, X_va_pca.T]).TX_te_all = np.vstack([X_te.T, X_te_gray.T, X_te_stretch.T, X_te_pca.T]).T# Compute correlation matrix between all color featurescorr_all = np.corrcoef(X_tr_all.reshape(-1, X_tr_all.shape[-1]).T)cols = ["Red", "Green", "Blue", "Gray", "Stretch1", "Stretch2", "Stretch3", "PC1", "PC2", "PC3"]plt.figure(figsize=(8, 8))sns.heatmap( 100 * corr_all, square=True, center=0, annot=True, fmt=".0f", cbar=False, xticklabels=cols, yticklabels=cols,)

rgb颜色代码(cmyk在线配色生成器)插图(11)#将所有图像合并成一个大的data framex _ tr _ all = NP . v stack([X _ tr。t,X_tr_gray。t,X_tr_stretch。t,X_tr_pca。T])。TX_va_all = np.vstack([X_va.T,X_va_gray。t,X_va_stretch。t,X_va_pca。T])。TX_te_all = np.vstack([X_te。t,X_te_gray。t,X_te_stretch。t,X_te_pca。T])。T#计算所有颜色特征之间的相关矩阵corr _ all = NP . corrcoef(X _ tr _ all . shape(-1,X_tr_all.shape[-1])。t)cols =[& # 34;红色& # 34;, "绿色& # 34;, "蓝色& # 34;, "格雷& # 34;, "Stretch1 & # 34, "Stretch2 & # 34, "拉伸3 & # 34;, "PC1 & # 34, "PC2 & # 34, "PC3 & # 34;]plt.figure(figsize=(8,8))sns.heatmap( 100 * corr_all,square=True,center=0,annot=True,fmt = & # 34. 0f & # 34,cbar=False,xticklabels=cols,yticklabels=cols,)

我们可以看到,许多新的颜色特征与原始RGB值高度相关(除了第二个和第三个PCA特征)。接下来可以测试颜色处理对图像分类是否有帮助。

测试图像分类

看看我们的颜色处理能否帮助卷积神经网络对8个目标类进行分类。我们创建一个“小”ResNet模型,并在数据集的所有4个版本(即原始、灰度、拉伸和PCA)上对其进行训练。

#这个ResNet架构的代码就是从这里改编的:# https://towardsdatascience.com/ building-a-ResNet-in-keras-e8f 1322 a 49 ba from Tensor flow导入Tensor from Tensor flow . keras . layers导入(Input,Conv2D,ReLU,BatchNormalization,Add,AveragePooling2D,Flatten,Dense,Dropout)from Tensor flow . keras . models导入model def ReLU _ bn(inputs:Tensor)-& gt;Tensor:ReLU = ReLU()(inputs)bn = batch normalization()(ReLU)return bndef residual _ block(x:Tensor,downsample: bool,filters: int,kernel _ size:int = 3)-& gt;tensor:y = conv 2d(kernel _ size = kernel _ size,strides=(1如果不是下采样else 2),filters=filters,padding = & # 34相同& # 34;)(x)y = relu _ bn(y)y = conv 2d(kernel _ size = kernel _ size,strides=1,filters=filters,padding = & # 34相同& # 34;)(y)如果缩减采样:x = Conv2D(kernel_size=1,strides=2,filters=filters,padding = & # 34相同& # 34;)(x) out = Add()([x,y])out = relu _ bn(out)return outdef create _ RES _ net(in _ shape =(28,28,3)):inputs = Input(shape = in _ shape)num _ filters = 32t = batch normalization()(inputs)t = conv 2d(kernel _ size = 3,strides=1,filters=num_filters,padding = & # 34相同& # 34;)(t)t = relu _ bn(t)num _ blocks _ list =[2,2]for I in range(len(num _ blocks _ list)):num _ blocks = num _ blocks _ list[I]for j in range(num _ blocks):t = residual _ block(t,downsample=(j == 0且I!= 0),filters = num _ filters)num _ filters * = 2t = AveragePooling2D(4)(t)t = Flatten()(t)t = Dense(128,activation = & # 34relu & # 34)(t)t = Dropout(0.5)(t)outputs = Dense(8,activation = & # 34softmax & # 34)(t) model = Model(inputs,outputs)Model . compile(optimizer = & # 34;亚当& # 34;,损失= & # 34;稀疏_分类_交叉熵& # 34;,metrics =[& # 34;准确性& # 34;])return modeldef run _ resnet(X _ tr,y_tr,X_va,y_va,epochs=200,verbose = 0):& # 34;""培训ResNet模型的支持功能& # 34;""# Create Model Model = Create _ RES _ net(in _ shape = X _ tr . shape[1:])# Creates & # 39;提前停止& # 39;从tensorflow导入keras early stopping _ CB = keras . callbacks . early stopping(patience = 10,restore _ best _ weights = True)# Train model history = model . fit(X _ tr,y_tr,batch_size=120,epochs=epochs,validation_data=(X_va,y_va),callbacks=[earlystopping_cb],verbose=verbose)返回模型,history def plot _ history(history):& # 34;""支持绘制模型历史的功能& # 34;""#绘制用于训练和验证的神经网络性能度量fig,axs = plt.subplots(1,2,figsize=(15,4)) results = pd。DataFrame(history.history)结果[[& # 34;准确性& # 34;, "val _ accuracy & # 34]].plot(ax=axs[0])结果[[& # 34;损失& # 34;, "val _ loss & # 34]].plot(ax=axs[1],logy = True)PLT . tight _ layout()PLT . show()def plot _ classification _ report(X _ te,y_te,model):& # 34;""支持绘制分类报告的功能& # 34;""#显示来自sklearn.metrics导入分类的分类报告_ report y _ pred = model . predict(X _ te)。arg max(axis = 1)print(classification _ report(y _ te . ravel(),y_pred))# Show confusion matrix from sk learn . metrics import confusionmatrix display fig,ax = plt.subplots(1,2,figsize=(16,7))confusionmatrix display . from _ predictions(y _ te . ravel(),y _ pred,ax=ax[0],colorbar=False,cmap = & # 34inferno _ r & # 34)from sklearn.metrics导入confusionmatrix display confusionmatrix display . from _ predictions(y _ te . ravel(),y_pred,normalize = & # 34真& # 34;,ax=ax[1],values _ format = & # 34. 1f & # 34,colorbar=False,cmap = & # 34inferno _ r & # 34)原始数据集的分类性能

首先,在原始数据集上训练ResNet模型以建立基线。模型在训练期间的性能(精度和损耗)如下所示。

# Train modelmodel_orig, history_orig = run_resnet(X_tr, y_tr, X_va, y_va)# Show model performance during trainingplot_history(history_orig)

rgb颜色代码(cmyk在线配色生成器)插图(12)# Train modelmodel_orig,history_orig = run_resnet(X_tr,y_tr,X_va,y_va)#显示训练期间的模型性能plot_history(history_orig)

# Evaluate Modelloss_orig_tr,ACC _ orig _ tr = Model _ orig . Evaluate(X _ tr,y_tr)loss_orig_va,ACC _ orig _ va = Model _ orig . Evaluate(X _ va,y_va)loss_orig_te,ACC _ orig _ te = Model _ orig . Evaluate(X _ te,y_te)# Report分类报告和混淆矩阵xplot _ classification _ Report(X _ te,y_te,Model _ orig)train score:loss = 0.055左侧的混淆矩阵显示了正确/错误识别样本的数量,而右侧显示了每个目标类别的比例值。

rgb颜色代码(cmyk在线配色生成器)插图(13)

灰色数据集的分类性能

对灰度转换图像做同样的事情。训练时模特表现如何?

# Train modelmodel_gray, history_gray = run_resnet(X_tr_gray, y_tr, X_va_gray, y_va)# Show model performance during trainingplot_history(history_gray)

rgb颜色代码(cmyk在线配色生成器)插图(14)#训练模型model_gray,history _ gray = run _ resnet(X _ tr _ gray,y_tr,X_va_gray,y_va)#显示训练期间的模型性能plot_history(history_gray)

混淆矩阵呢?

# Evaluate Modelloss_gray_tr, acc_gray_tr = model_gray.evaluate(X_tr_gray, y_tr)loss_gray_va, acc_gray_va = model_gray.evaluate(X_va_gray, y_va)loss_gray_te, acc_gray_te = model_gray.evaluate(X_te_gray, y_te)# Report classification report and confusion matrixplot_classification_report(X_te_gray, y_te, model_gray)Train score: loss = 0.1118 - accuracy = 0.9619Valid score: loss = 0.2255 - accuracy = 0.9287Test score: loss = 0.2407 - accuracy = 0.9220

rgb颜色代码(cmyk在线配色生成器)插图(15)# Evaluate Modelloss_gray_tr,ACC _ gray _ tr = model_gray . Evaluate(X _ tr _ gray,y_tr)loss_gray_va,ACC _ gray _ va = model _ gray . Evaluate(X _ va _ gray,y_va)loss_gray_te,ACC _ gray_te = model _ gray . Evaluate(X _ te _ gray,y_te)# Report分类报告和混淆矩阵xplot _ classification _ Report(X _ te,y _ te,model _ gray)训练得分:loss = 0.1118

重新调整和扩展数据集的分类性能。

对重新对齐和拉伸的图像做同样的事情。

# Train modelmodel_stretch, history_stretch = run_resnet(X_tr_stretch, y_tr, X_va_stretch, y_va)# Show model performance during trainingplot_history(history_stretch)

rgb颜色代码(cmyk在线配色生成器)插图(16)# Train modelmodel_stretch,history _ stretch = run _ resnet(X _ tr _ stretch,y_tr,X_va_stretch,y_va)#显示训练期间的模型性能plot_history(history_stretch)

混淆矩阵

# Evaluate Modelloss_stretch_tr, acc_stretch_tr = model_stretch.evaluate(X_tr_stretch, y_tr)loss_stretch_va, acc_stretch_va = model_stretch.evaluate(X_va_stretch, y_va)loss_stretch_te, acc_stretch_te = model_stretch.evaluate(X_te_stretch, y_te)# Report classification report and confusion matrixplot_classification_report(X_te_stretch, y_te, model_stretch)Train score: loss = 0.0229 - accuracy = 0.9921Valid score: loss = 0.1672 - accuracy = 0.9533Test score: loss = 0.1975 - accuracy = 0.9491

rgb颜色代码(cmyk在线配色生成器)插图(17)# Evaluate Modelloss_stretch_tr,ACC _ stretch _ tr = model_stretch . Evaluate(X _ tr _ stretch,y_tr)loss_stretch_va,ACC _ stretch _ va = model _ stretch . Evaluate(X _ va _ stretch,y_va)loss_stretch_te,ACC _ stretch _ te = model _ stretch . Evaluate(X _ te _ stretch,y_te)# Report分类报告和混淆矩阵xplot _ class ification _ Report(X _ te,y_te,model _ stretch)训练得分:loss = 0.0229

PCA转换数据集的分类性能

# Train modelmodel_pca, history_pca = run_resnet(X_tr_pca, y_tr, X_va_pca, y_va)# Show model performance during trainingplot_history(history_pca)

rgb颜色代码(cmyk在线配色生成器)插图(18)#训练模型model_pca,history _ PCA = run _ resnet(X _ tr _ PCA,y_tr,X_va_pca,y_va)#显示训练期间的模型性能plot_history(history_pca)

混淆矩阵

# Evaluate Modelloss_pca_tr, acc_pca_tr = model_pca.evaluate(X_tr_pca, y_tr)loss_pca_va, acc_pca_va = model_pca.evaluate(X_va_pca, y_va)loss_pca_te, acc_pca_te = model_pca.evaluate(X_te_pca, y_te)# Report classification report and confusion matrixplot_classification_report(X_te_pca, y_te, model_pca)Train score: loss = 0.0289 - accuracy = 0.9918Valid score: loss = 0.1459 - accuracy = 0.9509Test score: loss = 0.1898 - accuracy = 0.9448

rgb颜色代码(cmyk在线配色生成器)插图(19)# Evaluate Modelloss_pca_tr,ACC _ PCA _ tr = model _ PCA . Evaluate(X _ tr _ PCA,y_tr)loss_pca_va,ACC _ PCA _ va = model _ PCA . Evaluate(X _ va _ PCA,y_va)loss_pca_te,ACC _ PCA _ te = model _ PCA . Evaluate(X _ te _ PCA,y_te)# Report分类报告和混淆矩阵xplot _ class ification _ Report(X _ te _ PCA,y_te,model _

模型对比

在训练完所有这些个体模型之后,我们来看看它们之间的关系以及它们之间的区别。首先,将它们各自对测试集的预测画在一起,并比较这些不同模型预测相同值的方式。

# Compute model specific predictionsy_pred_orig = model_orig.predict(X_te).argmax(axis=1)y_pred_gray = model_gray.predict(X_te_gray).argmax(axis=1)y_pred_stretch = model_stretch.predict(X_te_stretch).argmax(axis=1)y_pred_pca = model_pca.predict(X_te_pca).argmax(axis=1)# Aggregate all model predictionstarget = y_te.ravel()predictions = np.array([y_pred_orig, y_pred_gray, y_pred_stretch, y_pred_pca])[ :, np.argsort(target)]# Plot model individual predictionsplt.figure(figsize=(20, 3))plt.imshow(predictions, aspect="auto", interpolation="nearest", cmap="rainbow")plt.xlabel(f"Predictions for all {predictions.shape[1]} test samples")plt.ylabel("Model")plt.yticks(ticks=range(4), labels=["Orig", "Gray", "Stretched", "PCA"]);

rgb颜色代码(cmyk在线配色生成器)插图(20)#计算特定于模型的预测sy _ pred _ orig = model _ orig . predict(X _ te)。arg max(axis = 1)y _ pred _ gray = model _ gray . predict(X _ te _ gray)。arg max(axis = 1)y _ pred _ stretch = model _ stretch . predict(X _ te _ stretch)。arg max(axis = 1)y _ pred _ PCA = model _ PCA . predict(X _ te _ PCA)。argmax(axis=1)#聚合所有模型预测star get = y _ te . ravel()predictions = NP . array([y _ pred _ orig,y_pred_gray,y_pred_stretch,y_pred_pca])[:,np.argsort(target)]# Plot模型个体预测splt . fig size =(20,3))plt.imshow(predictions,aspect = & # 34auto & # 34,插值= & # 34;最近的& # 34;,cmap = & # 34彩虹& # 34;)PLT . xlabel(f & # 34;所有{predictions.shape[1]}测试样本的预测& # 34;)PLT . y label(& # 34;型号& # 34;)plt.yticks(ticks=range(4),labels =[& # 34;Orig & # 34, "格雷& # 34;, "伸展& # 34;, "PCA & # 34]);

我们可以看到,除了原始数据集,其他模型在第8个目标类(红色部分)都不会出错。所以我们的操作看起来是有用的。在三种方法中,“重新排列和拉伸”的数据集似乎表现最好。为了支持这种说法,让我们看看我们的四个模型的测试精度。

# Collect accuraciesaccs_te = np.array([acc_orig_te, acc_gray_te, acc_stretch_te, acc_pca_te]) * 100# Plot accuraciesplt.figure(figsize=(8, 3))plt.title("Test accuracy for our four models")plt.bar(["Orig", "Gray", "Stretched", "PCA"], accs_te, alpha=0.5)plt.hlines(accs_te[0], -0.4, 3.4, colors="black", linestyles="dotted")plt.ylim(90, 98);

rgb颜色代码(cmyk在线配色生成器)插图(21)# Collect accuracies cs _ te = NP . array([ACC _ orig _ te,acc_gray_te,acc_stretch_te,ACC _ PCA _ te])* 100 # Plot accuracies PLT . figure(fig size =(8,3))PLT . title(& # 34;测试我们四种型号的精确度& # 34;)PLT . bar([& # 34;Orig & # 34, "格雷& # 34;, "伸展& # 34;, "PCA & # 34],accs_te,alpha = 0.5)PLT . hlines(accs _ te[0],-0.4,3.4,colors = & # 34黑色& # 34;,linestyles = & # 34点线& # 34;)plt.ylim(90,98);

模型叠加

这四种型号之间存在一些差异。让我们尝试进一步训练一个“元”模型,它使用我们的4个模型的预测作为输入。

#计算所有模型和数据集的预测概率sy _ prob _ tr _ orig = model _ orig . predict(X _ tr)y _ prob _ tr _ gray = model _ gray . predict(X _ tr _ gray)y _ prob _ tr _ stretch = model _ stretch . predict(X _ tr _ stretch)y _ prob _ tr _ PCA = model _ PCA . predict(X _ tr _ PCA)y _ prob _ va _ orig = model _ orig . predict(X _ va)y _ prob _ va _ grayravel()有许多不同的分类模型可供选择,但为了保持其简短紧凑,让我们快速训练一个多层感知器分类器,并将其得分与其他四个模型进行比较。

从sklearn.neural_network导入MLPClassifier#创建MLP分类器clf = MLP classifier(hidden _ layer _ sizes =(32,16),activation = & # 34relu & # 34,规划求解= & # 34;亚当& # 34;,alpha=0.42,batch_size=120,learning _ rate = & # 34适应性& # 34;,learning_rate_init=0.001,max_iter=100,shuffle=True,random_state=24,early_stopping=True,validation _ fraction = 0.15)# Train model clf . fit(y _ prob _ Train,y_train)#计算元分类器的预测精度ACC _ meta _ te = NP . mean(clf . predict(y _ prob _ te)= = y _ te . ravel())# Collect accuracies cs _ te = NP . array([ACC _ orig测试所有五种型号的精确度& # 34;)PLT . bar([& # 34;Orig & # 34, "格雷& # 34;, "伸展& # 34;, "PCA & # 34, "Meta & # 34],accs_te,alpha = 0.5)PLT . bar([& # 34;Orig & # 34, "格雷& # 34;, "伸展& # 34;, "PCA & # 34, "Meta & # 34],accs_meta,alpha = 0.5)PLT . hlines(accs _ te[0],-0.4,4.4,colors = & # 34黑色& # 34;,linestyles = & # 34点线& # 34;)plt.ylim(90,98);

rgb颜色代码(cmyk在线配色生成器)插图(22)

干得好!在原始数据集和三个颜色变换数据集上训练四个不同的模型,然后用这些预测概率训练一个新的元分类器,帮助我们把初始预测准确率从94%提高到96.4%!

本文地址:

https://miykael . github . io/blog/2021/color _ engineering _ medmnist/

作者:迈克尔·诺特

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/183310.html

发表回复

登录后才能评论