How to use data generator to train an autoencoder? - python

I am trying to train an autoencoder and I want to feed the data using a data generator API of Keras. The code snippet is given below. I have tried both fit() and fit_generator() and none of them is working.
seed=24
batch_size= 8
image_height,image_width =32,32
img_data_gen_args = dict(rescale = 1/255.)
image_data_generator = ImageDataGenerator(**img_data_gen_args)
image_generator = image_data_generator.flow_from_directory(path,
seed=seed,
batch_size=batch_size,
class_mode='input')
encoder_input = keras.Input(shape=(image_height,image_width,1))
# encoder
x = Conv2D(32, (3, 3), activation='relu', padding='same')(encoder_input)
x = MaxPooling2D((2, 2), padding='same')(x)
encoded = Conv2D(1, (3, 3), activation='relu', padding='same')(x)
encoder = Model(encoder_input, encoded)
# decoder
decoder_input= Input(shape=(8, 8, 1))
decoder = Conv2D(32, (3, 3), activation='relu', padding='same')(decoder_input)
x = UpSampling2D((2, 2))(decoder)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)
decoder = Model(decoder_input, decoded)
# auto encoder
auto_input = Input(shape=(image_height,image_width, 1))
encoded = encoder(auto_input)
decoded = decoder(encoded)
autoencoder = Model(auto_input, decoded)
autoencoder.compile(optimizer="adam", loss="binary_crossentropy", metrics=['accuracy'])
num_train_imgs = len(os.listdir(path))
steps_per_epoch = num_train_imgs //batch_size
history = autoencoder.fit_generator(generator=image_generator,
validation_data=image_generator,
epochs=20)
# history = model.fit_generator(image_generator, validation_data=image_generator,
# steps_per_epoch=steps_per_epoch,
# validation_steps=steps_per_epoch, epochs=50)
#history = autoencoder.fit(
# image_generator,
# epochs=10,
# validation_data=image_generator,
#)
I am getting the following error
---------------------------------------------------------------------------
UnimplementedError Traceback (most recent call last)
Input In [62], in <cell line: 1>()
----> 1 history = autoencoder.fit_generator(generator=image_generator,
2 validation_data=image_generator,
3 epochs=20)

Your input shape of your decoder needs to be (16, 16, 1) to work with the output of the encoder. Also, try setting color_mode='grayscale' in flow_from_directory. Here is a working example with dummy data:
# Create dummy data
import numpy
from PIL import Image
imarray = numpy.random.rand(32, 32, 3) * 255
im = Image.fromarray(imarray.astype('uint8')).convert('L')
im.save('/content/images/class1/image.png')
im.save('/content/images/class1/image1.png')
im.save('/content/images/class1/image2.png')
im.save('/content/images/class2/image3.png')
im.save('/content/images/class2/image4.png')
im.save('/content/images/class2/image5.png')
Model:
import tensorflow as tf
seed=24
batch_size= 8
image_height,image_width =32,32
img_data_gen_args = dict(rescale = 1/255.)
image_data_generator = tf.keras.preprocessing.image.ImageDataGenerator(**img_data_gen_args)
image_generator = image_data_generator.flow_from_directory('/content/images',
seed=seed, target_size=(image_height, image_width),
batch_size=batch_size,
class_mode='input', color_mode='grayscale')
encoder_input = tf.keras.layers.Input(shape=(image_height,image_width,1))
# encoder
x = tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same')(encoder_input)
x = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(x)
encoded = tf.keras.layers.Conv2D(1, (3, 3), activation='relu', padding='same')(x)
encoder = tf.keras.Model(encoder_input, encoded)
# decoder
decoder_input= tf.keras.layers.Input(shape=(16, 16, 1))
decoder = tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same')(decoder_input)
x = tf.keras.layers.UpSampling2D((2, 2))(decoder)
decoded = tf.keras.layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)
decoder = tf.keras.Model(decoder_input, decoded)
# auto encoder
auto_input = tf.keras.layers.Input(shape=(image_height,image_width, 1))
encoded = encoder(auto_input)
decoded = decoder(encoded)
autoencoder = tf.keras.Model(auto_input, decoded)
autoencoder.compile(optimizer="adam", loss="binary_crossentropy", metrics=['accuracy'])
history = autoencoder.fit(image_generator, epochs=20)
Found 6 images belonging to 2 classes.
Epoch 1/20
1/1 [==============================] - 1s 544ms/step - loss: 0.6932 - accuracy: 0.0000e+00
Epoch 2/20
1/1 [==============================] - 0s 19ms/step - loss: 0.6931 - accuracy: 0.0000e+00
Epoch 3/20
...
...

