首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ValueError:无法将输入数组从形状(300,300,3)广播到形状(300,300)

ValueError:无法将输入数组从形状(300,300,3)广播到形状(300,300)
EN

Stack Overflow用户
提问于 2019-11-28 03:20:21
回答 2查看 878关注 0票数 2

我有一个简单的Python代码(用于培训的Keras教程)。我试图在加载图像时删除img = img.convert('L')以保留颜色(我所有的图像都是RGB色的,所以数据不是问题),但我遇到了这个错误:

代码语言:javascript
复制
training_images = np.array([i[0] for i in training_data]).reshape(-1, IMAGE_SIZE, IMAGE_SIZE, 3)
ValueError: could not broadcast input array from shape (300,300,3) into shape (300,300)

出什么问题了?如何修复它?

代码语言:javascript
复制
from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from PIL import Image
from random import shuffle, choice
import numpy as np
import os

IMAGE_SIZE = 300
IMAGE_DIRECTORY = './data/test_set'

def label_img(name):
  if name == 'cats': return np.array([1, 0])
  elif name == 'notcats' : return np.array([0, 1])

def load_data():
  train_data = []
  directories = next(os.walk(IMAGE_DIRECTORY))[1]

  for dirname in directories:
    file_names = next(os.walk(os.path.join(IMAGE_DIRECTORY, dirname)))[2]

    for i in range(200):
      image_name = choice(file_names)
      image_path = os.path.join(IMAGE_DIRECTORY, dirname, image_name)
      label = label_img(dirname)
      img = Image.open(image_path)
      #img = img.convert('L')
      img = img.resize((IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)
      train_data.append([np.array(img), label])

  return train_data

def create_model():
  model = Sequential()
  model.add(Conv2D(32, kernel_size = (3, 3), activation='relu', 
                   input_shape=(IMAGE_SIZE, IMAGE_SIZE, 1)))
  model.add(MaxPooling2D(pool_size=(2,2)))
  model.add(BatchNormalization())
  model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
  model.add(MaxPooling2D(pool_size=(2,2)))
  model.add(BatchNormalization())
  model.add(Dropout(0.2))
  model.add(Flatten())
  model.add(Dense(256, activation='relu'))
  model.add(Dropout(0.2))
  model.add(Dense(64, activation='relu'))
  model.add(Dense(2, activation = 'softmax'))

  return model

training_data = load_data()
training_images = np.array([i[0] for i in training_data]).reshape(-1, IMAGE_SIZE, IMAGE_SIZE, 1)
training_labels = np.array([i[1] for i in training_data])

model = create_model()
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(training_images, training_labels, batch_size=50, epochs=10, verbose=1)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-28 06:21:34

因为我能够在一些discussion in the comments之后识别出问题,所以我将把它作为答案发布。

在一线上

代码语言:javascript
复制
training_images = np.array([i[0] for i in training_data]).reshape(-1, IMAGE_SIZE, IMAGE_SIZE, 1)

您正在尝试将3通道RGB图像重塑为单通道(灰度)图像,这是不可能的(也不是您想做的事情,因为您想保留颜色),因此使用ValueError。只有在删除img = img.convert('L')之前才需要此部分,以便为模型提供合适的训练数据形状,该模型的输入形状为(IMAGE_SIZE, IMAGE_SIZE, 1)

现在您正在处理RGB图像,可以删除reshape,因为图像已经具有由load_data()返回的正确形状(IMAGE_SIZE, IMAGE_SIZE, 3)。但是,正如nneonneo's answer中所述,需要修改模型才能处理新的输入形状。

票数 2
EN

Stack Overflow用户

发布于 2019-11-28 04:40:48

代码语言:javascript
复制
  model.add(Conv2D(32, kernel_size = (3, 3), activation='relu', 
                   input_shape=(IMAGE_SIZE, IMAGE_SIZE, 1)))

你的模型想要灰度图像(1通道),但你试图训练彩色图像(3通道)。这行不通的。你将不得不修改你的模型来拍摄彩色图像,或者传递灰度图像。您开始使用的示例代码使用.reshape(-1, IMAGE_SIZE, IMAGE_SIZE, 1),以便将灰度图像转换为此神经网络第一层所需的形状。

如果模型是为灰度设计的,您只需保留.convert('L'),它会将彩色图像转换为灰度。许多图像分类任务在灰度模式下工作得很好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59077156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档