Chainer: Cannot classify, trained model(x) throws error - python

I am using Chainer for written digit recognition. I have trained a model on the MNIST database. However I cannot for some reason classify a single example. My guess was that I didn't choose the right format for the example but I've tried it many ways and I still cannot resolve this issue. Apologies if this is obvious, I'm unexperienced at Python.
This is what the error looks like
Code:
import chainer
import chainer.functions as F
import chainer.links as L
import os
import sys
from chainer.training import extensions
import numpy as np
from tkinter.filedialog import askopenfilename
from PIL import Image
from chainer import serializers
from chainer.dataset import concat_examples
from chainer.backends import cuda
from chainer import Function, gradient_check, report, training, utils, Variable
from chainer import datasets, iterators, optimizers, serializers
from chainer import Link, Chain, ChainList
CONST_RESUME = ''
class Network(chainer.Chain):
def __init__(self, n_units, n_out):
super(Network, self).__init__()
with self.init_scope():
self.l1 = L.Linear(None, n_units)
self.l2 = L.Linear(None, n_units)
self.l3 = L.Linear(None, n_out)
def __call__(self, x):
h1 = F.sigmoid(self.l1(x))
h2 = F.sigmoid(self.l2(h1))
return self.l3(h2)
def query_yes_no(question, default="no"):
"""Ask a yes/no question via raw_input() and return their answer.
"question" is a string that is presented to the user.
"default" is the presumed answer if the user just hits <Enter>.
It must be "yes" (the default), "no" or None (meaning
an answer is required of the user).
The "answer" return value is True for "yes" or False for "no".
"""
valid = {"yes": True, "y": True, "ye": True,
"no": False, "n": False}
if default is None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)
choice = input().lower()
if default is not None and choice == '':
return valid[default]
elif choice in valid:
return valid[choice]
else:
sys.stdout.write("Please respond with 'yes' or 'no' "
"(or 'y' or 'n').\n")
return np.argmax(y.data)
def main():
#file_list = [None]*10
#for i in range(10):
# file_list[i] = open('data{}.txt'.format(i), 'rb')
print('MNIST digit recognition.')
usr_in : str
model = L.Classifier(Network(100, 10))
chainer.backends.cuda.get_device_from_id(0).use()
model.to_gpu()
usr_in = input('Input (t) to train, (l) to load.')
while len(usr_in) != 1 and (usr_in[0] != 'l' or usr_in[0] != 't'):
print('Invalid input.')
usr_in = input()
if usr_in[0] == 't':
optimizer = chainer.optimizers.Adam()
optimizer.setup(model)
train, test = chainer.datasets.get_mnist()
train_iter = chainer.iterators.SerialIterator(train, batch_size=100, shuffle=True)
test_iter = chainer.iterators.SerialIterator(test, 100, repeat=False, shuffle=False)
updater = training.updaters.StandardUpdater(train_iter, optimizer, device=0)
trainer = training.Trainer(updater, (10, 'epoch'), out='out.txt')
trainer.extend(extensions.Evaluator(test_iter, model, device=0))
trainer.extend(extensions.dump_graph('main/loss'))
frequency = 1
trainer.extend(extensions.snapshot(), trigger=(frequency, 'epoch'))
trainer.extend(extensions.LogReport())
if extensions.PlotReport.available():
trainer.extend(extensions.PlotReport(['main/loss', 'validation/main/loss'], 'epoch', file_name='loss.png'))
trainer.extend(extensions.PlotReport(['main/accuracy', 'validation/main/accuracy'], 'epoch', file_name='accuracy.png'))
trainer.extend(extensions.PrintReport(['epoch', 'main/loss', 'validation/main/loss', 'main/accuracy', 'validation/main/accuracy', 'elapsed_time']))
trainer.extend(extensions.ProgressBar())
if CONST_RESUME:
chainer.serializers.load_npz(CONST_RESUME, trainer)
trainer.run()
ans = query_yes_no('Would you like to save this network?')
if ans:
usr_in = input('Input filename: ')
serializers.save_npz('{}.{}'.format(usr_in, 'npz'), model)
elif usr_in[0] == 'l':
filename = askopenfilename(initialdir=os.getcwd(), title='Choose a file')
serializers.load_npz(filename, model)
else:
return
while True:
ans = query_yes_no('Would you like to evaluate an image with the current network?')
if ans:
filename = askopenfilename(initialdir=os.getcwd(), title='Choose a file')
file = Image.open(filename)
bw_file = file.convert('L')
size = 28, 28
bw_file.thumbnail(size, Image.ANTIALIAS)
pix = bw_file.load()
x = np.empty([28 * 28])
for i in range(28):
for j in range(28):
x[i * 28 + j] = pix[i, j]
#gpu_id = 0
#batch = (, gpu_id)
x = (x.astype(np.float32))[None, ...]
y = model(x)
print('predicted_label:', y.argmax(axis=1)[0])
else:
return
main()