Related

Tensorflow : convolutional autoencoder via subclassing

I was playing with some Keras samples, defining models through subclassing, but I can't get it working.
from keras import layers, Model
from keras.datasets import mnist
from keras.callbacks import TensorBoard
import numpy as np
import datetime
import os
class Encoder(Model):
def __init__(self, name: str = "encoder"):
super(Encoder, self).__init__(name=name)
self._conv16 = layers.Conv2D(16, (3, 3), activation='relu', padding='same', name="conv16")
self._conv8 = layers.Conv2D(8, (3, 3), activation='relu', padding='same', name="conv8")
self._max_pool = layers.MaxPooling2D((2, 2), padding='same', name="max_pool")
def call(self, inputs: np.ndarray):
x = layers.Conv2D(16, (3, 3), activation='relu', padding='same')(inputs)
x = layers.MaxPooling2D((2, 2), padding='same')(x)
x = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2), padding='same')(x)
x = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(x)
encoded = layers.MaxPooling2D((2, 2), padding='same')(x)
# x = self._conv16(inputs)
# x = self._max_pool(x)
# x = self._conv8(x)
# x = self._max_pool(x)
# x = self._conv8(x)
# encoded = self._max_pool(x)
return encoded
class Decoder(Model):
def __init__(self, name: str = "decoder"):
super(Decoder, self).__init__(name=name)
self._conv16 = layers.Conv2D(16, (3, 3), activation='relu', padding='same', name="conv16")
self._conv8 = layers.Conv2D(8, (3, 3), activation='relu', padding='same', name="conv8")
self._conv1 = layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same', name="conv1")
self._up_sampling = layers.UpSampling2D((2, 2), name="up_samp")
def call(self, inputs: np.ndarray):
x = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(inputs)
x = layers.UpSampling2D((2, 2))(x)
x = layers.Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = layers.UpSampling2D((2, 2))(x)
x = layers.Conv2D(16, (3, 3), activation='relu')(x)
x = layers.UpSampling2D((2, 2))(x)
decoded = layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)
# x = self._conv8(inputs)
# x = self._up_sampling(x)
# x = self._conv8(x)
# x = self._up_sampling(x)
# x = self._conv16(x)
# x = self._up_sampling(x)
# decoded = self._conv1(x)
return decoded
class Autoencoder(Model):
def __init__(self, name: str = "autoencoder"):
super(Autoencoder, self).__init__(name=name)
self.encoder = Encoder()
self.decoder = Decoder()
def call(self, inputs: np.ndarray):
encoded = self.encoder(inputs)
reconstructed = self.decoder(encoded)
return reconstructed
(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))
print(x_train.shape)
print(x_test.shape)
autoencoder = Autoencoder()
autoencoder.compile(optimizer='adam', loss='binary_crossentropy')
autoencoder.fit(x_train, x_train,
epochs=50,
batch_size=128,
shuffle=True,
validation_data=(x_test, x_test)
First of all, I can't get the commented code working. Whenever I try to use it, I get errors such "ValueError: Input 0 of layer "conv8" is incompatible with the layer: expected axis -1of input shape to have value 1, but received input with shape (60000, 56, 56, 8)". I can't spot a difference in the model definition.
Secondly, running the above code gives me:
ValueError: tf.function only supports singleton tf.Variables created on the first call. Make sure the tf.Variable is only created once or created outside tf.function. See https://www.tensorflow.org/guide/function#creating_tfvariables for more information.
I'm not sure what I'm doing wrong.
In your code, there are many issues that need to be addressed. For example,
Issue 1: In the call method, the inputs argument should be tensor and not numpy array.
Issue 2: In model subclassing, you should initiate the trainable layer in the init method or build method and use the instances in the call function. It's the reason for the following error that you got.
ValueError: tf.function only supports singleton tf.Variables were created on the first call. Make sure the tf. Variable is only created once or created outside tf. function. See https://www.tensorflow.org/guide/function#creating_tfvariables for more information.
Issue 3: In your encoder block, it seems that you used self._conv8 twice, which happens also in the decoder block. It shouldn't be like that. If you need to call them twice (or multiple times), you need to initiate each of them in the init (or build) method independently. I think it's one of the so-called downsides of subclassing approach that you need to initiate the N times layer in init and forward their instances in the call method another N times. It's the reason for the following error that you got. ( Side note, passing the same input to the same trainable layer is also referred to as weight sharing, which I don't think it's the intention here. )
ValueError: Input 0 of layer "conv8" is incompatible with the layer: expected axis -1of input shape to have value 1, but received input with shape (60000, 56, 56, 8)
Solution
By addressing the above issue, here is the working code. Also, note that it's better and proper to import keras from tensorflow.
Encoder
from tensorflow.keras import layers, Model
from tensorflow.keras.datasets import mnist
from tensorflow.keras.callbacks import TensorBoard
import numpy as np
class Encoder(Model):
def __init__(self, name: str = "encoder"):
super().__init__(name=name)
self._conv16 = layers.Conv2D(16, (3, 3), activation='relu',
padding='same', name="conv16")
self._conv8 = layers.Conv2D(8, (3, 3), activation='relu',
padding='same', name="conv8")
self._max_pool = layers.MaxPooling2D((2, 2), padding='same',
name="max_pool")
def call(self, inputs):
x = self._conv16(inputs)
x = self._max_pool(x)
encoded = self._conv8(x)
return encoded
Decoder
class Decoder(Model):
def __init__(self, name: str = "decoder"):
super(Decoder, self).__init__(name=name)
self._conv16 = layers.Conv2D(16, (3, 3),
activation='relu',
padding='same', name="conv16")
self._conv8 = layers.Conv2D(8, (3, 3),
activation='relu',
padding='same', name="conv8")
self._conv1 = layers.Conv2D(1, (3, 3),
activation='sigmoid',
padding='same', name="conv1")
self._up_sampling = layers.UpSampling2D((2, 2), name="up_samp")
def call(self, inputs):
x = self._conv8(inputs)
x = self._up_sampling(x)
x = self._conv16(x)
decoded = self._conv1(x)
return decoded
Autoencoder
class Autoencoder(Model):
def __init__(self, name: str = "autoencoder"):
super(Autoencoder, self).__init__(name=name)
self.encoder = Encoder()
self.decoder = Decoder()
def call(self, inputs):
encoded = self.encoder(inputs)
reconstructed = self.decoder(encoded)
return reconstructed
Execute
(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))
print(x_train.shape)
print(x_test.shape)
autoencoder = Autoencoder()
autoencoder.compile(optimizer='adam', loss='binary_crossentropy')
autoencoder.fit(x_train, x_train,
epochs=50,
batch_size=128,
shuffle=True,
validation_data=(x_test, x_test))
Epoch 1/5
12ms/step - loss: 0.1100 - val_loss: 0.0676
Epoch 2/5
12ms/step - loss: 0.0666 - val_loss: 0.0651
Epoch 3/5
12ms/step - loss: 0.0649 - val_loss: 0.0641
Epoch 4/5
12ms/step - loss: 0.0642 - val_loss: 0.0635
Epoch 5/5
11ms/step - loss: 0.0636 - val_loss: 0.0631
Predict
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 2)
y_pred = autoencoder.predict(x_test)
ax[0].imshow(x_test[10, :,:, 0])
ax[1].imshow(y_pred[10, :,:, 0])

