PCA in CNN deep learning model using Keras - tensorflow

I built a CNN model for image classification using Keras and I want to use principal component analysis (PCA) with the model. How to use PCA in CNN for image recognition using Keras?
I have tried the following code but when I run pca.fit() code, the code still running for hours and the RAM become full.
#Data files
train_iris_data = 'Iris_Database_01/Training'
valid_iris_data = 'Iris_Database_01/Validation'
test_iris_data = 'Iris_Database_01/Testing'
#Image data generator
train_iris_datagen = ImageDataGenerator(
rotation_range=10,
shear_range=0.2,
zoom_range=0.1,
width_shift_range=0.1,
height_shift_range=0.1
)
test_iris_datagen = ImageDataGenerator()
#Image batches
image_size = (224, 224)
batch = 32
# Training
train_iris_generator = train_iris_datagen.flow_from_directory(
train_iris_data,
target_size=image_size,
batch_size=batch,
class_mode='categorical')
# Validation
validation_iris_generator = test_iris_datagen.flow_from_directory(
valid_iris_data,
target_size=image_size,
batch_size=batch,
class_mode='categorical',
shuffle = False)
# Testing
test_iris_generator = test_iris_datagen.flow_from_directory(
test_iris_data,
target_size=image_size,
batch_size=1,
class_mode='categorical',
shuffle = False)
pca = PCA(n_components=2)
pca.fit(train_iris_generator)
#pca = PCA(n_components=0.8)
#pca.fit(train_iris_generator)

you can use truncated SVD instead. Another method that you can use is, IncrementalPCA PCA.
from sklearn.decomposition import TruncatedSVD
from sklearn.decomposition import IncrementalPCA
def func_PCA(input_data):
input_data = np.array(input_data)
pca = IncrementalPCA(n_components=50, batch_size=50)
pca.fit(input_data)
pca_input_data = pca.transform(input_data)
eigenvalues = pca.explained_variance_
eigenvectors = pca.components_
return pca_input_data, eigenvalues, eigenvectors
def svd_func(input_data):
svd = TruncatedSVD(n_components=50)
svd.fit(input_data)
pca_input_data = svd.transform(input_data)
eigenvalues = svd.explained_variance_
eigenvectors = svd.components_
return pca_input_data, eigenvalues, eigenvectors

Related

Why pure tensorflow autoencoder cannot converge, when Keras one fits good

