I want to copy some of the VGG16 layer weights layer by layer to another small network with alike layers, but I get an error that says:
File "/home/d/Desktop/s/copyweights.py", line 78, in <module>
list(f["model_weights"].keys())
File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
File "/usr/local/lib/python3.5/dist-packages/h5py/_hl/group.py", line 262, in __getitem__
oid = h5o.open(self.id, self._e(name), lapl=self._lapl)
File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
File "h5py/h5o.pyx", line 190, in h5py.h5o.open
KeyError: "Unable to open object (object 'model_weights' doesn't exist)"
The file is definitely in the path, I downloaded the file again just to make sure it is not corrupted (and it doesn't cause an error when I use model.load_weights in general - I also have HDF5 installed
Here is the code:
from keras import applications
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential, Model
from keras.layers import Dropout, Flatten, Dense, GlobalAveragePooling2D
from keras import backend as k
from keras.callbacks import ModelCheckpoint, LearningRateScheduler, TensorBoard, EarlyStopping
from keras import layers
from keras import models
from keras import optimizers
from keras.layers import Dropout
from keras.regularizers import l2
from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
import matplotlib.pyplot as plt
from keras.preprocessing.image import ImageDataGenerator
import os
epochs = 50
callbacks = []
#schedule = None
decay = 0.0
earlyStopping = EarlyStopping(monitor='val_loss', patience=10, verbose=0, mode='min')
mcp_save = ModelCheckpoint('.mdl_wts.hdf5', save_best_only=True, monitor='val_loss', mode='min')
reduce_lr_loss = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1, epsilon=1e-5, mode='min')
base_model = models.Sequential()
base_model.add(layers.Conv2D(64, (3, 3), activation='relu', name='block1_conv1', input_shape=(256, 256, 3)))
base_model.add(layers.Conv2D(64, (3, 3), activation='relu', name='block1_conv2'))
base_model.add(layers.MaxPooling2D((2, 2)))
#model.add(Dropout(0.2))
base_model.add(layers.Conv2D(128, (3, 3), activation='relu', name='block2_conv1'))
base_model.add(layers.Conv2D(128, (3, 3), activation='relu', name='block2_conv2'))
base_model.add(layers.MaxPooling2D((2, 2), name='block2_pool'))
#model.add(Dropout(0.2))
base_model.summary()
"""
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 256, 256, 3) 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, 256, 256, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 256, 256, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 128, 128, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 128, 128, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 128, 128, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 64, 64, 128) 0
=================================================================
Total params: 260,160.0
Trainable params: 260,160.0
Non-trainable params: 0.0
"""
layer_dict = dict([(layer.name, layer) for layer in base_model.layers])
[layer.name for layer in base_model.layers]
"""
['input_1',
'block1_conv1',
'block1_conv2',
'block1_pool',
'block2_conv1',
'block2_conv2',
'block2_pool']
"""
import h5py
weights_path = '/home/d/Desktop/s/vgg16_weights_new.h5' # ('https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels.h5)
f = h5py.File(weights_path)
list(f["model_weights"].keys())
"""
['block1_conv1',
'block1_conv2',
'block1_pool',
'block2_conv1',
'block2_conv2',
'block2_pool',
'block3_conv1',
'block3_conv2',
'block3_conv3',
'block3_conv4',
'block3_pool',
'block4_conv1',
'block4_conv2',
'block4_conv3',
'block4_conv4',
'block4_pool',
'block5_conv1',
'block5_conv2',
'block5_conv3',
'block5_conv4',
'block5_pool',
'dense_1',
'dense_2',
'dense_3',
'dropout_1',
'global_average_pooling2d_1',
'input_1']
"""
# list all the layer names which are in the model.
layer_names = [layer.name for layer in base_model.layers]
"""
# Here we are extracting model_weights for each and every layer from the .h5 file
>>> f["model_weights"]["block1_conv1"].attrs["weight_names"]
array([b'block1_conv1/kernel:0', b'block1_conv1/bias:0'],
dtype='|S21')
# we are assiging this array to weight_names below
>>> f["model_weights"]["block1_conv1"]["block1_conv1/kernel:0]
<HDF5 dataset "kernel:0": shape (3, 3, 3, 64), type "<f4">
# The list comprehension (weights) stores these two weights and bias of both the layers
>>>layer_names.index("block1_conv1")
1
>>> model.layers[1].set_weights(weights)
# This will set the weights for that particular layer.
With a for loop we can set_weights for the entire network.
"""
for i in layer_dict.keys():
weight_names = f["model_weights"][i].attrs["weight_names"]
weights = [f["model_weights"][i][j] for j in weight_names]
index = layer_names.index(i)
base_model.layers[index].set_weights(weights)
base_model.add(layers.Flatten())
base_model.add(layers.Dropout(0.5)) #Dropout for regularization
base_model.add(layers.Dense(256, activation='relu'))
base_model.add(layers.Dense(1, activation='sigmoid')) #Sigmoid function at the end because we have just two classes
# compile the model with a SGD/momentum optimizer
# and a very slow learning rate.
base_model.compile(loss='binary_crossentropy',
optimizer=optimizers.Adam(lr=1e-4, decay=decay),
metrics=['accuracy'])
os.environ["CUDA_VISIBLE_DEVICES"]="0"
train_dir = '/home/d/Desktop/s/data/train'
eval_dir = '/home/d/Desktop/s/data/eval'
test_dir = '/home/d/Desktop/s/data/test'
# create a data generator
train_datagen = ImageDataGenerator(rescale=1./255, #Scale the image between 0 and 1
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,)
val_datagen = ImageDataGenerator(rescale=1./255) #We do not augment validation data. we only perform rescale
test_datagen = ImageDataGenerator(rescale=1./255) #We do not augment validation data. we only perform rescale
# load and iterate training dataset
train_generator = train_datagen.flow_from_directory(train_dir, target_size=(224,224),class_mode='binary', batch_size=16, shuffle='True', seed=42)
# load and iterate validation dataset
val_generator = val_datagen.flow_from_directory(eval_dir, target_size=(224,224),class_mode='binary', batch_size=16, shuffle='True', seed=42)
# load and iterate test dataset
test_generator = test_datagen.flow_from_directory(test_dir, target_size=(224,224), class_mode=None, batch_size=1, shuffle='False', seed=42)
#The training part
#We train for 64 epochs with about 100 steps per epoch
history = base_model.fit_generator(train_generator,
steps_per_epoch=train_generator.n // train_generator.batch_size,
epochs=epochs,
validation_data=val_generator,
validation_steps=val_generator.n // val_generator.batch_size,
callbacks=[earlyStopping, mcp_save, reduce_lr_loss])
#Save the model
#base_model.save_weights('/home/d/Desktop/s/base_model_weights.h5')
#base_model.save('/home/d/Desktop/s/base_model_keras.h5')
#lets plot the train and val curve
#get the details form the history object
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
#Train and validation accuracy
plt.plot(epochs, acc, 'b', label='Training accuracy')
plt.plot(epochs, val_acc, 'r', label='Validation accuracy')
plt.title('Training and Validation accurarcy')
plt.legend()
plt.figure()
#Train and validation loss
plt.plot(epochs, loss, 'b', label='Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title('Training and Validation loss')
plt.legend()
plt.show()
Take the VGG16 model directly:
from keras.applications import VGG16
vgg = VGG16(choose parameters)
for layer in vgg.layers:
layer_weights_list = layer.get_weights()
Related
I have a simple LSTM network in Keras:
def create_model(x):
lstm_model = Sequential()
lstm_model.add(LSTM(100, input_dim=x.shape[2], input_length=x.shape[1]))
lstm_model.add(Dense(1,activation='sigmoid'))
lstm_model.compile(loss='mean_squared_error', optimizer='adam')
return lstm_model
and I am trying to train it on the data that has the following shapes:
training data input: (100, 2784, 6), training data output: (100, 2784, 1)
validation data input: (50, 27, 6), validation data output: (50, 27, 1)
test data input: (50, 27, 6), test data output: (50, 27, 1)
model.fit(train_x, train_y, validation_data=(validation_x, validation_y), epochs=EPOCHS, batch_size=BATCH_SIZE, shuffle=False, callbacks=[...])
I keep on failing on dimensions either because a) validation data is not the same shape as the training data or b) because the y shapes are not right
What am I doing wrong?
P.S. Standalone code for convenience
import numpy as np
import keras
from keras.models import Sequential
from keras.layers import LSTM, Dense
x_train=np.arange(1670400)
x_train=x_train.reshape((100, 2784, 6))
y_train=np.arange(278400)
y_train=y_train.reshape((100, 2784, 1))
x_val=np.arange(8100)
x_val=x_val.reshape((50, 27, 6))
y_val=np.arange(1350)
y_val=y_val.reshape((50, 27, 1))
x_test=np.arange(8100)
x_test=x_test.reshape((50, 27, 6))
y_test=np.arange(1350)
y_test=y_test.reshape((50, 27, 1))
def create_model(x):
lstm_model = Sequential()
lstm_model.add(LSTM(100, input_dim=x.shape[2], input_length=x.shape[1]))
lstm_model.add(Dense(1,activation='sigmoid'))
lstm_model.compile(loss='mean_squared_error', optimizer='adam')
return lstm_model
model=create_model(x_train)
model.fit(x_train, y_train, validation_data=(x_val, y_val), epochs=10, batch_size=32, shuffle=False)
This modification worked:
changing to batch_input_shape and adding return_sequences=True to the LSTM layer
import numpy as np
import keras
from keras.models import Sequential
from keras.layers import LSTM, Dense
x_train=np.arange(1670400)
x_train=x_train.reshape((100, 2784, 6))
y_train=np.arange(278400)
y_train=y_train.reshape((100, 2784, 1))
x_val=np.arange(8100)
x_val=x_val.reshape((50, 27, 6))
y_val=np.arange(1350)
y_val=y_val.reshape((50, 27, 1))
x_test=np.arange(8100)
x_test=x_test.reshape((50, 27, 6))
y_test=np.arange(1350)
y_test=y_test.reshape((50, 27, 1))
def create_model():
lstm_model = Sequential()
lstm_model.add(LSTM(100, batch_input_shape=(None,None,6), return_sequences=True))
lstm_model.add(Dense(1, activation='sigmoid'))
lstm_model.compile(loss='mean_squared_error', optimizer='adam')
return lstm_model
model=create_model()
model.fit(x_train, y_train, validation_data=(x_val, y_val), epochs=10, batch_size=32, shuffle=False)
I am writing to build a model to predict handwritten characters using the dataset given here (https://www.kaggle.com/sachinpatel21/az-handwritten-alphabets-in-csv-format)
EDIT: ( after making the changes suggested in the comments )
Error I get now : ValueError: Error when checking input: expected conv2d_4_input to have shape (28, 28, 1) but got array with shape (249542, 784, 1)
Find below the code for the CNN :
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras import backend as K
from keras.utils import np_utils
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
seed = 785
np.random.seed(seed)
dataset = np.loadtxt('../input/A_Z Handwritten Data/A_Z Handwritten Data.csv', delimiter=',')
print(dataset.shape) # (372451, 785)
X = dataset[:,1:785]
Y = dataset[:,0]
(X_train, X_test, Y_train, Y_test) = train_test_split(X, Y, test_size=0.33, random_state=seed)
X_train = X_train / 255
X_test = X_test / 255
X_train = X_train.reshape((-1, X_train.shape[0], X_train.shape[1], 1))
X_test = X_test.reshape((-1, X_test.shape[0], X_test.shape[1], 1))
print(X_train.shape) # (1, 249542, 784, 1)
Y_train = np_utils.to_categorical(Y_train)
Y_test = np_utils.to_categorical(Y_test)
print(Y_test.shape) # (122909, 26)
num_classes = Y_test.shape[1] # 26
model = Sequential()
model.add(Conv2D(32, (5, 5), input_shape=(28, 28, 1), activation='relu', data_format="channels_last"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print("DONE")
model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=10, batch_size=256, verbose=2)
# Final evaluation of the model
scores = model.evaluate(X_test,Y_test, verbose=0)
print("CNN Error: %.2f%%" % (100-scores[1]*100))
model.save('weights.model')
So the problem is that your data isn't structured properly. Look at the solution below:
Read the data with pandas:
data = pd.read_csv('/users/vpolimenov/Downloads/A_Z Handwritten Data.csv')
data.shape
# shape: (372450, 785)
Get your X and y:
data.rename(columns={'0':'label'}, inplace=True)
X = data.drop('label',axis = 1)
y = data['label']
Split and scale:
X_train, X_test, y_train, y_test = train_test_split(X,y)
standard_scaler = MinMaxScaler()
standard_scaler.fit(X_train)
X_train = standard_scaler.transform(X_train)
X_test = standard_scaler.transform(X_test)
Here is the magic:
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32')
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
X_train.shape
# (279337, 28, 28, 1)
Here is your model:
num_classes = y_test.shape[1] # 26
model = Sequential()
model.add(Conv2D(32, (5, 5), input_shape=(28, 28, 1), activation='relu', data_format="channels_last"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print("DONE")
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=256, verbose=2) # WHERE I GET THE ERROR
Summary of your model:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_25 (Conv2D) (None, 24, 24, 32) 832
_________________________________________________________________
max_pooling2d_25 (MaxPooling (None, 12, 12, 32) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 12, 12, 32) 0
_________________________________________________________________
flatten_25 (Flatten) (None, 4608) 0
_________________________________________________________________
dense_42 (Dense) (None, 128) 589952
_________________________________________________________________
dense_43 (Dense) (None, 26) 3354
=================================================================
Total params: 594,138
Trainable params: 594,138
Non-trainable params: 0
I've stopped it after the second epoch, but you can see it working:
Train on 279337 samples, validate on 93113 samples
Epoch 1/10
- 80s - loss: 0.2478 - acc: 0.9308 - val_loss: 0.1021 - val_acc: 0.9720
Epoch 2/10
- 273s - loss: 0.0890 - acc: 0.9751 - val_loss: 0.0716 - val_acc: 0.9803
Epoch 3/10
Note:
It takes so long to fit due to the huge number of parameters in your network. You can try to reduce those and get a much faster/efficient network.
I am trying to use ResNet50 Pretrained network for segmentation problem.
I remove the last layer and add my desired layer. But when I try to fit, I get the following error:
ValueError: Error when checking target: expected conv2d_1 to have shape (16, 16, 1) but got array with shape (512, 512, 1)
I have two folders: images and masks. images are RGB and masks are in grayscale.
The shape is 512x512 for all images.
I can not figure in which part am I doing wrong.
Any help will be appreciated.
from keras.applications.resnet50 import ResNet50
image_input=Input(shape=(512, 512, 3))
model = ResNet50(input_tensor=image_input,weights='imagenet',include_top=False)
x = model.output
x = Conv2D(1, (1,1), padding="same", activation="sigmoid")(x)
model = Model(inputs=model.input, outputs=x)
model.summary()
conv2d_1 (Conv2D) (None, 16, 16, 1) 2049 activation_49[0][0]
for layer in model.layers[:-1]:
layer.trainable = False
for layer in model.layers[-1:]:
layer.trainable = True
model.compile(optimizer=Adam(), loss='binary_crossentropy', metrics=['accuracy'])
Your network gives an output of shape (16, 16, 1) but your y (target) has shape (512, 512, 1)
Run the following to see this.
from keras.applications.resnet50 import ResNet50
from keras.layers import Input
image_input=Input(shape=(512, 512, 3))
model = ResNet50(input_tensor=image_input,weights='imagenet',include_top=False)
model.summary()
# Output shows that the ResNet50 network has output of shape (16,16,2048)
from keras.layers import Conv2D
conv2d = Conv2D(1, (1,1), padding="same", activation="sigmoid")
conv2d.compute_output_shape((None, 16, 16, 2048))
# Output shows the shape your network's output will have.
Either your y or the way you use ResNet50 has to change. Read about ResNet50 to see what you are missing.
i am trying to use VGG16 pretrained in Keras, but i keep getting this error:
ValueError: Error when checking target: expected block5_pool to have 4 dimensions, but got array with shape (6, 1)
What is the error mean?
Error when checking target: expected block5_pool to have 4 dimensions,
but got array with shape (6, 1)
This the my actual code:
from keras import applications
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, ZeroPadding2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
# dimensions of our images.
img_width, img_height = 224, 224
train_data_dir = 'database/train'
validation_data_dir = 'database/validation'
nb_train_samples = 2000
nb_validation_samples = 26
epochs = 50
batch_size = 20
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
print('VGG-16 Model loaded.')
top_model = Sequential()
top_model.add(ZeroPadding2D((1,1),input_shape=input_shape))
top_model.add(Conv2D(64, (3, 3), activation='relu'))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(64, (3, 3), activation='relu'))
top_model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(128, (3, 3), activation='relu'))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(128, (3, 3), activation='relu'))
top_model.add(MaxPooling2D((2,2), strides=(2,2)))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(256, (3, 3), activation='relu'))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(256, (3, 3), activation='relu'))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(256, (3, 3), activation='relu'))
top_model.add(MaxPooling2D((2,2), strides=(2,2)))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(512, (3, 3), activation='relu'))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(512, (3, 3), activation='relu'))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(512, (3, 3), activation='relu'))
top_model.add(MaxPooling2D((2,2), strides=(2,2)))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(512, (3, 3), activation='relu'))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(512, (3, 3), activation='relu'))
top_model.add(ZeroPadding2D((1,1)))
top_model.add(Conv2D(512, (3, 3), activation='relu'))
top_model.add(MaxPooling2D((2,2), strides=(2,2)))
top_model.add(Flatten())
top_model.add(Dense(4096, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(12))
top_model.add(Activation('softmax'))
# note that it is necessary to start with a fully-trained
# classifier, including the top classifier,
# in order to successfully do fine-tuning
# top_model.load_weights('./vgg16_face_weights.h5')
# add the model on top of the convolutional base
model.add_update(top_model)
# set the first 25 layers (up to the last conv block)
# to non-trainable (weights will not be updated)
for layer in model.layers[:25]:
layer.trainable = False
model.compile(loss='sparse_categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size)
model.save_weights('first_try.h5')
The terminal run:
VGG-16 Model loaded.
Found 46 images belonging to 12 classes.
Found 26 images belonging to 12 classes.
Epoch 1/50
Traceback (most recent call last):
File "C:/Users/w024029h/PycharmProjects/keras_pretrained/pretrained.py", line 113, in <module>
validation_steps=nb_validation_samples // batch_size)
File "C:\Users\w024029h\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\legacy\interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "C:\Users\w024029h\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\engine\training.py", line 2230, in fit_generator
class_weight=class_weight)
File "C:\Users\w024029h\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\engine\training.py", line 1877, in train_on_batch
class_weight=class_weight)
File "C:\Users\w024029h\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\engine\training.py", line 1480, in _standardize_user_data
exception_prefix='target')
File "C:\Users\w024029h\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\engine\training.py", line 113, in _standardize_input_data
'with shape ' + str(data_shape))
ValueError: Error when checking target: expected block5_pool to have 4 dimensions, but got array with shape (6, 1)
I had this same error before. I resolved it by changing the class_mode on the data generators from 'binary' to None
According to the keras docs, setting the class_mode to 'binary' will return a 1-D array.
By changing the class_mode=None, no labels are returned and the generator will only yield batches of image data. This is what you are expecting with your model and this works well with the fit_generator() method. However, when using class_mode None, the data still needs to reside in a subdirectory of directory for it to work correctly.
This page was useful to me
^look at flow_from_directory()
Hope this helps!
I have not coded in years, forgive me. I am trying to do something that may be impossible. I have 38 videos of people performing the same basic movement. I want to train the model to identify those doing it correct v not correct.
I am using color now, because the grayscale did not work either and I wanted to test like the example I used. I used the model as defined in an example, link.
Keras,
Python3.5 in Anaconda 64,
Tensorflow backend,
on Windows 10 (64bit)
I was hoping to try different models on the problem and use grayscale to reduce memory, but cant get past first step!
Thanks!!!
Here is my code:
import time
import numpy as np
import sys
import os
import cv2
import keras
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten, BatchNormalization
from keras.layers import Conv3D, Conv2D, MaxPooling2D, GRU, ConvLSTM2D, TimeDistributed
y_cat = np.zeros(40,np.float)
good = "Good"
bad = "Bad"
batch_size = 32
num_classes = 1
epochs = 1
nvideos = 38
nframes = 130
nrows = 240
ncols = 320
nchan = 3
x_learn = np.zeros((nvideos,nframes,nrows,ncols,nchan),np.int32)
x_learn = np.load(".\\train\\datasetcolor.npy")
with open(".\\train\\tags.txt") as ft:
y_learn = ft.readlines()
y_learn = [x.strip() for x in y_learn]
ft.close()
# transform string tags to numeric.
for i in range (0,len(y_learn)):
if (y_learn[i] == good): y_cat[i] = 1
elif (y_learn[i] == bad): y_cat[i] = 0
#build model
# duplicating from https://github.com/fchollet/keras/blob/master/examples/conv_lstm.py
model = Sequential()
model.image_dim_ordering = 'tf'
model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
input_shape=(nframes,nrows,ncols,nchan),
padding='same', return_sequences=True))
model.add(BatchNormalization())
model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
padding='same', return_sequences=True))
model.add(BatchNormalization())
model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
padding='same', return_sequences=True))
model.add(BatchNormalization())
model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
padding='same', return_sequences=True))
model.add(BatchNormalization())
model.add(Conv3D(filters=1, kernel_size=(3, 3, 3),
activation='sigmoid',
padding='same', data_format='channels_last'))
model.compile(loss='binary_crossentropy', optimizer='adadelta')
print(model.summary())
# fit with first 3 videos because I don't have the horsepower yet
history = model.fit(x_learn[:3], y_learn[:3],
batch_size=batch_size,
epochs=epochs)
print (history)
Results:
Layer (type) Output Shape Param #
=================================================================
conv_lst_m2d_5 (ConvLSTM2D) (None, 130, 240, 320, 40) 62080
_________________________________________________________________
batch_normalization_5 (Batch (None, 130, 240, 320, 40) 160
_________________________________________________________________
conv_lst_m2d_6 (ConvLSTM2D) (None, 130, 240, 320, 40) 115360
_________________________________________________________________
batch_normalization_6 (Batch (None, 130, 240, 320, 40) 160
_________________________________________________________________
conv_lst_m2d_7 (ConvLSTM2D) (None, 130, 240, 320, 40) 115360
_________________________________________________________________
batch_normalization_7 (Batch (None, 130, 240, 320, 40) 160
_________________________________________________________________
conv_lst_m2d_8 (ConvLSTM2D) (None, 130, 240, 320, 40) 115360
_________________________________________________________________
batch_normalization_8 (Batch (None, 130, 240, 320, 40) 160
_________________________________________________________________
conv3d_1 (Conv3D) (None, 130, 240, 320, 1) 1081
=================================================================
Total params: 409,881.0
Trainable params: 409,561
Non-trainable params: 320.0
_________________________________________________________________
None
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-d909d285f474> in <module>()
82 history = model.fit(x_learn[:3], y_learn[:3],
83 batch_size=batch_size,
---> 84 epochs=epochs)
85
86 print (history)
ValueError: Error when checking model target: expected conv3d_1 to have 5 dimensions, but got array with shape (3, 1)
"Target" means that the problem is in the output of your model versus the format of y_learn.
The array y_learn should be exactly the same shape of the model's output, because the model outputs a "guess", while y_learn is the "correct answer". The system can only compare the guess with the correct answer if they have the same dimensions.
See the difference:
Model Output (seen in the summary): (None,130,240,320,1)
y_learn: (None,1)
Where "None" is the batch size. You gave y_learn[:3], then your batch size is 3 for this training session.
In order to correct it properly, we need to understand what y_learn is.
If I understood well, you've got only a number, 0 or 1, for each video. If that's so, your y_learn is totally ok, and what you need is for your model to output things like (None,1).
A very simple way to do that (perhaps not the best, and I couldn't be of more help here...) is to add a final Dense layer with just one neuron:
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
Now, when you do model.summary(), you will see the final output as (None,1)