内核svm的图片格式
picture formatting for kernel svm
我很难将一系列图像转换为正确的格式以输入 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()
然后在每个一维图片数组的末尾附加一些零。
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))
Training data and target sizes: (198,), (198,) Test data and target
sizes: (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 return array(a, dtype, copy=False, order=order)
502
503
ValueError: setting an array element with a sequence.
我想这一定与数组大小有关,但我想不通。 :-/
除了错误之外,更一般地说,我对我的方法有一个疑问。特别是我认为我的 "padding" 可能不正确,也许调整大小会更好。
我感谢对我的方法的任何反馈。谢谢
我很确定这是因为在特征列中使用列表并将字符串作为目标值。对于后者,您需要使用 LabelEncoder
class 将它们转换为规范化的 class 标签,如 fit() 所要求的那样。
查看此处的说明:
https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html
这需要在 train/test 拆分之前完成,以确保 LabelEncoder 拥有所有名称 'seen'。
对于前者,您可能需要搜索 MNIST 教程,它将提供大量应用于图像 class化问题的算法。
此外,在展平之前调整大小应该比填充效果更好。
我找到问题了。
感谢 Artem 发现了我没有编码 类 的明显问题,但这最终不是我的问题。
原来我的图片数组的表示方式不正确。
原始数组是 df_raw['picNew'].shape
计算结果为
(248,)
我需要的是二维表示
np.stack(df_raw['picNew'] , axis=1).shape
(830435, 248)
现在一切都很好。
我仍然不确定最 "correct" 将图像大小调整为相同长度的方法。将 0 附加到数组长度似乎有点简单......所以如果有人有想法:)
我很难将一系列图像转换为正确的格式以输入 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()
然后在每个一维图片数组的末尾附加一些零。
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))
Training data and target sizes: (198,), (198,) Test data and target sizes: (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 return array(a, dtype, copy=False, order=order) 502 503
ValueError: setting an array element with a sequence.
我想这一定与数组大小有关,但我想不通。 :-/
除了错误之外,更一般地说,我对我的方法有一个疑问。特别是我认为我的 "padding" 可能不正确,也许调整大小会更好。 我感谢对我的方法的任何反馈。谢谢
我很确定这是因为在特征列中使用列表并将字符串作为目标值。对于后者,您需要使用 LabelEncoder
class 将它们转换为规范化的 class 标签,如 fit() 所要求的那样。
查看此处的说明: https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html
这需要在 train/test 拆分之前完成,以确保 LabelEncoder 拥有所有名称 'seen'。
对于前者,您可能需要搜索 MNIST 教程,它将提供大量应用于图像 class化问题的算法。
此外,在展平之前调整大小应该比填充效果更好。
我找到问题了。
感谢 Artem 发现了我没有编码 类 的明显问题,但这最终不是我的问题。
原来我的图片数组的表示方式不正确。
原始数组是 df_raw['picNew'].shape
计算结果为
(248,)
我需要的是二维表示
np.stack(df_raw['picNew'] , axis=1).shape
(830435, 248)
现在一切都很好。
我仍然不确定最 "correct" 将图像大小调整为相同长度的方法。将 0 附加到数组长度似乎有点简单......所以如果有人有想法:)