I'm newbie at machine learning(and at stackoverflow too). I want to ask for help.
I have two implementations of same two-layer autoencoder for mnist.
First one fits good:
import tensorflow as tf, numpy as np
def in_pics(pics):
return np.array(pics, np.float32)/255.
def out_pics(pics):
npformed = np.array(pics, np.float32)
samples = np.shape(npformed)[0]
return np.reshape(npformed, (samples, 784))/255.
(train_data, test_data) = tf.keras.datasets.mnist.load_data()
train_dataset = tf.data.Dataset.from_tensor_slices((in_pics(train_data[0]), out_pics(train_data[0]))).batch(100)
test_dataset = tf.data.Dataset.from_tensor_slices((in_pics(test_data[0]), out_pics(test_data[0]))).batch(100)
model = tf.keras.Sequential(
[
tf.keras.layers.InputLayer(input_shape=(28,28)),
tf.keras.layers.Reshape(target_shape=(784,)),
tf.keras.layers.Dense(128, activation="sigmoid", kernel_initializer=tf.keras.initializers.truncated_normal(stddev=0.1),
bias_initializer =tf.keras.initializers.truncated_normal(stddev=0.1)),
tf.keras.layers.Dense(784, activation="sigmoid", kernel_initializer=tf.keras.initializers.truncated_normal(stddev=0.1),
bias_initializer =tf.keras.initializers.truncated_normal(stddev=0.1)),
]
)
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), optimizer="adam")
model.fit(x = train_dataset, epochs=20, verbose=1, validation_data=test_dataset)
Keras result
And I have the same model, same learning procedure, but written in terms of pure tensorflow(almost):
import tensorflow as tf, numpy as np
def prep_pics(pics):
npformed = np.array(pics, np.float32)
samples = np.shape(npformed)[0]
return np.reshape(npformed, (samples, 784))/255.
batch_size, num_batches = 100, 12000
(train_data, test_data) = tf.keras.datasets.mnist.load_data()
(train_pics_prepared, test_pics_prepared) = (prep_pics(train_data[0]), prep_pics(test_data[0]))
train_dataset = tf.data.Dataset.from_tensor_slices((train_pics_prepared, train_pics_prepared))
test_dataset = tf.data.Dataset.from_tensor_slices((test_pics_prepared, test_pics_prepared)).batch(batch_size)
encoder_W = tf.Variable(tf.keras.initializers.truncated_normal(stddev=0.1)(shape = [784,128], dtype = tf.float32))
encoder_b = tf.Variable(tf.keras.initializers.truncated_normal(stddev=0.1)(shape = [128],dtype = tf.float32))
decoder_W = tf.Variable(tf.keras.initializers.truncated_normal(stddev=0.1)(shape = [128,784], dtype = tf.float32))
decoder_b = tf.Variable(tf.keras.initializers.truncated_normal(stddev=0.1)(shape = [784],dtype = tf.float32))
optimizer = tf.keras.optimizers.Adam()
bin_cross = tf.keras.losses.BinaryCrossentropy(from_logits=True)
#tf.function
def trainstep(X_pack, Y_pack):
with tf.GradientTape() as tape:
tape.watch([encoder_W, encoder_b, decoder_W, decoder_b])
encoded = tf.nn.sigmoid(tf.matmul(X_pack, encoder_W) + encoder_b)
decoded = tf.nn.sigmoid(tf.matmul(encoded, decoder_W) + decoder_b)
loss = bin_cross(decoded, Y_pack)
gradients = tape.gradient(loss, [encoder_W, encoder_b, decoder_W, decoder_b])
optimizer.apply_gradients(zip(gradients, [encoder_W, encoder_b, decoder_W, decoder_b]))
num_samples = len(train_data[0])
epochs = num_batches//(num_samples//batch_size)
for i in range(epochs):
print(f"Epoch num {i+1}:")
dataset = train_dataset.shuffle(num_samples).batch(batch_size)
for x,y in dataset:
trainstep(x,y)
Loss is never becomes lower than 0.64(First one had 0.07 in the end of education).
Tensorflow result.
What I tried:
1.) Change optimizer to Adagrad and even to SGD.
2.) Use other loss - sigmoid_cross_entropy_with_logits.
3.) Learn more. Especially for SGD.
Cannot find mistake or typo almost for week. Please, help!

Agumenting data in keras using albumentations

