Ich erstelle ein CNN für Nicht-Bilddaten in Keras 2.1.0 unter Windows 10.

Meine Eingabefunktion ist eine 3x12-Matrix mit nicht negativen Zahlen und meine Ausgabe ist ein binärer Multi-Label-Vektor mit einer Länge von 6x1

Und ich bin auf diesen Fehler gestoßen, erwartete, dass conv2d_14_input Form (3, 12, 1) hat, aber Array mit Form (3, 12, 6500)

Hier ist mein Code unten

import tensorflow as tf
from scipy.io import loadmat
import numpy as np
from tensorflow.keras.layers import BatchNormalization
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout
from tensorflow.keras.layers import Conv2D, MaxPool2D, Flatten


reshape_channel_train = loadmat('reshape_channel_train')
reshape_channel_test = loadmat('reshape_channel_test.mat')
reshape_label_train = loadmat('reshape_label_train')
reshape_label_test = loadmat('reshape_label_test')

X_train = reshape_channel_train['store_train']
X_test = reshape_channel_test['store_test']

X_train = np.expand_dims(X_train,axis = 0)
X_test  = np.expand_dims(X_test, axis = 0)

Y_train = reshape_label_train['label_train']
Y_test = reshape_label_test['label_test']

classifier = Sequential()
classifier.add(Conv2D(8, kernel_size=(3,3) , input_shape=(3, 12, 1), padding="same"))
classifier.add(BatchNormalization())
classifier.add(Activation('relu'))

classifier.add(Conv2D(8, kernel_size=(3,3), input_shape=(3, 12, 1), padding="same"))
classifier.add(BatchNormalization())
classifier.add(Activation('relu'))

classifier.add(Flatten())
classifier.add(Dense(8, activation='relu'))
classifier.add(Dense(6, activation='sigmoid'))
classifier.compile(optimizer='nadam', loss='binary_crossentropy', metrics=['accuracy'])

history = classifier.fit(X_train, Y_train, batch_size = 32, epochs=100,
                         validation_data=(X_test, Y_test), verbose=2)

Nach einigem Suchen habe ich den Trick zum Erweitern von Dimensionen verwendet, aber es scheint nicht zu funktionieren

X_train = np.expand_dims(X_train,axis = 0)
X_test  = np.expand_dims(X_test, axis = 0)

Die Variable X_train mit 6500 Trainingsinstanzen wird aus einer Matlab .mat-Datei mit der Dimension 3x12x6500 geladen.

Wobei jede Trainingsinstanz eine 3x12-Matrix ist.

Bevor die Tricks expand_dim verwendet werden, kann das k-te Trainingsbeispiel von X_train [:,:, k] und X_train [:,:, k] .shape aufgerufen werden Rückkehr (3,12). Auch X_train.shape würde zurückkehren (3, 12, 6500)

Nach Verwendung der Tricks expand_dim würde der Befehl X_train [:,:, k] .shape (1, 3, 6500) zurückgeben

Bitte helfen Sie mir dabei! Danke

1
Tuong Nguyen Minh 1 Sept. 2020 im 15:35

2 Antworten

Beste Antwort

Sie verwalten Ihre Daten falsch. Eine Conv2D Ebene akzeptiert Daten in diesem Format (n_sample, height, width, channels), die in Ihrem Fall (für Ihren X_train) zu (6500,3,12,1) wurden. Sie müssen einfach auf diesen Fall zurückgreifen

# create data as in your matlab data
n_class = 6
n_sample = 6500
X_train = np.random.uniform(0,1, (3,12,n_sample)) # (3,12,n_sample)
Y_train = tf.keras.utils.to_categorical(np.random.randint(0,n_class, n_sample)) # (n_sample, n_classes)

# reshape your data for conv2d
X_train = X_train.transpose(2,0,1) # (n_sample,3,12)
X_train = np.expand_dims(X_train, -1) # (n_sample,3,12,1)

classifier = Sequential()
classifier.add(Conv2D(8, kernel_size=(3,3) , input_shape=(3, 12, 1), padding="same"))
classifier.add(BatchNormalization())
classifier.add(Activation('relu'))

classifier.add(Conv2D(8, kernel_size=(3,3), padding="same"))
classifier.add(BatchNormalization())
classifier.add(Activation('relu'))

classifier.add(Flatten())
classifier.add(Dense(8, activation='relu'))
classifier.add(Dense(n_class, activation='softmax'))
classifier.compile(optimizer='nadam', loss='categorical_crossentropy', metrics=['accuracy'])

history = classifier.fit(X_train, Y_train, batch_size = 32, epochs=2, verbose=2)

# get predictions
pred = np.argmax(classifier.predict(X_train), 1)

Ich verwende auch eine softmax Aktivierung mit categorical_crossentropy, die besser für Probleme mit mehreren Klassen geeignet ist, aber Sie können dies auch ändern. Denken Sie daran, die gleiche Datenmanipulation auch auf Ihre Testdaten anzuwenden

1
Marco Cerliani 1 Sept. 2020 im 13:19

Sie müssen das Argument data_format = "channel_last" übergeben, da Ihre Kanäle endlich sind

Sie versuchen dies:

x_train=x_train.reshape((6500,3,12,1))
x_test=x_test.reshape((-1,3,12,1))


and in each of conv2d layer conv2D(<other args>, data_format="channels_last")
1
Sayan Dey 1 Sept. 2020 im 13:05