keras и tensorflow на python — Ошибка значения: («Входные данные в «NumpyArrayIterator» должны иметь ранг 4. Вы передали массив с формой’, (36848,))

#python #tensorflow #keras

Вопрос:

Я также искал множество подобных вопросов, но не мог найти правильного ответа. Найдите кого-нибудь, кто может быстро дать нам ответ! пожалуйста!

Это мой полный код, и я хочу создать модель машинного обучения, подобную Mnist в корейском слове

Ошибка значения: (‘Входные данные NumpyArrayIterator должны иметь ранг 4. Вы передали массив с формой’, (36848,))

если вам нужна дополнительная информация, прокомментируйте, пожалуйста

 import keras
import keras.utils as utils

from keras import backend as K
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D
from keras.layers.convolutional import MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import EarlyStopping
from sklearn.preprocessing import LabelEncoder,OneHotEncoder

batch_size = 128
epochs = 300
num_classes = 980

y_train = utils.to_categorical(y_train, num_classes)
y_val = utils.to_categorical(y_val, num_classes)

cb_early_stopping = EarlyStopping(monitor='val_loss', patience=50)

train_generator = ImageDataGenerator(rescale=1./255, 
                                     rotation_range=15, 
                                     width_shift_range=0.15, 
                                     height_shift_range=0.15, 
                                     shear_range=0.2, 
                                     zoom_range=[0.8, 1.2])

val_generator = ImageDataGenerator(rescale=1./255)

train_data_flow = train_generator.flow(X_train, y_train, 
                                       batch_size=batch_size,
                                       shuffle=(True),sample_weight=(None),
                                       seed=(None),save_to_dir=None)
val_data_flow = val_generator.flow(X_val, y_val,
                                   batch_size=batch_size)

img_rows, img_cols = 32, 32
input_shape = (img_rows, img_cols, 3)

model = Sequential()
model.add(Convolution2D(32, (3, 3), padding='same',
                 input_shape=X_train.shape[1:]))
model.add(Activation('relu'))
model.add(Convolution2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Convolution2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Dropout(0.50))

model.add(Convolution2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))

RMSprop = keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=None, decay=0.0)
                     
model.compile(loss='categorical_crossentropy',
              optimizer=RMSprop,
              metrics=['accuracy'])

hist = model.fit_generator(train_data_flow,
                           epochs=epochs,
                           verbose=1,
                           steps_per_epoch = 230,
                           validation_data=val_data_flow,
                           validation_steps = 70,
                           callbacks=[cb_early_stopping])

                           
## 2-2. Keras 모델 저장
## 2-2. Save Keras model

model.save('korean_classification.hdf5')

## 2-3. 훈련과정 그래프로 확인하기
## 2-3. View training curriculum graphs

acc = hist.history['acc']
val_acc = hist.history['val_acc']
loss = hist.history['loss']
val_loss = hist.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()
 

и если вам нужен более подробный код

 import pandas as pd
import io 

csv_file_path = "label_image_map.csv"
lable_file = "label.txt"

csv_file = io.open(csv_file_path, 'r', encoding='utf-8')
labels_file = io.open(lable_file, 'r', encoding='utf-8').read().splitlines()

# Map characters to indices.
label_dict = {}
count = 0
for label in labels_file:
    label_dict[label] = count
    count  = 1

# Build the lists.
filenames = []
labels = []

for row in csv_file:
    path, label = row.strip().split(',')
    filenames.append(path)
    labels.append(label_dict[label])

print("csv file load finished")

## 1-2. 두 개 리스트 랜덤으로 섞기
## 1-2. Shuffle two lists randomly

from subprocess import check_output
import random

seed = 1998

shuffled_indices = list(range(len(filenames)))
random.seed(seed)
random.shuffle(shuffled_indices)
filenames = [filenames[i] for i in shuffled_indices]
labels = [labels[i] for i in shuffled_indices]

print("List shuffle finished")

## 1-3. 이미지 경로의 이미지와 해당 label 시각화 
## 1-3. Visualize the image of the image path and its label

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

for i in range(0, 5):
    print(labels[i])
    
    img = mpimg.imread(filenames[i])
    plt.figure(figsize=(2, 2))
    plt.imshow(img, cmap ='gray')

## 1-4. 이미지 경로에 있는 총 46,060개의 이미지 데이터 새로운 리스트에 담기
## 1-4. A total of 46,060 image data in the image path Add to a new list

import cv2

X_data = []

total_count = 0
prev_count = 0

# image_paths = "C/Users/jheem/Documents/VisualStudioCode/Python/images/"

for i in range(1,46061,1) :
    image_paths = ("C/Users/jheem/Documents/VisualStudioCode/Python/images/image_%d.jpeg" % (i))
    # for image_path in image_paths:
    image = cv2.imread(image_paths)
    X_data.append(image)
    total_count  = 1
        
    if total_count - prev_count > 5000:
        prev_count = total_count
        print('{} images added...'.format(total_count))
print(total_count,prev_count)
print("Image adding finished")


## 1-5. 46,060개의 데이터 훈련셋/검증셋으로 나누기(비율 : r)
## 1-5. Divide by 46,060 data training set/verification sets(ratios: r)

import numpy as np
from sklearn.model_selection import train_test_split

r = 0.20
X = np.array(X_data)
y = np.array(labels)

print(X.shape,y.shape)

y.reshape(-1, 1)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = r)

print("X_data:", X.shape)
print("y_labels:", y.shape)
print("nX_train:", X_train.shape)
print("X_val:", X_val.shape)
print("y_train:", y_train.shape)
print("y_val:", y_val.shape)
 

Комментарии:

1. Что это такое X_train.shape ?

2. X_train: (36848,)

3. Ваш ввод имеет неправильную форму. Вы читаете изображения, и он ожидает измерение 4 ранга, которое есть (samples, height, width, channels) . Но вы прошли 1D вектор.

4. Вы должны сделать массив 4D внутри X_train . Проверьте X_data X и X_train формы , чтобы выяснить, какая из них имеет неправильную форму.

5. Спасибо вам за ваш совет. Но это все еще сложно, поэтому я думаю, что мне следует больше изучить структуру массива 4D.

Ответ №1:

Как прокомментировал @Kaveh, форма ввода изображения должна быть 4D.

Свертка2d ожидает ввода формы (n_samples, height, width, channels) .

  1. n_samples-это количество образцов
  2. высота и ширина-это значение пикселя изображения
  3. Каналы указывают изображение в RGB или сером масштабе, где значение 3 для цветного изображения RGB и для изображения в сером масштабе будет равно 1.