I am a newbie in CNN and I am trying the code the Deconvolution (to generate feature maps) in MNIST database (because it's the simplest one to learn for a beginner). I want my model to generate feature maps at the end.The idea is to implement the paper Saliency Detection Via Dense Convolution Network to some extent.
Here is the complete code that I am trying to run:
import keras
from keras.datasets import mnist
import keras.backend as K
from keras.models import Model, Sequential
from keras.layers import Input, Dense, Flatten, Dropout, Activation, Reshape
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.pooling import MaxPooling2D, GlobalAveragePooling2D
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D, Conv2DTranspose, UpSampling2D
from keras.initializers import RandomNormal
init = RandomNormal(mean = 0., stddev = 0.02)
def GeneratorDeconv(image_size = 28):
L = int(image_size)
inputs = Input(shape = (100, ))
x = Dense(512*int(L/16)**2)(inputs) #shape(512*(L/16)**2,)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Reshape((int(L/16), int(L/16), 512))(x) # shape(L/16, L/16, 512)
x = Conv2DTranspose(256, (4, 4), strides = (2, 2),
kernel_initializer = init,
padding = 'same')(x) # shape(L/8, L/8, 256)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2DTranspose(128, (4, 4), strides = (2, 2),
kernel_initializer = init,
padding = 'same')(x) # shape(L/4, L/4, 128)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2DTranspose(64, (4, 4), strides = (2, 2),
kernel_initializer = init,
padding = 'same')(x) # shape(L/2, L/2, 64)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2DTranspose(3, (4, 4), strides= (2, 2),
kernel_initializer = init,
padding = 'same')(x) # shape(L, L, 3)
images = Activation('tanh')(x)
model = Model(inputs = inputs, outputs = images)
model.summary()
return model
batch_size = 128
num_classes = 10
epochs = 1
# input image dimensions
img_rows, img_cols = 28, 28
# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()
if K.image_data_format() == 'channels_first':
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
model = GeneratorDeconv()
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
The function def GeneratorDeconv(image_size = 28): I picked from ProgramCreek Python
Now, I am confused that how can I embed it into my own custom model. Up to model.compile(...) the program runs okay. But at model.fit(...) , it gives error:
ValueError: Error when checking input: expected input_2 to have 2
dimensions, but got array with shape (60000, 28, 28, 1)
I don't know how to resolve the issues. Please help.
The input to your model is:
inputs = Input(shape = (100, ))
This will take a vector in the shape of (samples, 100), so it expects a 2D input.
However:
print('x_train shape:', x_train.shape)
>>>x_train shape: (60000, 28, 28, 1)
You are inputting a 4D array, when you specified that your input took a 2D one. That is what is causing the error.
I made some edits to your architecture so the shapes match up and it actually trains:
def GeneratorDeconv(image_size = 28):
L = int(image_size)
inputs = Input(shape = (28, 28,1))
x = Dense(512*int(L/16)**2)(inputs)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2DTranspose(256, (4, 4), strides = (2, 2),
kernel_initializer = init,
padding = 'same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2DTranspose(128, (4, 4), strides = (2, 2),
kernel_initializer = init,
padding = 'same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2DTranspose(64, (4, 4), strides = (2, 2),
kernel_initializer = init,
padding = 'same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2DTranspose(3, (4, 4), strides= (2, 2),
kernel_initializer = init,
padding = 'same')(x)
x = Flatten()(x)
x = Dense(10)(x)
images = Activation('tanh')(x)
model = Model(inputs = inputs, outputs = images)
model.summary()
return model
Related
I am getting error trying to feed in the following data into my network. I have issue with reshaping the training data and the input to the network. The error I am getting is:
Error when checking target: expected conv1d_92 to have shape (4, 1) but got array with shape (1, 784)
The code is as follows:
# -*- coding: utf-8 -*-
"""
Created on Wed Mar 17 20:57:51 2021
#author: morte
"""
import keras
from keras import layers
from keras.datasets import mnist
import numpy as np
#(x_train, _), (x_test, _) = mnist.load_data()
#x_train = x_train.astype('float32') / 255.
#x_test = x_test.astype('float32') / 255.
#x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
#x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
(x_train, _), (x_test, _) = mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = np.reshape(x_train, (len(x_train),1,28*28)) #
x_test = np.reshape(x_test, (len(x_test),1,28*28)) #
input_img = keras.Input(shape=(x_train.shape[1:]))
x = layers.Conv1D(16,(3), activation='relu', padding='same')(input_img)
x = layers.MaxPooling1D(2, padding='same')(x)
x = layers.Conv1D(8,(3), activation='relu', padding='same')(x)
x = layers.MaxPooling1D(2, padding='same')(x)
x = layers.Conv1D(8,(3), activation='relu', padding='same')(x)
encoded = layers.MaxPooling1D(2, padding='same')(x)
# at this point the representation is (4, 4, 8) i.e. 128-dimensional
x = layers.Conv1D(8,(3), activation='relu', padding='same')(encoded)
x = layers.UpSampling1D(2)(x)
x = layers.Conv1D(8,(3), activation='relu', padding='same')(x)
x = layers.UpSampling1D(2)(x)
x = layers.Conv1D(16,(3), activation='relu')(x)
x = layers.UpSampling1D(2)(x)
decoded = layers.Conv1D(1, (3), activation='sigmoid', padding='same')(x)
autoencoder = keras.Model(input_img, decoded)
autoencoder.compile(optimizer='adam', loss='binary_crossentropy')
from keras.datasets import mnist
import numpy as np
from keras.callbacks import TensorBoard
autoencoder.fit(x_train, x_train,
epochs=2,
batch_size=128,
shuffle=True,
validation_data=(x_test, x_test),
)
decoded_imgs = autoencoder.predict(x_test)
import matplotlib.pyplot as plt
n = 10
plt.figure(figsize=(20, 4))
for i in range(1, n + 1):
# Display original
ax = plt.subplot(2, n, i)
plt.imshow(x_test[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# Display reconstruction
ax = plt.subplot(2, n, i + n)
plt.imshow(decoded_imgs[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
Since it is an Autoencoder Network, Encoder-Input has to match Decoder-Output.
You are giving a (1,785) shaped Input-array and outputting an (4,1) array.
For more details you can add the line: autoencoder.summary() (for example after the line autoencoder = keras.Model(input_img, decoded))
This will give you information about the shapes of every layer.
An approach would be for example add a Dense Layer at the end of your Decoder.
I'm training a functional keras model on mnist dataset. There's a layer that requires 2 inputs - the traditional input tensor and a current batch of on-hot encoded labels. I think I've set up my model to accept 2 inputs, but I get:
ValueError: Error when checking model : the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 2 array(s), but instead got the following list of 1 arrays. [array([[[[0.], ...
Most answers suggested converting inputs to numpy arrays, but mnist images and labels are numpy arrays by default.
batch_size = 128
num_classes = 10
epochs = 1
# Mnist part
img_rows, img_cols = 28, 28
(x_train, y_train), (x_test, y_test) = mnist.load_data()
if K.image_data_format() == 'channels_first':
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
# Model part
images = Input(shape=input_shape, name='images_input')
labels = Input(shape=(num_classes,), name='labels_input')
x = Conv2D(32, kernel_size=(3, 3), activation='relu')(images)
x = Conv2D(64, (3, 3), activation='relu')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Dropout(0.25)(x)
x = Flatten()(x)
x = Dense(128, activation='relu', name='features')(x)
x = Dropout(0.5)(x)
x = SomeLayerWith2Inputs()([x, labels])
output = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=[images, labels], outputs=output)
model.compile(
loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy']
)
# x_train = <type 'numpy.ndarray'> (60000, 28, 28, 1)
# y_train = <type 'numpy.ndarray'> (60000, 10)
# x_test = <type 'numpy.ndarray'> (10000, 28, 28, 1)
# y_test = <type 'numpy.ndarray'> (10000, 10)
model.fit(
[x_train, y_train],
y_train,
batch_size=batch_size,
callbacks=[tensorboard],
epochs=epochs,
verbose=1,
validation_data=([x_test, y_test], y_test)
)
I've also tried to do model.fit(x={'images_input': x_train, 'labels_input': y_train}, y=y_train), but that also didn't work.
I'm using Keras v2.2.4
Found the problem. There was also a tensorboard callback (not shown in original question):
tensorboard = TensorBoard(
batch_size=128,
embeddings_freq=1,
embeddings_layer_names=['features'],
embeddings_metadata='metadata.tsv',
embeddings_data=x_test
)
The embeddings_data argument should be [x_test, y_test].
I am using Keras autoencodes with Theano backend. And want to make autoencode for 720x1080 RGB images.
This is my code
from keras.datasets import mnist
import numpy as np
from keras.layers import Input, LSTM, RepeatVector, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model
from PIL import Image
x_train = []
x_train_noisy = []
for i in range(5,1000):
image = Image.open('data/trailerframes/frame' + str(i) + '.jpg', 'r')
x_train.append(np.array(image))
image = Image.open('data/trailerframes_avg/frame' + str(i) + '.jpg', 'r')
x_train_noisy.append(np.array(image))
x_train = np.array(x_train)
x_train = x_train.astype('float32') / 255.
x_train_noisy = np.array(x_train_noisy)
x_train_noisy = x_train_noisy.astype('float32') / 255.
input_img = Input(shape=(720, 1080, 3))
x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(32, (3, 3), data_format="channels_last", activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(32, (3, 3), data_format="channels_last", activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), data_format="channels_last", activation='sigmoid', padding='same')(x)
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
autoencoder.fit(x_train_noisy, x_train,
epochs=10,
batch_size=128,
shuffle=True,
validation_data=(x_train_noisy, x_train))
But it gives me an error
ValueError: Error when checking input: expected input_7 to have shape (None, 720, 1080, 3) but got array with shape (995, 720, 1280, 3)
Input error:
As simple as:
You defined your input as (720,1080,3)
You're trying to trian your model with data in the form (720,1280,3)
One of them is wrong, and I think it's a typo in the input:
#change 1080 for 1280
input_img = Input(shape=(720, 1280, 3))
Output error (target):
Now, your target data is shaped like (720,1280,3), and your last layer outputs (720,1280,1)
A simple fix is:
decoded = Conv2D(3, (3, 3), data_format="channels_last", activation='sigmoid', padding='same')(x)
Using the encoder:
After training that model, you can create submodels for using only the encoder or the decoder:
encoderModel = Model(input_img, decoded)
decoderInput = Input((shape of the encoder output))
decoderModel = Model(decoderInput,decoded))
These two models will share the exact same weights of the entire model, training one model will affect all three models.
For using them without training, you can use model.predict(data), which will give you the results without training.
I'm working on image denoising using autoencoders (working with keras tensorflow backend).
when i train my model the loss rate is pretty high and stable(somewhere around 2.x).
i can't understand what i'm doing wrong.
here's my code:
from keras.layers import Input, Dense, Convolution2D, MaxPooling2D,UpSampling2D
from keras.models import Model
from keras.datasets import mnist
from keras.callbacks import TensorBoard
import matplotlib.pyplot as plt
import numpy as np
(x_train, _), (x_test, _) = mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = np.reshape(x_train, (len(x_train), 28, 28, 1))
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))
# adding noise to images
noise_factor = 0.5
x_train_noisy = x_train + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_train.shape)
x_test_noisy = x_test + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_test.shape)
x_train_noisy = np.clip(x_train_noisy, 0., 1.)
x_test_noisy = np.clip(x_test_noisy, 0., 1.)
input_img = Input(shape=(28, 28, 1))
x = Convolution2D(32, 3, 3, activation='relu', border_mode='same')(input_img)
x = MaxPooling2D((2, 2), border_mode='same')(x)
x = Convolution2D(32, 3, 3, activation='relu', border_mode='same')(x)
encoded = MaxPooling2D((2, 2), border_mode='same')(x)
# at this point the representation is (32, 7, 7)
x = Convolution2D(32, 3, 3, activation='relu', border_mode='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Convolution2D(32, 3, 3, activation='relu', border_mode='same')(x)
x = UpSampling2D((2, 2))(x)
decoded = Convolution2D(1, 3, 3, activation='sigmoid', border_mode='same')(x)
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
autoencoder.fit(x_train_noisy, x_train,
nb_epoch=100,
batch_size=128,
shuffle=True,
validation_data=(x_test_noisy, x_test))
any suggestions?
I'm getting an error in Keras where the dimension of the output is different than the dimension of the input. I don't understand where the 20 comes from. All my dimensions seem to be showing 18. Also, the Output Shape for convolution2d_70 just says 'multiple', so I'm not sure what that means. Any ideas?
Exception: Error when checking model target: expected convolution2d_70 to have shape (None, 1, 36L, 20L) but got array with shape (49L, 1L, 36L, 18L)
from keras.layers import Dense, Input, Convolution2D, MaxPooling2D, UpSampling2D
from keras.models import Model
from os import listdir
import os.path
import numpy as np
import re
versions = !pip freeze
for line in versions:
if re.search('Keras', line):
print line
samples = 100
x = np.ndarray([samples,36,18])
i=0
for i in range(samples):
x[i] = np.random.randint(15, size=(36, 18))
i+=1
#TODO: CREATE A REAL TEST SET
x_train = x[:49]
x_test = x[50:]
print x_train.shape
print x_test.shape
#INPUT LAYER
input_img = Input(shape=(1,x_train.shape[1],x_train.shape[2]))
x = Convolution2D(16, 3, 3, activation='relu', border_mode='same')(input_img)
x = MaxPooling2D((2, 2), border_mode='same')(x)
x = Convolution2D(8, 3, 3, activation='relu', border_mode='same')(x)
x = MaxPooling2D((2, 2), border_mode='same')(x)
x = Convolution2D(8, 3, 3, activation='relu', border_mode='same')(x)
encoded = MaxPooling2D((2, 2), border_mode='same')(x)
# at this point the representation is (8, 4, 4) i.e. 128-dimensional
x = Convolution2D(8, 3, 3, activation='relu', border_mode='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Convolution2D(8, 3, 3, activation='relu', border_mode='same')(x)
x = UpSampling2D((2, 2))(x)
x = Convolution2D(16, 3, 3, activation='relu')(x)
x = UpSampling2D((2, 2))(x)
decoded = Convolution2D(1, 3, 3, activation='sigmoid', border_mode='same')(x)
#MODEL
autoencoder = Model(input=input_img, output=decoded)
#SEPERATE ENCODER MODEL
encoder = Model(input=input_img, output=encoded)
# create a placeholder for an encoded (32-dimensional) input
encoded_input = Input(shape=(8, 4, 4))
# retrieve the last layer of the autoencoder model
decoder_layer1 = autoencoder.layers[-3]
decoder_layer2 = autoencoder.layers[-2]
decoder_layer3 = autoencoder.layers[-1]
print decoder_layer3.get_config()
# create the decoder model
decoder = Model(input=encoded_input, output=decoder_layer3(decoder_layer2(decoder_layer1(encoded_input))))
#COMPILER
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
autoencoder.summary()
x_train = x_train.astype('float32') / 15.
x_test = x_test.astype('float32') / 15.
x_test = np.reshape(x_test, (len(x_test), 1, x_test.shape[1], x_test.shape[2]))
x_train = np.reshape(x_train, (len(x_train), 1, x_train.shape[1], x_train.shape[2]))
autoencoder.fit(x_train,
x_train,
nb_epoch=5,
batch_size=1,
verbose=True,
shuffle=True,
validation_data=(x_test,x_test))
Notice that in third convolutional layer in decoder you are missing border_mode='same'. This makes your dimensionality mismatch.