I am trying to train a keras ResNet50 model for image classification model using a tutorial. Instead of the inbuilt data generator, I want to use albumentations library for augmentation.
from albumentations import Compose
transforms = Compose([HorizontalFlip()])
I have read a few articles, but I could not figure out how to implement albumentations.
Which line of code should I modify to implement albumentations.
I am reproducing the code below after removing non necessary lines.
NUM_CLASSES = 2
CHANNELS = 3
IMAGE_RESIZE = 224
RESNET50_POOLING_AVERAGE = 'avg'
DENSE_LAYER_ACTIVATION = 'softmax'
OBJECTIVE_FUNCTION = 'categorical_crossentropy'
LOSS_METRICS = ['accuracy']
NUM_EPOCHS = 300
EARLY_STOP_PATIENCE = 20
STEPS_PER_EPOCH_TRAINING = 20
STEPS_PER_EPOCH_VALIDATION = 20
BATCH_SIZE_TRAINING = 10
BATCH_SIZE_VALIDATION = 10
# %% ---------------------------------------------------------------------
TrainingData_directory = 'C:/datafolder/Train'
ValidationData_directory = 'C:/datafolder/Validation'
ModelCheckpointPath = 'C:/datafolder/ResNet50_Weights.hdf5'
# %% ---------------------------------------------------------------------
from albumentations import Compose
import tensorflow as tf
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# %% ---------------------------------------------------------------------
model = Sequential()
model.add(ResNet50(include_top = False, pooling = RESNET50_POOLING_AVERAGE, weights = 'imagenet'))
model.add(Dense(NUM_CLASSES, activation = DENSE_LAYER_ACTIVATION))
model.layers[0].trainable = False
from tensorflow.keras import optimizers
sgd = optimizers.SGD(lr = 0.001, decay = 1e-6, momentum = 0.9, nesterov = True)
model.compile(optimizer = sgd, loss = OBJECTIVE_FUNCTION, metrics = LOSS_METRICS)
from keras.applications.resnet50 import preprocess_input
from keras.preprocessing.image import ImageDataGenerator
image_size = IMAGE_RESIZE
data_generator = ImageDataGenerator(preprocessing_function = preprocess_input)
train_generator = data_generator.flow_from_directory(TrainingData_directory,
target_size = (image_size, image_size),
batch_size = BATCH_SIZE_TRAINING,
class_mode = 'categorical')
validation_generator = data_generator.flow_from_directory(ValidationData_directory,
target_size = (image_size, image_size),
batch_size = BATCH_SIZE_VALIDATION,
class_mode = 'categorical')
from tensorflow.python.keras.callbacks import EarlyStopping, ModelCheckpoint
cb_early_stopper = EarlyStopping(monitor = 'val_loss', patience = EARLY_STOP_PATIENCE)
cb_checkpointer = ModelCheckpoint(filepath = ModelCheckpointPath,
monitor = 'val_loss', save_best_only = True, mode = 'auto')
fit_history = model.fit_generator(
train_generator,
steps_per_epoch=STEPS_PER_EPOCH_TRAINING,
epochs = NUM_EPOCHS,
validation_data=validation_generator,
validation_steps=STEPS_PER_EPOCH_VALIDATION,
callbacks=[cb_checkpointer, cb_early_stopper]
)
I think you can do it using the ImageDataGenerator preprocessing_function. The function should taken in a single image as input and return an image. So in your case.
def augmentor (img)
# place you code here do to the albumentations transforms
# your code should result in a single transformed image I called aug_img
return aug_img/127.5-1 #scales the pixels between -1 and +1 which it what preprocees_input does
data_generator = ImageDataGenerator(preprocessing_function = augmentor)
You can include it into the preprocessing function passed to ImageDataGenerator:
def preprocessing_function(x):
preprocessed_x = preprocess_input(x)
transformed_image = transforms(image=preprocessed_x)['image']
return transformed_image
ImageDataGenerator(preprocessing_function = preprocessing_function)
That's (IMO) the limitation or losing the flexibility that one might come across using a built-in data generator (ImageDataGenerator). You should implement your own custom data generator.
Check this kernel: [TF.Keras]: SOTA Augmentation in Sequence Generator, where we've shown how one can use albumentation, cutmix, mixup, and fmix type advance augmentation into the custom generator. Here is a basic approach of how to use albumentaiton in a custom data generator.
import albumentations as A
# For Training
def albu_transforms_train(data_resize):
return A.Compose([
A.ToFloat(),
A.Resize(data_resize, data_resize),
A. [.....what ever......]
], p=1.)
class Generator(tf.keras.utils.Sequence):
def __getitem__(self, index):
...........
Data = np.empty((self.batch_size, *self.dim))
Target = np.empty((self.batch_size, 5), dtype = np.float32)
for i, k in enumerate(idx):
# load the image file using cv2
image = cv2.imread(self.img_path + self.data['image_id'][k])
image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
# call augmentor / albumentation
res = self.augment(image=image)
image = res['image']
# assign
Data[i,:, :, :] = image
Target[i,:] = self.label.loc[k, :].values
return Data, Target
# call the generator
check_gens = Generator(...., transform = albu_transforms_train(128))

transfer learning of Inception v3 returns the same predictions

