【问题标题】:Tensorflow and tflearn : value error setting an array element with a sequenceTensorflow和tflearn:使用序列设置数组元素的值错误
【发布时间】:2018-06-22 21:32:01
【问题描述】:

我正在尝试使用 tflearn 使用卷积神经网络对图像进行分类。输入图像的大小不同,我将它们全部调整为 32x32x3(我正在使用所有 RGB 通道)。这是我的代码。

import os
import numpy as np
from random import shuffle
from tqdm import tqdm
import tflearn
import cv2
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.estimator import regression
from tflearn.data_preprocessing import ImagePreprocessing
from tflearn.data_augmentation import ImageAugmentation
import tensorflow as tf
import matplotlib.pyplot as plt
import pickle

TRAIN_DIR = 'some_dir'

def label_img(img):
    word_label = img.split('.')[0]
    if 'metal' in word_label: 
        return np.array([1,0,0,0])
    elif 'plastic' in word_label: 
        return np.array([0,1,0,0])
    elif 'paper' in word_label: 
        return np.array([0,0,1,0])
    elif 'glass' in word_label: 
        return np.array([0,0,0,1])

def create_train_data():
    training_data = []
    for img in tqdm(os.listdir(TRAIN_DIR)):
        label = label_img(img)
        path = os.path.join(TRAIN_DIR,img)
        img = cv2.imread(path,1)
        img = cv2.resize(img, (32,32), interpolation = cv2.INTER_AREA)
        float_img = img.astype(float)
        float_img = float_img.reshape([-1,3,32,32])
        float_img = float_img.transpose([0,2,3,1])
        training_data.append([float_img, label])

    shuffle(training_data)
    with open('training_data.pickle','wb') as f:
        pickle.dump(training_data,f)

    return training_data

if os.path.exists('training_data.pickle'):
    pickle_in = open('training_data.pickle','rb')
    train_data = pickle.load(pickle_in)
else:
    train_data = create_train_data()


img_prep = ImagePreprocessing()
img_prep.add_featurewise_zero_center()
img_prep.add_featurewise_stdnorm()

img_aug = ImageAugmentation()
img_aug.add_random_flip_leftright()
img_aug.add_random_rotation(max_angle=15.)

network = input_data(shape=[None, 32, 32, 3], data_preprocessing=img_prep, data_augmentation=img_aug)
network = conv_2d(network, 32, 3, strides=1, padding='same', activation='relu', bias=True, bias_init='zeros', weights_init='uniform_scaling')
network = max_pool_2d(network, 2 , strides=None, padding='same')
network = conv_2d(network, 64, 3, strides=1, padding='same', activation='relu', bias=True, bias_init='zeros', weights_init='uniform_scaling')
network = conv_2d(network, 64, 3 , strides=1, padding='same', activation='relu', bias=True, bias_init='zeros', weights_init='uniform_scaling')
network = max_pool_2d(network, 2 , strides=None, padding='same')
network = fully_connected(network, 512, activation='relu')
network = dropout(network, 0.5)
network = fully_connected(network, 4, activation='softmax')
network = regression(network, optimizer='adam', loss='categorical_crossentropy', learning_rate=0.001)

train = train_data[:-200]
test = train_data[-200:]

X = np.array([i[0] for i in train]).reshape(-1, 32, 32, 3)
Y = np.array([i[1] for i in train])

test_x = np.array([i[0] for i in test]).reshape(-1, 32, 32, 3)
test_y = np.array([i[1] for i in test])

model = tflearn.DNN(network, tensorboard_dir='log')
model.fit(X, Y, n_epoch=50, shuffle=True, validation_set= (test_x, test_y) , show_metric=True, batch_size=100 , run_id='aa2')

我收到函数的最后一行代码的错误

model.fit(....)

错误提示“value error:setting an array element with a sequence”。 我检查了 tflearn 文档。它表示输入(在我的例子中,函数 model.fit 中的 X,Y 参数)和验证(test_x,test_y 函数中的参数都需要数组的数据类型。因此,我已将它们全部转换为 numpy 数组,但仍然出现此错误。 另外,我在另一台安装了 tensorflow 的 virtualenv 的机器上运行了这段代码。代码完美地在那台机器上运行。我已经搜索了很多论坛,但没有一个有答案。

还有一件事,我使用了 tflearn 的图像预处理和图像增强。他们不应该在技术上通过添加更多图像(旋转 15 度的图像)来增加数据集的大小吗?数据集的大小也没有增加。使用这些功能有什么错误吗?

提前致谢!

【问题讨论】:

  • X(和 Y)中的所有元素都应该具有相同的维度。您的预处理弄乱了尺寸一定有问题。
  • @sladomic 我的 X 形状为 (2327, 32, 32, 3),Y 形状为 (2327,)。 Y 应该只包含相应数据的一个热编码标签,那么您认为问题到底出在哪里? X 和 Y 的形状都是错误的吗?我有 2327 张图片用于训练,200 张用于测试。

标签: python arrays numpy tensorflow tflearn


【解决方案1】:

改变这一行:

float_img = float_img.reshape([-1,3,32,32])

float_img = float_img.reshape([3,32,32])

你也不需要在下面再次重塑:

X = np.array([i[0] for i in train]).reshape(-1, 32, 32, 3)

【讨论】:

  • 我也认为 cv2.imread() 返回最后一列中的频道。所以应该是 float_img.reshape([32,32,3])
  • 我尝试在代码中实现这些更改。当我删除 reshape 时,tensorflow 给我另一个错误说 ValueError: Cannot feed value of shape (100, 1, 32, 32, 3) for Tensor 'InputData/X:0',其形状为 '(?, 32, 32 , 3)'。但无论如何,即使我只更改 float_img 行,错误仍然存​​在。
  • 嗯,对我来说,这两种解决方案似乎都有效,但我更喜欢不重新整形的一种,因为调整大小后形状已经正确(32、32、3)。您是否检查过,您正在检索原始图像而不是旧的 pickle 文件?
  • 是的,我检查了旧的泡菜文件。代码似乎不适合我。它给了我同样的错误:(
  • 知道了,他们在处理数据时出了点问题!我查看了数据集并对其进行了整理。 :P 感谢您的帮助!
猜你喜欢
  • 2018-09-01
  • 1970-01-01
  • 2018-11-11
  • 1970-01-01
  • 2018-12-30
  • 2018-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多