【问题标题】:How to get training data for Keras Sequential CNN into the correct tensor shape?如何将 Keras Sequential CNN 的训练数据转换为正确的张量形状?
【发布时间】:2019-02-09 14:15:29
【问题描述】:

我有一个 4 维张量的图像像素数据(红色(高度,宽度),绿色(高度,宽度),蓝色(高度,宽度),14000 个示例)和一个包含边界框坐标的 CSV 文件每个图像都有 ie, (Image name, X1, Y1, X2, Y2),它有 14000 行,每个示例也有一个。

如何将这些数据输入我的神经网络?目前,如果我尝试输入张量,它会将 14000 个示例的整个数组传递给 (X1,Y1,X2,Y2) 的一行{它应该为 x1,y1,x2,y2 的一行传递一个数组}。

知道如何解决这个问题吗?

这是代码和相关的错误:

train_csv = pd.read_csv('datasets/training.csv').values
test_csv = pd.read_csv('datasets/test.csv').values

y_train = train_csv[:,[1,2,3,4]]   #done
x_train_names = train_csv[:,0]     #obtained names of images in array

#### load images into an array ####
X_train = []
path = "datasets/images/images/"
imagelist = listdir(path)
for i in range(len(x_train_names)):
img_name = x_train_names[i]
img = Image.open(path + str(img_name))
arr = array(img)
X_train.append(arr) 


#### building a very basic classifier, just to get some result ####
classifier = Sequential()
classifier.add(Convolution2D(64,(3,3),input_shape=(64,64,3), activation = 
'relu')) 
classifier.add(Dropout(0.2))
classifier.add(MaxPooling2D((4,4)))
classifier.add(Convolution2D(32,(2,2), activation = 'relu')) 
classifier.add(MaxPooling2D((2,2)))
classifier.add(Flatten())
classifier.add(Dense(16, activation = 'relu'))
classifier.add(Dropout(0.5))
classifier.add(Dense(4))
classifier.compile('adam','binary_crossentropy',['accuracy'])
classifier.fit(x=X_train,y=y_train, steps_per_epoch=80, batch_size=32, 
epochs=25)

错误:

ValueError:检查模型输入时出错:您传递给模型的 Numpy 数组列表不是模型预期的大小。预计会看到 1 个数组,但得到了以下 14000 个数组的列表:

[array([[[141, 154, 144],
         [141, 154, 144],
         [141, 154, 144],
         ...,
         [149, 159, 150],
         [150, 160, 151],
         [150, 160, 151]],

        [[140, 153, 143],
         […

编辑:我将所有图像都转换为灰度图像,因此不会出现内存错误。这意味着我的 X_train 应该沿通道数(早期,RGB)具有 1 个维度。这是我编辑的代码:

y_train = train_csv[:,[1,2,3,4]]   #done
x_train_names = train_csv[:,0]     #obtained names of images in array

# load images into an array
path = "datasets/images/images/"
imagelist = listdir(path)

img_name = x_train_names[0]

X_train = np.ndarray((14000,img.height,img.width,1))

for i in range(len(x_train_names)):
img_name = x_train_names[i]
img = Image.open(path + str(img_name)).convert('L') 
##converting image to grayscale because I get memory error else 
X_train[i,:,:,:] = np.asarray(img)

ValueError: 无法将输入数组从形状 (480,640) 广播到形状 (480,640,1)

(在X_train[i,:,:,:] = np.asarray(img) 线)

【问题讨论】:

    标签: python arrays machine-learning keras deep-learning


    【解决方案1】:

    第一步始终是找出您的第一个卷积层期望的输入形状。 tf.nn.conv2d 的文档指出 4D 输入张量的预期形状是 [batch, in_height, in_width, in_channels]

    要加载数据,我们可以使用 numpy ndarray。为此,我们应该知道您要加载的图像数量以及图像的尺寸:

    path = "datasets/images/images/"
    imagelist = listdir(path)
    
    img_name = x_train_names[0]
    img = Image.open(path + str(img_name))
    
    X_train = np.ndarray((len(imagelist),img.height,img.width,3))
    
    for i in range(len(x_train_names)):
     img_name = x_train_names[i]
     img = Image.open(path + str(img_name))
     X_train[i,:,:,:] = np.asarray(img)
    

    你的 X_train 张量的 shape 属性应该给你:

    print(X_train.shape)
    > (len(x_train_names), img.height, img.width, 3)
    

    编辑:

    要分批加载图像,您可以执行以下操作:

    #### Build and compile your classifier up here here ####
    
    num_batches = 5
    len_batch = np.floor(len(x_train_names)/num_batches).astype(int) 
    
    X_train = np.ndarray((len_batch,img.height,img.width,3))
    
    for batch_idx in range(num_batches):
        idx_start = batch_idx*len_batch
        idx_end = (batch_idx+1)*len_batch-1
        x_train_names_batch = x_train_names[idx_start:idx_end]
    
        for i in range(len(x_train_names_batch)):
            img_name = x_train_names_batch[i]
            img = Image.open(path + str(img_name))
            X_train[i,:,:,:] = np.asarray(img)
    
        classifier.fit(x=X_train,y=y_train, steps_per_epoch=num_batches, batch_size=len(x_train_names_batch), epochs=2)
    

    【讨论】:

    • 数据集中有大约 50,000 张图像,使用此代码会在 X_train = np.ndarray((len(imagelist),img.height,img.width,3)) 处给我一个 MemoryError。我有 16gb 的 RAM 和 64 位 Python,所以我不确定我为什么会得到这个……有什么想法吗?
    • 您是在训练集生成期间还是在训练期间内存不足?我估计 50000 个 64x64x3 图像的总文件大小约为 5 GB,对吧?然而,在前向传递期间,所需的内存显着增加。尝试减少批量大小或特征图的数量。如果这还不够,您应该在给定时间仅将部分图像加载到训练集中。 Keras 还提供了一个更复杂的dataloader,它正是为这种情况而设计的。
    • 还有一件事:将 X_train 张量明确地转换为 uint8 类型,如下所示:X_train = np.ndarray((len(imagelist),img.height,img.width,3), dtype=np.uint8)
    • 我正在考虑为此将图像转换为灰度格式,Florian。执行该代码本身时出现该错误,我什至没有到达训练/测试部分。我认为创建数组本身时存在内存问题。无论如何,我编辑了我的代码以使用灰度,你能帮帮我吗?请查看我编辑的答案。
    • 你好坂月。对于您的灰度方法,您必须像这样重塑您的图像:X_train[i,:,:,:] = np.asarray(img).reshape((img.height, img.width, 1))。如果这行得通,那很好。但是,在灰度上操作时,您可能会失去分类性能,因为您正在“丢弃”颜色信息。相反,您可以只加载多个较小批次的彩色图像。我会更新我的主要答案,给你一个例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    相关资源
    最近更新 更多