Get the output of just bottleneck layer from autoencoder

I'm new to Autoencoder. I have built a simple convolution autoencoder as shown below:
# ENCODER
input_img = Input(shape=(64, 64, 1))
encode1 = Conv2D(32, (3, 3), activation=tf.nn.leaky_relu, padding='same')(input_img)
encode2 = MaxPooling2D((2, 2), padding='same')(encode1)
l = Flatten()(encode2)
l = Dense(100, activation='linear')(l)
# DECODER
d = Dense(1024, activation='linear')(l)
d = Reshape((32,32,1))(d)
decode3 = Conv2D(64, (3, 3), activation=tf.nn.leaky_relu, padding='same')(d)
decode4 = UpSampling2D((2, 2))(decode3)
model = models.Model(input_img, decode4)
model.compile(optimizer='adam', loss='mse')
# Train it by providing training images
model.fit(x, y, epochs=20, batch_size=16)
Now after training this model, I want to get output from bottleneck layer i.e dense layer. That means if I throw array of shape (1000, 64, 64) to model, I want compressed array of shape (1000, 100).
I have tried one method as shown below, but it's giving me some error.
model = Model(inputs=[x], outputs=[l])
err:
ValueError: Input tensors to a Functional must come from `tf.keras.Input`.
I have also tried some other method but that's also not working. Can someone tell me how can I get compressed array back after training the model.
You need to create the separate model for the encoder. After you train the whole system encoder-decoder, you can use only encoder for prediction. Code example:
# ENCODER
input_img = layers.Input(shape=(64, 64, 1))
encode1 = layers.Conv2D(32, (3, 3), activation=tf.nn.leaky_relu, padding='same')(input_img)
encode2 = layers.MaxPooling2D((2, 2), padding='same')(encode1)
l = layers.Flatten()(encode2)
encoder_output = layers.Dense(100, activation='linear')(l)
# DECODER
d = layers.Dense(1024, activation='linear')(encoder_output)
d = layers.Reshape((32,32,1))(d)
decode3 = layers.Conv2D(64, (3, 3), activation=tf.nn.leaky_relu, padding='same')(d)
decode4 = layers.UpSampling2D((2, 2))(decode3)
model_encoder = Model(input_img, encoder_output)
model = Model(input_img, decode4)
model.fit(X, y, epochs=20, batch_size=16)
model_encoder.predict(X) should return a vector for each image.
Getting the output of intermediate layer (bottleneck_layer).
# ENCODER
input_img = Input(shape=(64, 64, 1))
encode1 = Conv2D(32, (3, 3), activation=tf.nn.leaky_relu, padding='same')(input_img)
encode2 = MaxPooling2D((2, 2), padding='same')(encode1)
l = Flatten()(encode2)
bottleneck = Dense(100, activation='linear', name='bottleneck_layer')(l)
# DECODER
d = Dense(1024, activation='linear')(bottleneck)
d = Reshape((32,32,1))(d)
decode3 = Conv2D(64, (3, 3), activation=tf.nn.leaky_relu, padding='same')(d)
decode4 = UpSampling2D((2, 2))(decode3)
# full model
model_full = models.Model(input_img, decode4)
model_full.compile(optimizer='adam', loss='mse')
model_full.fit(x, y, epochs=20, batch_size=16)
# bottleneck model
bottleneck_output = model_full.get_layer('bottleneck_layer').output
model_bottleneck = models.Model(inputs = model_full.input, outputs = bottleneck_output)
bottleneck_predictions = model_bottleneck.predict(X_test)