I have tried to customize inception to classify. I used the cat, dog, human and other to classify cat, dog, human ( collection of family photos) and other (mostly natural scenes) I have about 2000 dog, 1000 cat, 7000 human and 3000 images split 80:20 among the train and validate. The essence of model is as below. When I train the training accuracy is close to 97% and validation accuracy is ~90%.
import os
from tensorflow.keras import layers
from tensorflow.keras import Model
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.applications.inception_v3 import InceptionV3
local_weights_file = 'C:/users/sethr/education/Healthcare/imagedetect/modelimageadvance /inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'
pre_trained_model = InceptionV3(input_shape = (150, 150,3), include_top = False, weights = `enter code here`local_weights_file)
for layer in pre_trained_model.layers:
layer.trainable = False
# pre_trained_model.summary()
last_layer = pre_trained_model.get_layer('mixed7')
#print('last layer output shape: ', last_layer.output_shape)
last_output = last_layer.output
# Flatten the output layer to 1 dimension
x = tf.keras.layers.Flatten()(last_output)
# Add a fully connected layer with 1,024 hidden units and ReLU activation
x = tf.keras.layers.Dense(512, activation='relu')(x)
x = tf.keras.layers.Dense(256, activation='relu')(x)
# Add a dropout rate of 0.2
x = tf.keras.layers.Dropout(0.2)(x)
# Add a final sigmoid layer for classification
x = tf.keras.layers.Dense(4, activation='softmax')(x)
model = Model(pre_trained_model.input, x)
model.compile(optimizer = RMSprop(lr=0.0001), loss = 'categorical_crossentropy', metrics = ['accuracy'])
history = model.fit(train_generator,validation_data = validation_generator,steps_per_epoch = 20,epochs = 20,validation_steps = 25,verbose = 2)
model.save("dcho.rp5")
___________________
import numpy as np
import cv2
import glob
from keras.preprocessing import image
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
labels= ["cat","dog","human","other"]
path='C:/Users/sethr/education/Healthcare/imagedetect/images/*.jpg'
for fim in glob.glob(path):
# predicting images
img=image.load_img(fim, target_size=(150, 150))
x=image.img_to_array(img)
x=np.expand_dims(x, axis=0)
images = np.vstack([x])
plt.figure()
plt.imshow(img)
plt.show()
classes = model.predict(images,batch_size=10)
________________________________________________________
_______________________________________________________
# All images will be rescaled by 1./255.
train_datagen = ImageDataGenerator( rescale = 1.0/255. )
test_datagen = ImageDataGenerator( rescale = 1.0/255. )
# --------------------
# Flow training images in batches of 20 using train_datagen generator
# --------------------
train_generator = train_datagen.flow_from_directory(train_dir,
batch_size=20,
shuffle='True',
class_mode='categorical',
target_size=(150, 150))
# --------------------
# Flow validation images in batches of 20 using test_datagen generator
# --------------------
validation_generator = test_datagen.flow_from_directory(validation_dir,
target_size = (150, 150),
batch_size=20,
class_mode='categorical',
shuffle='True',
)
_______________________________________________________________
The problem is it is returning always human as prediction.. I played around with Adam, Adjusted learning rate but still the prediction remains the same. Any insight.
The issue is you have not done the rescaling part when you predicting images.
You are doing rescaling only for training and validation
train_datagen = ImageDataGenerator( rescale = 1.0/255. )
test_datagen = ImageDataGenerator( rescale = 1.0/255. )
# Note - this test_datagen used for validation
In order to get correct predictions, we should do the same preprocessing steps as we did for training and validation. So you need to rescale the image.
You can rescale the image by using this code
x = x* 1.0/255.0
So the correct predicting image part is shown below.
for fim in glob.glob(path):
# predicting images
img=image.load_img(fim, target_size=(150, 150))
x=image.img_to_array(img)
x=np.expand_dims(x, axis=0)
# Add this line
x = x* 1.0/255.0
images = np.vstack([x])
plt.figure()
plt.imshow(img)
plt.show()
classes = model.predict(images,batch_size=10)

How to use tensorflow feature_columns as input to a keras model

