【问题标题】:picture formatting for kernel svm内核 svm 的图片格式
【发布时间】:2019-06-19 16:46:26
【问题描述】:

我在将一系列图像转换为正确格式以输入 sklearn.svm.SVC 时遇到了一些困难。

这是我的第一个图像识别项目,所以我有点痛苦。

我有一个循环,它将一堆 base64 RGB 图像(不同大小)引入数据帧

imageData = mpimg.imread(io.BytesIO(base64.b64decode(value)),format='JPG')

然后我将 RGB 图像转换为灰度,并展平

data_images = rgb2gray(imageData).ravel()

rgb2gray:

def rgb2gray(rgb):
    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
    return gray

如果我看尺寸差异

df_raw.sample(10)

我们可以看到我的样本之间的图片像素长度是不一样的。我对如何进行有点困惑。由于没有更好的主意,我决定根据最大尺寸的图片添加填充,

df_raw.picLen.max()

然后在每个 1D 图片数组的末尾附加一些零。

def padPic(x,numb,maxN):
    N = maxN-len(x)
    out = np.pad(x,(numb,N),'constant')
    return out

打电话

df_raw['picNew'] = df_raw.apply(lambda row: padPic(row['pic'],0,df_raw.picLen.max()), axis=1)
df_raw['picNewLen']  = df_raw.apply(lambda row: len(row['picNew']), axis=1)

我现在有所有相同大小的数组

从这里我尝试使用图片数据作为 X 和一组标签作为 y 来拟合一个模型来支持向量算法。

from sklearn.svm import SVC
X_train, X_test, y_train, y_test = train_test_split(df_raw.picNew, df_raw.name, test_size = 0.2, random_state=42)

检查尺寸:

print('Training data and target sizes: \n{}, {}'.format(X_train.shape,y_train.shape))
print('Test data and target sizes: \n{}, {}'.format(X_test.shape,y_test.shape))

训练数据和目标大小:(198,), (198,) 测试数据和目标 尺寸:(50,), (50,)

在我说服自己一切准备就绪后,我尝试拟合模型

svm = SVC()
svm.fit(X_train, y_train)

这会引发错误,我不知道为什么:

/opt/wakari/anaconda/envs/ulabenv_2018-11-13_10.15.00/lib/python3.5/site-packages/numpy/core/numeric.py in asarray(a, dtype, order) 499 500""" --> 501 返回数组(a,dtype,copy=False,order=order) 502 503

ValueError: 使用序列设置数组元素。

我认为这一定与数组大小有关,但我无法弄清楚。 :-/

除了错误之外,更一般地说,我对我的方法有一个疑问。特别是我认为我的“填充”可能不正确,也许调整大小会更好。 我感谢对我的方法的任何反馈。谢谢

【问题讨论】:

    标签: python arrays scikit-learn classification svm


    【解决方案1】:

    我发现了问题所在。

    感谢 Artem 发现了我没有对类进行编码的明显问题,但这最终不是我的问题。

    原来我的图片数组的表示方式不正确。 原始数组是 df_raw['picNew'].shape,其计算结果为

    (248,)

    我需要的是 2D 表示

    np.stack(df_raw['picNew'] , axis=1).shape
    

    (830435, 248)

    现在一切都好。

    我仍然不确定将图像大小调整为相同长度的最“正确”方法。将 0 附加到数组长度似乎有点简单......所以如果有人有想法:)

    【讨论】:

      【解决方案2】:

      我很确定这是由于在特征列中使用列表和字符串作为目标值。对于后者,您需要使用LabelEncoder 类将它们转换为规范化的类标签,根据 fit() 的要求。

      请参阅此处的说明: https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html

      这需要在训练/测试拆分之前完成,以确保标签编码器“看到”所有名称。

      对于前者,您可能需要搜索 MNIST 教程,这些教程将提供大量应用于图像分类问题的算法。

      此外,在展平之前调整大小应该比填充效果更好。

      【讨论】:

      • 拍摄,我完全错过了编码器。谢谢你。当我适合并设置编码器 le = LabelEncoder(), le.fit(df_raw.name), le.transform(df_raw.name) 我仍然有同样的错误。
      • 只是为了表明我的图片具有相同数量的元素。 'result = map(lambda x: len(x), X_train), print(np.unique(list(result))) ' [830435]
      猜你喜欢
      • 2014-09-17
      • 2014-04-28
      • 2021-12-03
      • 2016-01-21
      • 2018-11-12
      • 2019-08-23
      • 2014-05-08
      • 2012-09-28
      • 2013-04-05
      相关资源
      最近更新 更多