Can you show us the error message? Otherwise it is difficult to guess where causes the error.
But I guess input shape may be different.
When you use the chainer built-in function to get dataset,
train, test = chainer.datasets.get_mnist()
These dataset image shape is (minibatch, channel, height, width). but it seems you are constructing input x as the shape (minibatch, height * width =28*28=784) which is the different shape??
You can also refer some tutorial for chainer,
chainer handson
deep learning tutorial with chainer
MNIST inference code

Related

Why does an ANN validation accuracy oscillate?

The following training curve is generated using the same Tensorflow + Keras script written in Python:
RED line uses five features.
GREEN line uses seven features.
BLUE line uses nine features.
Can anyone tell me the probable cause of the oscillation of the GREEN line so that I can troubleshoot my script?
Source code:
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
#os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0" # Use both gpus for training.
import sys, random
import time
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import ModelCheckpoint
import numpy as np
from lxml import etree, objectify
# <editor-fold desc="GPU">
# resolve GPU related issues.
try:
physical_devices = tf.config.list_physical_devices('GPU')
for gpu_instance in physical_devices:
tf.config.experimental.set_memory_growth(gpu_instance, True)
except Exception as e:
pass
# END of try
# </editor-fold>
# <editor-fold desc="Lxml helper">
class LxmlHelper:
#classmethod
def objectify_xml(cls, input_path_dir):
file_dom = etree.parse(input_path_dir) # parse xml and convert it into DOM
file_xml_bin = etree.tostring(file_dom, pretty_print=False, encoding="ascii") # encode DOM into ASCII object
file_xml_text = file_xml_bin.decode() # convert binary ASCII object into ASCII text
objectified_xml = objectify.fromstring(file_xml_text) # convert text into a Doxygen object
return objectified_xml
# </editor-fold>
# <editor-fold desc="def encode(letter)">
def encode(letter: str):
if letter == 'H':
return [1.0, 0.0, 0.0]
elif letter == 'E':
return [0.0, 1.0, 0.0]
elif letter == 'C':
return [0.0, 0.0, 1.0]
elif letter == '-':
return [0.0, 0.0, 0.0]
# END of function
def encode_string_1(pattern_str: str):
# Iterate over the string
one_hot_binary_str = []
for ch in pattern_str:
try:
one_hot_binary_str = one_hot_binary_str + encode(ch)
except Exception as e:
print(pattern_str, one_hot_binary_str, ch)
# END of for loop
return one_hot_binary_str
# END of function
def encode_string_2(pattern_str: str):
# Iterate over the string
one_hot_binary_str = []
for ch in pattern_str:
temp_encoded_vect = [encode(ch)]
one_hot_binary_str = one_hot_binary_str + temp_encoded_vect
# END of for loop
return one_hot_binary_str
# END of function
# </editor-fold>
# <editor-fold desc="def load_data()">
def load_data_k(fname: str, class_index: int, feature_start_index: int, **selection):
"""Loads data for training and validation
:param fname: (``string``) - name of the file with the data
:param selection: (``kwargs``) - see below
:return: four tensorflow tensors: training input, training output, validation input and validation output
:Keyword Arguments:
* *top_n_lines* (``number``) --
take top N lines of the input and disregard the rest
* *random_n_lines* (``number``) --
take random N lines of the input and disregard the rest
* *validation_part* (``float``) --
separate N_lines * given_fraction of the input lines from the training set and use
them for validation. When the given_fraction = 1.0, then the same input set of
N_lines is used both for training and validation (this is the default)
"""
i = 0
file = open(fname)
if "top_n_lines" in selection:
lines = [next(file) for _ in range(int(selection["top_n_lines"]))]
elif "random_n_lines" in selection:
tmp_lines = file.readlines()
lines = random.sample(tmp_lines, int(selection["random_n_lines"]))
else:
lines = file.readlines()
data_x, data_y, data_z = [], [], []
for l in lines:
row = l.strip().split() # return a list of words from the line.
x = [float(ix) for ix in row[feature_start_index:]] # convert 3rd to 20th word into a vector of float numbers.
y = encode(row[class_index]) # convert the 3rd word into binary.
z = encode_string_1(row[class_index+1])
data_x.append(x) # append the vector into 'data_x'
data_y.append(y) # append the vector into 'data_y'
data_z.append(z) # append the vector into 'data_z'
# END for l in lines
num_rows = len(data_x)
given_fraction = selection.get("validation_part", 1.0)
if given_fraction > 0.9999:
valid_x, valid_y, valid_z = data_x, data_y, data_z
else:
n = int(num_rows * given_fraction)
data_x, data_y, data_z = data_x[n:], data_y[n:], data_z[n:]
valid_x, valid_y, valid_z = data_x[:n], data_y[:n], data_z[:n]
# END of if-else block
tx = tf.convert_to_tensor(data_x, np.float32)
ty = tf.convert_to_tensor(data_y, np.float32)
tz = tf.convert_to_tensor(data_z, np.float32)
vx = tf.convert_to_tensor(valid_x, np.float32)
vy = tf.convert_to_tensor(valid_y, np.float32)
vz = tf.convert_to_tensor(valid_z, np.float32)
return tx, ty, tz, vx, vy, vz
# END of the function
# </editor-fold>
# <editor-fold desc="def create_model()">
def create_model(n_hidden_1, n_hidden_2, num_classes, num_features):
# create the model
model = Sequential()
model.add(tf.keras.layers.InputLayer(input_shape=(num_features,)))
model.add(tf.keras.layers.Dense(n_hidden_1, activation='sigmoid'))
model.add(tf.keras.layers.Dense(n_hidden_2, activation='sigmoid'))
###model.add(tf.keras.layers.Dense(n_hidden_3, activation='sigmoid'))
model.add(tf.keras.layers.Dense(num_classes, activation='softmax'))
# instantiate the optimizer
opt = keras.optimizers.SGD(learning_rate=LEARNING_RATE)
# compile the model
model.compile(
optimizer=opt,
loss="categorical_crossentropy",
metrics="categorical_accuracy"
)
# return model
return model
# </editor-fold>
if __name__ == "__main__":
# <editor-fold desc="(input/output parameters)">
my_project_routine = LxmlHelper.objectify_xml("my_project_evaluate.xml")
# input data
INPUT_DATA_FILE = str(my_project_routine.input.input_data_file)
INPUT_PATH = str(my_project_routine.input.input_path)
CLASS_INDEX = int(my_project_routine.input.class_index)
FEATURE_INDEX = int(my_project_routine.input.feature_index)
# output data
OUTPUT_PATH = str(my_project_routine.output.output_path)
MODEL_FILE = str(my_project_routine.output.model_file)
TRAINING_PROGRESS_FILE = str(my_project_routine.output.training_progress_file)
# Learning parameters
LEARNING_RATE = float(my_project_routine.training_params.learning_rate)
EPOCH_SIZE = int(my_project_routine.training_params.epoch_size)
BATCH_SIZE = int(my_project_routine.training_params.batch_size)
INPUT_LINES_COUNT = int(my_project_routine.input.input_lines_count)
VALIDATION_PART = float(my_project_routine.training_params.validation_part)
SAVE_PERIOD = str(my_project_routine.output.save_period)
# NN parameters
HIDDEN_LAYER_1_NEURON_COUNT = int(my_project_routine.hidden_layers.one)
HIDDEN_LAYER_2_NEURON_COUNT = int(my_project_routine.hidden_layers.two)
###HIDDEN_LAYER_3_NEURON_COUNT = int(my_project_routine.hidden_layers.three)
CLASS_COUNT = int(my_project_routine.class_count)
FEATURES_COUNT = int(my_project_routine.features_count)
input_file_path_str = os.path.join(INPUT_PATH, INPUT_DATA_FILE)
training_progress_file_path_str = os.path.join(OUTPUT_PATH, TRAINING_PROGRESS_FILE)
model_file_path = os.path.join(OUTPUT_PATH, MODEL_FILE)
# command-line arg processing
input_file_name_str = None
if len(sys.argv) > 1:
input_file_name_str = sys.argv[1]
else:
input_file_name_str = input_file_path_str
# END of if-else
# </editor-fold>
# <editor-fold desc="(load data from file)">
# load training data from the disk
train_x, train_y, _, validate_x, validate_y, _ = \
load_data_k(
fname=input_file_name_str,
class_index=CLASS_INDEX,
feature_start_index=FEATURE_INDEX,
random_n_lines=INPUT_LINES_COUNT,
validation_part=VALIDATION_PART
)
print("training data size : ", len(train_x))
print("validation data size : ", len(validate_x))
# </editor-fold>
### STEPS_PER_EPOCH = len(train_x) // BATCH_SIZE
### VALIDATION_STEPS = len(validate_x) // BATCH_SIZE
# <editor-fold desc="(model creation)">
# load previously saved NN model
model = None
try:
model = keras.models.load_model(model_file_path)
print("Loading NN model from file.")
model.summary()
except Exception as ex:
print("No NN model found for loading.")
# END of try-except
# </editor-fold>
# <editor-fold desc="(model run)">
# # if there is no model loaded, create a new model
if model is None:
csv_logger = keras.callbacks.CSVLogger(training_progress_file_path_str)
checkpoint = ModelCheckpoint(
model_file_path,
monitor='loss',
verbose=1,
save_best_only=True,
mode='auto',
save_freq='epoch'
)
callbacks_vector = [
csv_logger,
checkpoint
]
# Set mirror strategy
#strategy = tf.distribute.MirroredStrategy(devices=["/device:GPU:0","/device:GPU:1"])
#with strategy.scope():
print("New NN model created.")
# create sequential NN model
model = create_model(
n_hidden_1=HIDDEN_LAYER_1_NEURON_COUNT,
n_hidden_2=HIDDEN_LAYER_2_NEURON_COUNT,
##n_hidden_3=HIDDEN_LAYER_3_NEURON_COUNT,
num_classes=CLASS_COUNT,
num_features=FEATURES_COUNT
)
# Train the model with the new callback
history = model.fit(
train_x, train_y,
validation_data=(validate_x, validate_y),
batch_size=BATCH_SIZE,
epochs=EPOCH_SIZE,
callbacks=[callbacks_vector],
shuffle=True,
verbose=2
)
print(history.history.keys())
# END of ... with
# END of ... if
# </editor-fold>
Plotting Script
import os
from argparse import ArgumentParser
import random
from typing import List
import matplotlib.pyplot as plt
import numpy as np
import math
import sys
import datetime
class Quad:
def __init__(self, x_vector, y_vector, color_char, label_str):
self.__x_vector = x_vector
self.__y_vector = y_vector
self.__color_char = color_char
self.__label_str = label_str
def get_x_vector(self):
return self.__x_vector
def get_y_vector(self):
return self.__y_vector
def get_color_char(self):
return self.__color_char
def get_label_str(self):
return self.__label_str
class HecaPlotClass:
def __init__(self):
self.__x_label_str: str = None
self.__y_label_str: str = None
self.__title_str: str = None
self.__trio_vector: List[Quad] = []
self.__plotter = plt
#property
def x_label_str(self):
return self.__x_label_str
#x_label_str.setter
def x_label_str(self, t):
self.__x_label_str = t
#property
def y_label_str(self):
return self.__y_label_str
#y_label_str.setter
def y_label_str(self, t):
self.__y_label_str = t
#property
def title_str(self):
return self.__title_str
#title_str.setter
def title_str(self, t):
self.__title_str = t
def add_y_axes(self, trio_obj: Quad):
self.__trio_vector.append(trio_obj)
def generate_plot(self):
for obj in self.__trio_vector:
x_vector = obj.get_x_vector()
y_vector = obj.get_y_vector()
label_str = obj.get_label_str()
# print(label_str)
# print(len(x_vector))
# print(len(y_vector))
self.__plotter.plot(
x_vector,
y_vector,
color=obj.get_color_char(),
label=label_str
)
# END of ... for loop
# Naming the x-axis, y_1_vector-axis and the whole graph
self.__plotter.xlabel(self.__x_label_str)
self.__plotter.ylabel(self.__y_label_str)
self.__plotter.title(self.__title_str)
# Adding legend, which helps us recognize the curve according to it's color
self.__plotter.legend()
# To load the display window
#self.__plotter.show()
def save_png(self, output_directory_str):
output_file_str = os.path.join(output_directory_str, self.__title_str + '.png')
self.__plotter.savefig(output_file_str)
def save_pdf(self, output_directory_str):
output_file_str = os.path.join(output_directory_str, self.__title_str + '.pdf')
self.__plotter.savefig(output_file_str)
class MainClass(object):
__colors_vector = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'orange', 'lightgreen', 'crimson']
__working_dir = r"."
__file_names_vector = ["training_progress-32.txt", "training_progress-64.txt", "training_progress-128.txt"]
__input_files_vector = []
__output_directory = None
__column_no_int = 0
__split_percentage_at_tail_int = 100
__is_pdf_output = False
__is_png_output = False
# <editor-fold desc="def load_data()">
#classmethod
def __load_data(cls, fname: str, percetage_int:int, column_no_int:int):
np_array = np.loadtxt(
fname,
# usecols=range(1,11),
dtype=np.float32,
skiprows=1,
delimiter=","
)
size_vector = np_array.shape
array_len_int = size_vector[0]
rows_count_int = int(percetage_int * array_len_int / 100)
np_array = np_array[-rows_count_int:]
x = np_array[:, 0]
y = np_array[:, column_no_int]
return x, y
# END of the function
# </editor-fold>
# <editor-fold desc="(__parse_args())">
#classmethod
def __parse_args(cls):
# initialize argument parser
my_parser = ArgumentParser()
my_parser.add_argument("-c", help="column no.", type=int)
my_parser.add_argument('-i', nargs='+', help='a list of input files', required=True)
my_parser.add_argument("-o", help="output directory", type=str)
my_parser.add_argument("-n", help="percentage of data to split from tail", type=float)
my_parser.add_argument("--pdf", help="PDF output", action='store_true')
my_parser.add_argument("--png", help="PNG output", action='store_true')
# parse the argument
args = my_parser.parse_args()
cls.__input_files_vector = args.i
cls.__output_directory = args.o
cls.__split_percentage_at_tail_int = args.n
cls.__column_no_int = args.c
cls.__is_pdf_output = args.pdf
cls.__is_png_output = args.png
# </editor-fold>
#classmethod
def main(cls):
cls.__parse_args()
if cls.__input_files_vector is None:
cls.__input_files_vector = cls.__file_names_vector
if cls.__output_directory is None:
cls.__output_directory = cls.__working_dir
if cls.__split_percentage_at_tail_int is None:
cls.__split_percentage_at_tail_int = 100
if cls.__column_no_int is None:
cls.__column_no_int = 1
my_project_plot_obj = HecaPlotClass()
i = 0
for file_path_str in cls.__input_files_vector:
print(file_path_str)
x_vector, y_vector = cls.__load_data(os.path.join(cls.__working_dir, file_path_str), cls.__split_percentage_at_tail_int, cls.__column_no_int)
my_project_plot_obj.x_label_str = "Epoch"
my_project_plot_obj.y_label_str = "Accuracy"
my_project_plot_obj.title_str = "training_plot-{date:%Y-%m-%d_%H:%M:%S}".format(date=datetime.datetime.now())
my_project_plot_obj.x_axis_vector = x_vector
if i == 0:
random_int = 0
else:
random_int = i % (len(cls.__colors_vector)-1)
# END of ... if
print("random_int : ", random_int)
my_project_plot_obj.add_y_axes(Quad(x_vector, y_vector, cls.__colors_vector[random_int], file_path_str))
i = i + 1
# END of ... for loop
my_project_plot_obj.generate_plot()
my_project_plot_obj.save_png(cls.__output_directory)
my_project_plot_obj.save_pdf(cls.__output_directory)
if __name__ == "__main__":
MainClass.main()
The primary reason could be improper (non-random ~ ordered) distribution of data.
If you notice the accuracy beyond epoch 180, there is a orderly switching between the accuracy between ~0.43 (approx.) and ~0.33 (~approx.), and occasionally ~0.23 (approx.). The more important thing to notice is that the accuracy is decreasing (there's no improvement in validation accuracy) as we increase the epochs.
The accuracy can increase in such cases if you (1) reduce batch size, or (2) use a better optimizer like Adam. And check the learning rate.
These changes can help the shift and oscillation, as well.
Additionally, Running average of the accuracy can be plotted to avoid the oscillation. This is again a mitigation scheme rather than a correction scheme. But, what it does is removes the order (partition of the data) and mixes the nearby data.
Lastly, I would also reshuffle the data and normalize after each layer. See if that helps.
Generally, sharp jumps and flat lines in the accuracy usually mean that a group of examples is classified as a given class at a same time. If your dataset contains, say, 50 examples with the same combination of 7 features then they would go into the same class at the same time. This is what probably causes sharp jumps - identical or similar examples clustered together.
So for example, if you have 50 men aged 64, and a decision boundary to classify them as more prone to an illness shifts from >65 to >63, then accuracy changes rapidly as all of them change classification at the same time.
Regarding the oscillation of the curve - due to the fact above, oscillation will be amplified by small changes in learning. Your network learns based on cross entropy, which means that it minimizes the difference between target and your predictions. This means that it operates on the difference between probability and target (say, 0.3 vs class 0) instead of class and target like accuracy (so, 0 vs 0) in the same example. Cross entropy is much more smooth as it is not affected by the issue outlined above.

Model weight not updated when training with Pytorch Lightning

I'm new in Pytorch Lightning. I made a very simple model using PL.
I checked the weights of the model before and after training but They are exactly the same knowing that the loss decrease during training.
def main(args, df_train, df_dev, df_test) :
""" main function"""
# Wandb connect
wandb_connect()
wandb_logger = WandbLogger(project="project name", name="Run name")
# Tokenization
[df_train, df_dev, df_test], params, tokenizer_qid, tokenizer_uid, tokenizer_qu_id, tokenizer_rank = apply_tokenization([df_train, df_dev, df_test])
# Dataloadeers
[train_loader, dev_loader, test_loader] = list(map(lambda x : Dataset_SM(x).get_dataloader(args.batch_size), [df_train, df_dev, df_test]))
# Model definition
model = NCM(**params).to(device)
# Weight before training
WW = model.emb_qid.weight
print(torch.mean(model.emb_qid.weight))
# Train & Eval
es = EarlyStopping(monitor='dev_loss', patience=4)
checkpoint_callback = ModelCheckpoint(dirpath=args.result_path)
trainer = pl.Trainer(max_epochs=args.n_epochs, callbacks=[es, checkpoint_callback], val_check_interval=args.val_check_interval,
logger=wandb_logger, gpus=1)
trainer.fit(model, train_loader, dev_loader)
trainer.save_checkpoint(args.result_path + "example.ckpt")
loaded_model = NCM.load_from_checkpoint(checkpoint_path=args.result_path + "example.ckpt", **params)
print(loaded_model.emb_qid.weight == WW)
Can someone tell me if I miss something ?
Just assigning .weight to new variable does not copy data, but only pass reference to data.
Here is short example:
import copy
import torch
def is_same(a, b):
return ((a - b).float().abs().sum() < 1e-6).item()
a = torch.nn.Conv2d(5, 5, 3)
b = a.weight
c = copy.deepcopy(a.weight)
torch.nn.init.xavier_uniform_(a.weight.data)
print("a == b: " + str(is_same(a.weight, b)))
print("a == c: " + str(is_same(a.weight, c)))
# output
a == b: True
a == c: False

How to convert Keras .h5 model to darknet yolo.weights format?

I have trained the yolov2 and yolov3 models using Keras with this Github project https://github.com/experiencor/keras-yolo2
Now I want to use the trained model (.h5) in darknet prediction. Essentially I need to convert this h5 model into the format expected by darknet(.weights). I have seen this project https://github.com/allanzelener/YAD2K/blob/master/yad2k.py
which does the reverse of what I want?
Did anyone try this before?
This is a problem I also faced but I solved it a bit by using the following code.
# Script converter_h5-2-wts.py
# -*- coding: utf-8 -*-
''' yolov3_keras_to_darknet.py'''
import argparse
import numpy
import numpy as np
import keras
from keras.models import load_model
from keras import backend as K
def parser():
parser = argparse.ArgumentParser(description="Darknet\'s yolov3.cfg and
yolov3.weights \
converted into Keras\'s yolov3.h5!")
parser.add_argument('-cfg_path', help='yolov3.cfg')
parser.add_argument('-h5_path', help='yolov3.h5')
parser.add_argument('-output_path', help='yolov3.weights')
return parser.parse_args()
class WeightSaver(object):
def __init__(self,h5_path,output_path):
self.model = load_model(h5_path)
self.layers = {weight.name:weight for weight in self.model.weights}
self.sess = K.get_session()
self.fhandle = open(output_path,'wb')
self._write_head()
def _write_head(self):
numpy_data = numpy.ndarray(shape=(3,),
dtype='int32',
buffer=np.array([0,2,0],dtype='int32') )
self.save(numpy_data)
numpy_data = numpy.ndarray(shape=(1,),
dtype='int64',
buffer=np.array([320000],dtype='int64'))
self.save(numpy_data)
def get_bn_layername(self,num):
layer_name = 'batch_normalization_{num}'.format(num=num)
bias = self.layers['{0}/beta:0'.format(layer_name)]
scale = self.layers['{0}/gamma:0'.format(layer_name)]
mean = self.layers['{0}/moving_mean:0'.format(layer_name)]
var = self.layers['{0}/moving_variance:0'.format(layer_name)]
bias_np = self.get_numpy(bias)
scale_np = self.get_numpy(scale)
mean_np = self.get_numpy(mean)
var_np = self.get_numpy(var)
return bias_np,scale_np,mean_np,var_np
def get_convbias_layername(self,num):
layer_name = 'conv2d_{num}'.format(num=num)
bias = self.layers['{0}/bias:0'.format(layer_name)]
bias_np = self.get_numpy(bias)
return bias_np
def get_conv_layername(self,num):
layer_name = 'conv2d_{num}'.format(num=num)
conv = self.layers['{0}/kernel:0'.format(layer_name)]
conv_np = self.get_numpy(conv)
return conv_np
def get_numpy(self,layer_name):
numpy_data = self.sess.run(layer_name)
return numpy_data
def save(self,numpy_data):
bytes_data = numpy_data.tobytes()
self.fhandle.write(bytes_data)
self.fhandle.flush()
def close(self):
self.fhandle.close()
class KerasParser(object):
def __init__(self, cfg_path, h5_path, output_path):
self.block_gen = self._get_block(cfg_path)
self.weights_saver = WeightSaver(h5_path, output_path)
self.count_conv = 0
self.count_bn = 0
def _get_block(self,cfg_path):
block = {}
with open(cfg_path,'r', encoding='utf-8') as fr:
for line in fr:
line = line.strip()
if '[' in line and ']' in line:
if block:
yield block
block = {}
block['type'] = line.strip(' []')
elif not line or '#' in line:
continue
else:
key,val = line.strip().replace(' ','').split('=')
key,val = key.strip(), val.strip()
block[key] = val
yield block
def close(self):
self.weights_saver.close()
def conv(self, block):
self.count_conv += 1
batch_normalize = 'batch_normalize' in block
print('handing.. ',self.count_conv)
# If bn exists, process bn first, in order of bias, scale, mean, var
if batch_normalize:
bias,scale,mean,var = self.bn()
self.weights_saver.save(bias)
scale = scale.reshape(1,-1)
mean = mean.reshape(1,-1)
var = var.reshape(1,-1)
remain = np.concatenate([scale,mean,var],axis=0)
self.weights_saver.save(remain)
# biase
else:
conv_bias = self.weights_saver.get_convbias_layername(self.count_conv)
self.weights_saver.save(conv_bias)
# weights
conv_weights = self.weights_saver.get_conv_layername(self.count_conv)
# (height, width, in_dim, out_dim) (out_dim, in_dim, height, width)
conv_weights = np.transpose(conv_weights,[3,2,0,1])
self.weights_saver.save(conv_weights)
def bn(self):
self.count_bn += 1
bias,scale,mean,var = self.weights_saver.get_bn_layername(self.count_bn)
return bias,scale,mean,var
def main():
args = parser()
keras_loader = KerasParser(args.cfg_path, args.h5_path, args.output_path)
for block in keras_loader.block_gen:
if 'convolutional' in block['type']:
keras_loader.conv(block)
keras_loader.close()
if __name__ == "__main__":
main()
Please do the indentation as the code pasted is from text file. I could not leave the four spaces on in the front of the line so please indent the code at your end.
usage is as below
$python converter_h5-2-wts.py -cfg_path text.cfg -h5_path test.h5 -output_path test.weights
If this works for you please limit vote for this post only but thank the original coder for the source code in python. I just searched some time back for this code.

Select different modes by string in Tensorflow

I am trying to build a VAE network in which I want the model to do different things in different modes. I have three modes: "train", "same" and "different" and a function named interpolation(mode) that does different things depend on the mode. My code looks like:
import tensorflow as tf
### some code here
mode = tf.placeholder(dtype = tf.string, name = "mode")
def interpolation(mode):
if mode == "train":
# do something
print("enter train mode")
elif mode == "same":
# do other things
print("enter same mode")
else:
# do other things
print("enter different mode")
# some other code here
sess.run(feed_dict = {mode: "train"})
sess.run(feed_dict = {mode: "same"})
sess.run(feed_dict = {mode: "different"})
But the output looks like:
enter different mode
enter different mode
enter different mode
which means the mode that gets passed in doesn't change the condition. What have I done wrong? How do I select mode by string argument?
First approach: You can select a different mode by using native Tensorflow switch-case. For example, I assume you have three cases, then you can do:
import tensorflow as tf
mode = tf.placeholder(tf.string, shape=[], name="mode")
def cond1():
return tf.constant('same')
def cond2():
return tf.constant('train')
def cond3():
return tf.constant('diff')
def cond4():
return tf.constant('default')
y = tf.case({tf.equal(mode, 'same'): cond1,
tf.equal(mode, 'train'): cond2,
tf.equal(mode, 'diff'): cond3},
default=cond4, exclusive=True)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(y, feed_dict={mode: "train"}))
print(sess.run(y, feed_dict={mode: "same"}))
Second approach: here is another way to do this with new AutoGraph API:
import tensorflow as tf
from tensorflow.contrib import autograph as ag
m = tf.placeholder(dtype=tf.string, name='mode')
def interpolation(mode):
if mode == "train":
return 'I am train'
elif mode == "same":
return 'I am same'
else:
return 'I am different'
cond_func = ag.to_graph(interpolation)(m)
with tf.Session() as sess:
print(sess.run(cond_func, feed_dict={m: 'same'}))

face recognition prediction error (cv::face::Fisherfaces::predict)

OpenCV Error: Bad argument (This Fisherfaces model is not computed yet. Did you
call Fisherfaces::train?) in cv::face::Fisherfaces::predict,
cv2.error: C:\projects\opencv-python\opencv_contrib\modules\face\src\fisher_faces.cpp:137: error: (-5) This Fisherfaces model is not computed yet. Did you call Fisherfaces::train? in function cv::face::Fisherfaces::predict
import cv2
import numpy as np
import argparse
import time
import glob
import os
import sys
import subprocess
import pandas
import random
import Update_Model
import math
#Define variables and load classifier
camnumber = 0
video_capture = cv2.VideoCapture()
facecascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
fishface = cv2.face.FisherFaceRecognizer_create()
try:
fishface.read("trained_emoclassifier.xml")
except:
print("no trained xml file found, please run program with --update flagfirst")
parser = argparse.ArgumentParser(description="Options for the emotion-based music player")
parser.add_argument("--update", help="Call to grab new images and update the model accordingly", action="store_true")
args = parser.parse_args()
facedict = {}
actions = {}
emotions = ["angry", "happy", "sad", "neutral"]
df = pandas.read_excel("EmotionLinks.xlsx") #open Excel file
actions["angry"] = [x for x in df.angry.dropna()] #We need de dropna() when columns are uneven in length, which creates NaN values at missing places. The OS won't know what to do with these if we try to open them.
actions["happy"] = [x for x in df.happy.dropna()]
actions["sad"] = [x for x in df.sad.dropna()]
actions["neutral"] = [x for x in df.neutral.dropna()]
def open_stuff(): #Open the file, credit to user4815162342, on the stackoverflow link in the text above
if sys.platform == "win32":
os.startfile(filename)
else:
opener ="open" if sys.platform == "darwin" else "xdg-open"
subprocess.call([opener, filename])
def crop_face(clahe_image, face):
for (x, y, w, h) in face:
faceslice = clahe_image[y:y+h, x:x+w]
faceslice = cv2.resize(faceslice, (350, 350))
facedict["face%s" %(len(facedict)+1)] = faceslice
return faceslice
def update_model(emotions):
print("Model update mode active")
check_folders(emotions)
for i in range(0, len(emotions)):
save_face(emotions[i])
print("collected images, looking good! Now updating model...")
Update_Model.update(emotions)
print("Done!")
def check_folders(emotions):
for x in emotions:
if os.path.exists("dataset\\%s" %x):
pass
else:
os.makedirs("dataset\\%s" %x)
def save_face(emotion):
print("\n\nplease look " + emotion + ". Press enter when you're ready to have your pictures taken")
input() #Wait until enter is pressed with the raw_input() method
video_capture.open(0)
while len(facedict.keys()) < 16:
detect_face()
video_capture.release()
for x in facedict.keys():
cv2.imwrite("dataset\\%s\\%s.jpg" %(emotion, len(glob.glob("dataset\\%s\\*" %emotion))), facedict[x])
facedict.clear()
def recognize_emotion():
predictions = []
confidence = []
for x in facedict.keys():
pred, conf = fishface.predict(facedict[x])
cv2.imwrite("images\\%s.jpg" %x, facedict[x])
predictions.append(pred)
confidence.append(conf)
recognized_emotion = emotions[max(set(predictions), key=predictions.count)]
print("I think you're %s" %recognized_emotion)
actionlist = [x for x in actions[recognized_emotion]] #get list of actions/files for detected emotion
random.shuffle(actionlist) #Randomly shuffle the list
open_stuff(actionlist[0]) #Open the first entry in the list
def grab_webcamframe():
ret, frame = video_capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
clahe_image = clahe.apply(gray)
return clahe_image
def detect_face():
clahe_image = grab_webcamframe()
face = facecascade.detectMultiScale(clahe_image, scaleFactor=1.1, minNeighbors=15, minSize=(10, 10), flags=cv2.CASCADE_SCALE_IMAGE)
if len(face) == 1:
faceslice = crop_face(clahe_image, face)
recognize_emotion()
return faceslice
else:
print("no/multiple faces detected, passing over frame")
def run_detection():
while len(facedict) != 10:
detect_face()
recognize_emotion = recognize_emotion()
return recognize_emotion
if args.update:
update_model(emotions)
else:
video_capture.open(camnumber)
run_detection()
how can i resolve it?

Categories

Resources