Tensorflow's feature_columns API is quite useful for non-numerical feature processing. However, the current API doc is more about using feature_columns with tensorflow Estimator. Is there a possible way to use feature_columns for categorical features representation and then build a model based on tf.keras?
The only reference I found is the following tutorial. It shows how to feed feature columns to a Keras Sequential model: Link
The code snippet is as follows:
from tensorflow.python.feature_column import feature_column_v2 as fc
feature_columns = [fc.embedding_column(ccv, dimension=3), ...]
feature_layer = fc.FeatureLayer(feature_columns)
model = tf.keras.Sequential([
feature_layer,
tf.keras.layers.Dense(128, activation=tf.nn.relu),
tf.keras.layers.Dense(64, activation=tf.nn.relu),
tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)
])
...
model.fit(dataset, steps_per_epoch=8) # dataset is created from tensorflow Dataset API
The question is how to use a customed model with keras functional model API. I tried the following, but it did not work (tensorflow version 1.12)
feature_layer = fc.FeatureLayer(feature_columns)
dense_features = feature_layer(features) # features is a dict of ndarrays in dataset
layer1 = tf.keras.layers.Dense(128, activation=tf.nn.relu)(dense_features)
layer2 = tf.keras.layers.Dense(64, activation=tf.nn.relu)(layer1)
output = tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)(layer2)
model = Model(inputs=dense_features, outputs=output)
The error log:
ValueError: Input tensors to a Model must come from `tf.layers.Input`. Received: Tensor("feature_layer/concat:0", shape=(4, 3), dtype=float32) (missing previous layer metadata).
I don't kown how to transform feature columns to keras model's input.
The behavior you desire could be achieved and it's able to combine tf.feature_column and keras functional API. And, actually, is not mentioned in TF docs.
This works at least in TF 2.0.0-beta1, but may being changed or even simplified in further releases.
Please check out issue in TensorFlow github repository Unable to use FeatureColumn with Keras Functional API #27416. There you will find useful comments about tf.feature_column and Keras Functional API.
Because you ask about general approach I would just copy the snippet with example from the link above. update: the code below should work
from __future__ import absolute_import, division, print_function
import numpy as np
import pandas as pd
#!pip install tensorflow==2.0.0-alpha0
import tensorflow as tf
from tensorflow import feature_column
from tensorflow import keras
from tensorflow.keras import layers
from sklearn.model_selection import train_test_split
csv_file = tf.keras.utils.get_file('heart.csv', 'https://storage.googleapis.com/download.tensorflow.org/data/heart.csv')
dataframe = pd.read_csv(csv_file, nrows = 10000)
dataframe.head()
train, test = train_test_split(dataframe, test_size=0.2)
train, val = train_test_split(train, test_size=0.2)
print(len(train), 'train examples')
print(len(val), 'validation examples')
print(len(test), 'test examples')
# Define method to create tf.data dataset from Pandas Dataframe
# This worked with tf 2.0 but does not work with tf 2.2
def df_to_dataset_tf_2_0(dataframe, label_column, shuffle=True, batch_size=32):
dataframe = dataframe.copy()
#labels = dataframe.pop(label_column)
labels = dataframe[label_column]
ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
if shuffle:
ds = ds.shuffle(buffer_size=len(dataframe))
ds = ds.batch(batch_size)
return ds
def df_to_dataset(dataframe, label_column, shuffle=True, batch_size=32):
dataframe = dataframe.copy()
labels = dataframe.pop(label_column)
#labels = dataframe[label_column]
ds = tf.data.Dataset.from_tensor_slices((dataframe.to_dict(orient='list'), labels))
if shuffle:
ds = ds.shuffle(buffer_size=len(dataframe))
ds = ds.batch(batch_size)
return ds
batch_size = 5 # A small batch sized is used for demonstration purposes
train_ds = df_to_dataset(train, label_column = 'target', batch_size=batch_size)
val_ds = df_to_dataset(val,label_column = 'target', shuffle=False, batch_size=batch_size)
test_ds = df_to_dataset(test, label_column = 'target', shuffle=False, batch_size=batch_size)
age = feature_column.numeric_column("age")
feature_columns = []
feature_layer_inputs = {}
# numeric cols
for header in ['age', 'trestbps', 'chol', 'thalach', 'oldpeak', 'slope', 'ca']:
feature_columns.append(feature_column.numeric_column(header))
feature_layer_inputs[header] = tf.keras.Input(shape=(1,), name=header)
# bucketized cols
age_buckets = feature_column.bucketized_column(age, boundaries=[18, 25, 30, 35])
feature_columns.append(age_buckets)
# indicator cols
thal = feature_column.categorical_column_with_vocabulary_list(
'thal', ['fixed', 'normal', 'reversible'])
thal_one_hot = feature_column.indicator_column(thal)
feature_columns.append(thal_one_hot)
feature_layer_inputs['thal'] = tf.keras.Input(shape=(1,), name='thal', dtype=tf.string)
# embedding cols
thal_embedding = feature_column.embedding_column(thal, dimension=8)
feature_columns.append(thal_embedding)
# crossed cols
crossed_feature = feature_column.crossed_column([age_buckets, thal], hash_bucket_size=1000)
crossed_feature = feature_column.indicator_column(crossed_feature)
feature_columns.append(crossed_feature)
feature_layer = tf.keras.layers.DenseFeatures(feature_columns)
feature_layer_outputs = feature_layer(feature_layer_inputs)
x = layers.Dense(128, activation='relu')(feature_layer_outputs)
x = layers.Dense(64, activation='relu')(x)
baggage_pred = layers.Dense(1, activation='sigmoid')(x)
model = keras.Model(inputs=[v for v in feature_layer_inputs.values()], outputs=baggage_pred)
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
model.fit(train_ds)
If you use tensorflow dataset API, that code could do well.
featurlayer = keras.layers.DenseFeatures(feature_columns=feature_columns)
train_dataset = train_dataset.map(lambda x, y: (featurlayer(x), y))
test_dataset = test_dataset.map(lambda x, y: (featurlayer(x), y))
model.fit(train_dataset, epochs=, steps_per_epoch=, # all_data/batch_num =
validation_data=test_dataset,
validation_steps=)
tf.feature_column.input_layer
user this function, and this api doc has a sample .
you can transform featur_columns into Tensor, and then use it into Mode()
I have been recently reading this document in TensorFlow 2.0 alpha version. It has examples using Keras together with the feature column API. Not sure if TF 2.0 is what you are going to use