How can I calculate score of a new image using entrained autoencoder model for anomaly detection in tensorflow?

I am beginner in tensorflow and I am trying to create a simple autoencoder for images to detect anomalies.Firstly, I created a simple autoencoder using dogs images , now I want to use this model to reconstruct my tests images and compare the result using some metrics.So how can I do it on tensorflow (because I am beginner on tensorflow )
(I found the same idea implemented on numerical datasets , and also on MNIST dataset ).
this is my code:
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import LearningRateScheduler
BATCH_SIZE = 256
EPOCHS = 2
train_datagen = ImageDataGenerator(rescale=1./255)
train_batches = train_datagen.flow_from_directory('C:/MyPath/PetImages1',
target_size=(64,64), shuffle=True, class_mode='input', batch_size=BATCH_SIZE)
input_img = Input(shape=(64, 64, 3))
x = Conv2D(48, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(96, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(192, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), padding='same')(x)
encoded = Conv2D(32, (1, 1), activation='relu', padding='same')(x)
latentSize = (8,8,32)
# DECODER
direct_input = Input(shape=latentSize)
x = Conv2D(192, (1, 1), activation='relu', padding='same')(direct_input)
x = UpSampling2D((2, 2))(x)
x = Conv2D(192, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(96, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(48, (3, 3), activation='relu', padding='same')(x)
decoded = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x)
# COMPILE
encoder = Model(input_img, encoded)
decoder = Model(direct_input, decoded)
autoencoder = Model(input_img, decoder(encoded))
autoencoder.compile(optimizer='Adam', loss='binary_crossentropy')
autoencoder.save_weights('autoencoder_DogsAuto.h5')
history=autoencoder.fit_generator(train_batches,steps_per_epoch=10,epochs =
EPOCHS)
#Images for tests
testGene = train_datagen.flow_from_directory('C:/PetImages/',
target_size=(64,64), shuffle=True, class_mode='input',
batch_size=BATCH_SIZE)
restored = autoencoder.predict_generator(testGene,
steps=testGene.n/BATCH_SIZE)
image_height=64
image_width=64
image_channels=3
x_train = np.zeros((0, image_height, image_width, image_channels), dtype=float)
for x, _ in train_batches :
if train_batches.total_batches_seen > train_batches.n/BATCH_SIZE:
break
else:
x_train = np.r_[x_train,x]
pred=autoencoder.predict(train_batches, steps=train_batches.n/BATCH_SIZE)
from sklearn import metrics
score1=np.sqrt(metrics.mean_squared_error(pred,x_train ))
print(score1)
And I got this error:
Traceback (most recent call last):
File "c:\autoencoder_anomaly.py", line 196, in
score1=np.sqrt(metrics.mean_squared_error(pred,x_train ))
File "C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\sklearn\metrics_regression.py", line 252, in mean_squared_error
y_true, y_pred, multioutput)
File "C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\sklearn\metrics_regression.py", line 84, in _check_reg_targets
check_consistent_length(y_true, y_pred)
ValueError: Found input variables with inconsistent numbers of samples: [6, 0]
Note that I am using only 6 images.
So how can I calculate the error of the reconstructed image using metrics and the autoencoder Model on tensorflow ?
This is simply because of shape mismatch.
when you calculate mean squared error,it calculates the element wise error of ground truth values and estimated values. so pred.shape and train_batches.shape should be equal.check the input data shapes and make sure they are equal.
step 1:
get all training images from the generator and add to one array
x_test = np.zeros((0, image_height, image_width, image_color), dtype=float)
for x, _ in testGene:
if testGene.total_batches_seen > testGene.n/BATCH_SIZE:
break
else:
x_test = np.r_[x_test , x]
step 2 : prediction
pred=autoencoder.predict(testGene, steps=testGene.n/BATCH_SIZE)
step 3 : calculate the difference
score1=np.sqrt(metrics.mean_squared_error(pred,testGene))

'Reshape' object is not iterable

I am trying to combine encoder and decoder in keras
Here is minimal code to test
Data load
from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D, Flatten, Reshape
from keras.models import Model
from keras import backend as K
from keras.datasets import mnist
import numpy as np
(x_train, _), (x_test, _) = mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_train = x_train[:5,:,:,]
x_test = x_test.astype('float32') / 255.
x_test = x_train
x_train = np.reshape(x_train, (len(x_train), 28, 28, 1)) # adapt this if using `channels_first` image data format
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1)) # adapt this if using `channels_first` image data format
Creating the model
input_img = Input(shape=(28, 28, 1))
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)
encoderOutputFlat = Flatten()(encoded)
encoder = Model(input_img, encoderOutputFlat)
decoder_input = Input(Reshape((7,7,32)))(encoderOutputFlat)
decoder = Conv2D(32, (3, 3), activation='relu', padding='same')(decoder_input)
x = UpSampling2D((2, 2))(decoder)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)
decoder = Model(decoder_input, decoded)
auto_input = Input(shape=(28,28,1))
encoded = encoder(auto_input)
decoded = decoder(encoded)
autoencoder = Model(auto_input, decoded)
Here I have the error
decoder_input = Input(Reshape((7,7,32)))(encoderOutputFlat)
How can I make it work?
I want to train it as one model. Then get values from encoder. Then I want to use decoder on the data separately.

How to use a different CNN without losing accuracy

I have been given a task to implement a Convolutional neural network that can evaluate hand-written digits found in the MNIST dataset with the architecture of the network looking like this:
I have implemented a CNN that matches the architecture, unfortunately it only has about a 10% accuracy to it. I've looked online and tried other example CNNs to make sure if anything else causing the issue, however they seem to work fine and give me a ~99% accuracy. I've placed both CNNs in my code and made a boolean switch to show the difference between the two:
import tensorflow
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
batch_size = 128
num_classes = 10
epochs = 1
img_rows, img_cols = 28, 28
(x_train, y_train), (x_test, y_test) = mnist.load_data()
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')
y_train = tensorflow.keras.utils.to_categorical(y_train, num_classes)
y_test = tensorflow.keras.utils.to_categorical(y_test, num_classes)
exampleModel = False # Use to toggle which CNN goes into the model
if exampleModel: # An example CNN that I found for MNIST
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
activation='relu',
input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
else: # The CNN I created
input_layer = tensorflow.keras.layers.Input(shape=input_shape)
conv1 = Conv2D(32, (1, 1), activation='relu')(input_layer)
pool1 = MaxPooling2D(2, 2)(conv1)
conv2_1 = Conv2D(64, (1, 1), activation='relu', padding='same')(pool1)
pool2_1 = MaxPooling2D(2, 2)(conv2_1)
drop2_1 = Dropout(0.5)(pool2_1)
conv2_2 = Conv2D(64, (1, 1), activation='relu', padding='same')(pool1)
pool2_2 = MaxPooling2D(2, 2)(conv2_2)
drop2_2 = Dropout(0.5)(pool2_2)
conv3_1 = Conv2D(256, (1, 1), activation='relu', padding='same')(drop2_1)
conv3_2 = Conv2D(256, (1, 1), activation='relu', padding='same')(drop2_2)
merged = tensorflow.keras.layers.concatenate([conv3_1, conv3_2], axis=-1)
merged = Dropout(0.5)(merged)
merged = Flatten()(merged)
fc1 = Dense(1000, activation='relu')(merged)
fc2 = Dense(500, activation='relu')(fc1)
out = Dense(10)(fc2)
model = tensorflow.keras.models.Model(input_layer, out)
model.compile(loss=tensorflow.keras.losses.categorical_crossentropy,
optimizer=tensorflow.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])
In order to complete my task, I believe I have to convert my example CNN piece-by-piece into the required architecture. Although I have no idea how to do this, they look completely different from each other (one is purely sequential, the other uses parallel layers and merging). I'm a beginner in machine learning so there might be something that I'm missing although I can't find and resource online that goes into this conversion process. Any help with this is appreciated.
You simply have to add an softmax activation to the last, out layer:
out = Dense(10, activation="softmax")(fc2)
Thus your model in completed form:
input_layer = tensorflow.keras.layers.Input(shape=input_shape)
conv1 = Conv2D(32, (1, 1), activation='relu')(input_layer)
pool1 = MaxPooling2D(2, 2)(conv1)
conv2_1 = Conv2D(64, (1, 1), activation='relu', padding='same')(pool1)
pool2_1 = MaxPooling2D(2, 2)(conv2_1)
drop2_1 = Dropout(0.5)(pool2_1)
conv2_2 = Conv2D(64, (1, 1), activation='relu', padding='same')(pool1)
pool2_2 = MaxPooling2D(2, 2)(conv2_2)
drop2_2 = Dropout(0.5)(pool2_2)
conv3_1 = Conv2D(256, (1, 1), activation='relu', padding='same')(drop2_1)
conv3_2 = Conv2D(256, (1, 1), activation='relu', padding='same')(drop2_2)
merged = tensorflow.keras.layers.concatenate([conv3_1, conv3_2], axis=-1)
merged = Dropout(0.5)(merged)
merged = Flatten()(merged)
fc1 = Dense(1000, activation='relu')(merged)
fc2 = Dense(500, activation='relu')(fc1)
out = Dense(10, activation="softmax")(fc2)
Out:
x_train shape: (60000, 28, 28, 1)
60000 train samples
10000 test samples
Train on 60000 samples, validate on 10000 samples
Epoch 1/1
60000/60000 [==============================] - 25s 416us/step - loss: 0.6394 - acc: 0.7858 - val_loss: 0.2956 - val_acc: 0.9047
Test loss: 0.29562548571825026
Test accuracy: 0.9047

Categories

Resources