Keras model predict fails

im a bit of a noob in ML. ive been trying to get a model retrained on the flowers dataset to work on keras-js withous success. whenever i try to run predict on the model i get "Error: predict() must take an object where the keys are the named inputs of the model: input_1." pls help here is my code
test.py
import sys
import json
import numpy as np
from collections import defaultdict
# It's very important to put this import before keras,
# as explained here: Loading tensorflow before scipy.misc seems to cause imread to fail #1541
# https://github.com/tensorflow/tensorflow/issues/1541
import scipy.misc
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import SGD
from keras import backend as K
from keras.utils import np_utils
import dataset
import net
np.random.seed(1337)
spe = 500
n = 299
batch_size = 128
nb_epoch = 1
nb_phase_two_epoch = 1
data_directory, test_directory, model_file_prefix = sys.argv[1:]
print "loading dataset"
X, y, tags = dataset.dataset(data_directory, n)
nb_classes = len(tags)
sample_count = len(y)
train_size = sample_count * 4 // 5
X_train = X[:train_size]
y_train = y[:train_size]
Y_train = np_utils.to_categorical(y_train, nb_classes)
X_test = X[train_size:]
y_test = y[train_size:]
Y_test = np_utils.to_categorical(y_test, nb_classes)
datagen = ImageDataGenerator(
featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=0,
width_shift_range=0.125,
height_shift_range=0.125,
horizontal_flip=True,
vertical_flip=False,
fill_mode='nearest')
#datagen.fit(X_train)
train_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
data_directory,
target_size=(299,299),
batch_size=16,
class_mode='categorical'
)
validation_generator = train_datagen.flow_from_directory(
data_directory,
target_size=(299,299),
batch_size=16,
class_mode='categorical'
)
def evaluate(model, vis_filename=None):
Y_pred = model.predict(X_test, batch_size=batch_size)
y_pred = np.argmax(Y_pred, axis=1)
accuracy = float(np.sum(y_test==y_pred)) / len(y_test)
print "accuracy:", accuracy
confusion = np.zeros((nb_classes, nb_classes), dtype=np.int32)
for (predicted_index, actual_index, image) in zip(y_pred, y_test, X_test):
confusion[predicted_index, actual_index] += 1
print "rows are predicted classes, columns are actual classes"
for predicted_index, predicted_tag in enumerate(tags):
print predicted_tag[:7],
for actual_index, actual_tag in enumerate(tags):
print "\t%d" % confusion[predicted_index, actual_index],
print
if vis_filename is not None:
bucket_size = 10
image_size = n // 4 # right now that's 56
vis_image_size = nb_classes * image_size * bucket_size
vis_image = 255 * np.ones((vis_image_size, vis_image_size, 3), dtype='uint8')
example_counts = defaultdict(int)
for (predicted_tag, actual_tag, normalized_image) in zip(y_pred, y_test, X_test):
example_count = example_counts[(predicted_tag, actual_tag)]
if example_count >= bucket_size**2:
continue
image = dataset.reverse_preprocess_input(normalized_image)
image = image.transpose((1, 2, 0))
image = scipy.misc.imresize(image, (image_size, image_size)).astype(np.uint8)
tilepos_x = bucket_size * predicted_tag
tilepos_y = bucket_size * actual_tag
tilepos_x += example_count % bucket_size
tilepos_y += example_count // bucket_size
pos_x, pos_y = tilepos_x * image_size, tilepos_y * image_size
vis_image[pos_y:pos_y+image_size, pos_x:pos_x+image_size, :] = image
example_counts[(predicted_tag, actual_tag)] += 1
vis_image[::image_size * bucket_size, :] = 0
vis_image[:, ::image_size * bucket_size] = 0
scipy.misc.imsave(vis_filename, vis_image)
print "loading original inception model"
model = net.build_model(nb_classes)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=["accuracy"])
# train the model on the new data for a few epochs
print "training the newly added dense layers"
print "samples per eph ",spe#X_train.shape[0]
model.fit_generator(train_generator,
samples_per_epoch=spe,
nb_epoch=nb_epoch,
validation_data=validation_generator,
nb_val_samples=spe,
)
net.save(model, tags, model_file_prefix)
# at this point, the top layers are well trained and we can start fine-tuning
# convolutional layers from inception V3. We will freeze the bottom N layers
# and train the remaining top layers.
# we chose to train the top 2 inception blocks, i.e. we will freeze
# the first 172 layers and unfreeze the rest:
for layer in model.layers[:172]:
layer.trainable = False
for layer in model.layers[172:]:
layer.trainable = True
# we need to recompile the model for these modifications to take effect
# we use SGD with a low learning rate
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy', metrics=["accuracy"])
# we train our model again (this time fine-tuning the top 2 inception blocks
# alongside the top Dense layers
print "fine-tuning top 2 inception blocks alongside the top dense layers"
for i in range(1,11):
print "mega-epoch %d/10" % i
model.fit_generator(train_generator,
samples_per_epoch=spe,
nb_epoch=nb_phase_two_epoch,
validation_data=validation_generator,
nb_val_samples=spe,
)
#evaluate(model, str(i).zfill(3)+".png")
# evaluate(model, "000.jpg")
net.save(model, tags, model_file_prefix)
when run with keras-js i get the error
Error: predict() must take an object where the keys are the named inputs of the model: input_1.
pls help
Wasn't easy to read your code - indentation was off and I don't really know what's in dataset and the other imports.
That said, the problem is probably the format of X_test. During training, you use output from ImageDatagenerator which rescales the images to (299,299) together with the other manipulations. During evaluation, you use the raw data in X_test directly.
Hope this helps /p